annotate lwcc/cc-gencode.c @ 505:59b8c8b15bd4

Add integer shifts and fix code template errors for mul/div/mod One needs to remove stuff from the stack after putting it there. Actually do that in the code output for multiplication, division, and modulus. Add integer shifting code output which is optimized for constant shift counts but calls a routine for non-constant shift counts. Shifting by a negative amount is a no-op. Shifting by more than the size of an integer results in 0 (for left shifts) or -1 (for right shifts). Both negative shift counts and shift counts larger than the base type are undefined in the C standard so this behaviour is allowed.
author William Astle <lost@l-w.ca>
date Sat, 26 Oct 2019 22:01:55 -0600
parents 14a40f8bb4eb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
499
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
1 /*
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
2 lwcc/cc-gencode.c
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
3
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
4 Copyright © 2019 William Astle
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
5
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
6 This file is part of LWTOOLS.
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
7
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
8 LWTOOLS is free software: you can redistribute it and/or modify it under the
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
9 terms of the GNU General Public License as published by the Free Software
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
10 Foundation, either version 3 of the License, or (at your option) any later
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
11 version.
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
12
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
13 This program is distributed in the hope that it will be useful, but WITHOUT
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
16 more details.
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
17
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
18 You should have received a copy of the GNU General Public License along with
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
19 this program. If not, see <http://www.gnu.org/licenses/>.
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
20 */
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
21
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
22 #include <stdio.h>
505
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
23 #include <stdlib.h>
499
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
24 #include <string.h>
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
25
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
26 #include <lw_alloc.h>
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
27 #include <lw_string.h>
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
28
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
29 #include "tree.h"
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
30
502
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
31 char *generate_nextlabel(void)
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
32 {
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
33 static int labelnum = 0;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
34 char buf[16];
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
35
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
36 sprintf(buf, "L%d", labelnum++);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
37 return lw_strdup(buf);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
38 }
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
39
505
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
40 void generate_code(node_t *n, FILE *output);
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
41
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
42 void generate_code_shift(node_t *n, FILE *output, int dir)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
43 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
44 generate_code(n -> children, output);
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
45 if (n -> children -> next_child -> type == NODE_CONST_INT)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
46 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
47 long ival;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
48 int i;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
49 ival = strtol(n -> children -> next_child -> strval, NULL, 0);
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
50 if (ival <= 0)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
51 return;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
52 if (ival >= 16)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
53 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
54 fprintf(output, "\tldd #%d\n", dir == 1 ? 0 : -1);
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
55 return;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
56 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
57 if (ival >= 8)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
58 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
59 if (dir == 1)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
60 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
61 fprintf(output, "\ttfr b,a\n\tclrb\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
62 for (i = ival - 8; i > 0; i--)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
63 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
64 fprintf(output, "\tlsla\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
65 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
66 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
67 else
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
68 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
69 fprintf(output, "\ttfr a,b\n\tsex\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
70 for (i = ival - 8; i > 0; i--)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
71 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
72 fprintf(output, "\tasrb\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
73 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
74 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
75 return;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
76 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
77 for (i = ival; i > 0; i--)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
78 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
79 if (dir == 1)
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
80 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
81 fprintf(output, "\taslb\n\trola\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
82 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
83 else
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
84 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
85 fprintf(output, "\tasra\n\trorb\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
86 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
87 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
88 return;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
89 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
90 else
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
91 {
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
92 fprintf(output, "\tpshs d\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
93 generate_code(n -> children -> next_child, output);
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
94 fprintf(output, "\tjsr ___%ssh16\n\tpuls d\n", dir == 1 ? "l" : "r");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
95 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
96 }
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
97
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
98
499
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
99 void generate_code(node_t *n, FILE *output)
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
100 {
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
101 node_t *nn;
502
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
102 char *label1, *label2;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
103
499
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
104 switch (n -> type)
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
105 {
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
106 // function definition - output prologue, then statements, then epilogue
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
107 case NODE_FUNDEF:
505
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
108 fprintf(output, "\tsection .text\n\texport _%s\n_%s\n", n->children->next_child->strval, n->children->next_child->strval);
499
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
109 generate_code(n->children->next_child->next_child->next_child, output);
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
110 fprintf(output, "\trts\n");
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
111 break;
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
112
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
113 case NODE_CONST_INT:
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
114 fprintf(output, "\tldd #%s\n", n->strval);
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
115 break;
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
116
501
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
117 case NODE_OPER_PLUS:
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
118 generate_code(n->children, output);
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
119 fprintf(output, "\tpshs d\n");
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
120 generate_code(n->children->next_child, output);
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
121 fprintf(output, "\taddd ,s++\n");
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
122 break;
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
123
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
124 case NODE_OPER_MINUS:
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
125 generate_code(n->children, output);
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
126 fprintf(output, "\tpshs d,x\n");
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
127 generate_code(n->children->next_child, output);
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
128 fprintf(output, "\tstd 2,s\n\tpuls d\n\tsubd ,s++\n");
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
129 break;
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
130
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
131 case NODE_OPER_TIMES:
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
132 generate_code(n -> children, output);
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
133 fprintf(output, "\tpshs d\n");
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
134 generate_code(n->children->next_child, output);
505
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
135 fprintf(output, "\tjsr ___mul16i\n\tpuls d\n");
501
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
136 break;
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
137
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
138 case NODE_OPER_DIVIDE:
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
139 generate_code(n -> children, output);
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
140 fprintf(output, "\tpshs d\n");
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
141 generate_code(n->children->next_child, output);
505
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
142 fprintf(output, "\tjsr ___div16i\n\tpuls d\n");
501
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
143 break;
502
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
144
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
145 case NODE_OPER_MOD:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
146 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
147 fprintf(output, "\tpshs d\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
148 generate_code(n -> children -> next_child, output);
505
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
149 fprintf(output, "\tjsr ___mod16i\n\tpuls d\n");
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
150 break;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
151
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
152 case NODE_OPER_LSH:
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
153 generate_code_shift(n, output, 1);
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
154 break;
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
155
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
156 case NODE_OPER_RSH:
59b8c8b15bd4 Add integer shifts and fix code template errors for mul/div/mod
William Astle <lost@l-w.ca>
parents: 502
diff changeset
157 generate_code_shift(n, output, 0);
502
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
158 break;
501
f3e9732973f1 Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents: 499
diff changeset
159
502
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
160 case NODE_OPER_COND:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
161 label1 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
162 label2 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
163 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
164 fprintf(output, "\tsubd #0\n\tbeq %s\n", label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
165 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
166 fprintf(output, "\tbra %s\n%s\n", label2, label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
167 generate_code(n -> children -> next_child -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
168 fprintf(output, "%s\n", label2);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
169 lw_free(label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
170 lw_free(label2);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
171 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
172
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
173 case NODE_OPER_COMMA:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
174 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
175 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
176 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
177
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
178 case NODE_OPER_BWAND:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
179 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
180 fprintf(output, "\tpshs d\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
181 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
182 fprintf(output, "\tandb 1,s\n\tanda ,s++\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
183 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
184
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
185 case NODE_OPER_BWOR:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
186 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
187 fprintf(output, "\tpshs d\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
188 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
189 fprintf(output, "\torb 1,s\n\tora ,s++\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
190 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
191
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
192 case NODE_OPER_BWXOR:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
193 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
194 fprintf(output, "\tpshs d\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
195 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
196 fprintf(output, "\teorb 1,s\n\teora ,s++\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
197 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
198
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
199 case NODE_OPER_BAND:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
200 label1 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
201 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
202 fprintf(output, "\tsubd #0\n\tbeq %s\n", label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
203 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
204 fprintf(output, "\tsubd #0\n\tbeq %s\n\tldd #1\n%s\n", label1, label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
205 lw_free(label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
206 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
207
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
208 case NODE_OPER_BOR:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
209 label1 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
210 label2 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
211 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
212 fprintf(output, "\tsubd #0\n\tbne %s\n", label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
213 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
214 fprintf(output, "\tsubd #0\n\tbeq %s\n%s\tldd #1\n%s\n", label2, label1, label2);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
215 lw_free(label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
216 lw_free(label2);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
217 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
218
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
219 case NODE_OPER_NE:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
220 case NODE_OPER_EQ:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
221 case NODE_OPER_LT:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
222 case NODE_OPER_GT:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
223 case NODE_OPER_LE:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
224 case NODE_OPER_GE:
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
225 generate_code(n -> children, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
226 fprintf(output, "\tpshs d\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
227 generate_code(n -> children -> next_child, output);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
228 fprintf(output, "\tsubd ,s++\n");
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
229 label1 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
230 label2 = generate_nextlabel();
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
231 fprintf(output, "\t%s %s\n", (
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
232 (n -> type == NODE_OPER_NE ? "bne" :
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
233 (n -> type == NODE_OPER_EQ ? "beq" :
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
234 (n -> type == NODE_OPER_LT ? "bge" :
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
235 (n -> type == NODE_OPER_GT ? "ble" :
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
236 (n -> type == NODE_OPER_LE ? "bgt" :
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
237 (n -> type == NODE_OPER_GE ? "blt" :
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
238 "foobar"))))))
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
239 ), label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
240 fprintf(output, "\tldd #0\n\tbra %s\n%s\tldd #1\n%s\n", label2, label1, label2);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
241 lw_free(label1);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
242 lw_free(label2);
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
243 break;
14a40f8bb4eb Add various operators to lwcc
William Astle <lost@l-w.ca>
parents: 501
diff changeset
244
499
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
245 default:
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
246 for (nn = n -> children; nn; nn = nn -> next_child)
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
247 generate_code(nn, output);
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
248 break;
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
249 }
c3099c5d9d3e Add very simple code generator
William Astle <lost@l-w.ca>
parents:
diff changeset
250 }