Mercurial > hg > index.cgi
comparison lwcc/cc-gencode.c @ 502:14a40f8bb4eb
Add various operators to lwcc
Add various binary and ternary operators to lwcc, but only those which can
work with constant operands. Seems like variables are probably required
next.
author | William Astle <lost@l-w.ca> |
---|---|
date | Wed, 25 Sep 2019 20:23:49 -0600 |
parents | f3e9732973f1 |
children | 59b8c8b15bd4 |
comparison
equal
deleted
inserted
replaced
501:f3e9732973f1 | 502:14a40f8bb4eb |
---|---|
25 #include <lw_alloc.h> | 25 #include <lw_alloc.h> |
26 #include <lw_string.h> | 26 #include <lw_string.h> |
27 | 27 |
28 #include "tree.h" | 28 #include "tree.h" |
29 | 29 |
30 char *generate_nextlabel(void) | |
31 { | |
32 static int labelnum = 0; | |
33 char buf[16]; | |
34 | |
35 sprintf(buf, "L%d", labelnum++); | |
36 return lw_strdup(buf); | |
37 } | |
38 | |
30 void generate_code(node_t *n, FILE *output) | 39 void generate_code(node_t *n, FILE *output) |
31 { | 40 { |
32 node_t *nn; | 41 node_t *nn; |
42 char *label1, *label2; | |
43 | |
33 switch (n -> type) | 44 switch (n -> type) |
34 { | 45 { |
35 // function definition - output prologue, then statements, then epilogue | 46 // function definition - output prologue, then statements, then epilogue |
36 case NODE_FUNDEF: | 47 case NODE_FUNDEF: |
37 fprintf(output, "_%s\n", n->children->next_child->strval); | 48 fprintf(output, "_%s\n", n->children->next_child->strval); |
68 generate_code(n -> children, output); | 79 generate_code(n -> children, output); |
69 fprintf(output, "\tpshs d\n"); | 80 fprintf(output, "\tpshs d\n"); |
70 generate_code(n->children->next_child, output); | 81 generate_code(n->children->next_child, output); |
71 fprintf(output, "\tjsr ___div16i\n"); | 82 fprintf(output, "\tjsr ___div16i\n"); |
72 break; | 83 break; |
84 | |
85 case NODE_OPER_MOD: | |
86 generate_code(n -> children, output); | |
87 fprintf(output, "\tpshs d\n"); | |
88 generate_code(n -> children -> next_child, output); | |
89 fprintf(output, "\tjsr ___mod16i\n"); | |
90 break; | |
73 | 91 |
92 case NODE_OPER_COND: | |
93 label1 = generate_nextlabel(); | |
94 label2 = generate_nextlabel(); | |
95 generate_code(n -> children, output); | |
96 fprintf(output, "\tsubd #0\n\tbeq %s\n", label1); | |
97 generate_code(n -> children -> next_child, output); | |
98 fprintf(output, "\tbra %s\n%s\n", label2, label1); | |
99 generate_code(n -> children -> next_child -> next_child, output); | |
100 fprintf(output, "%s\n", label2); | |
101 lw_free(label1); | |
102 lw_free(label2); | |
103 break; | |
104 | |
105 case NODE_OPER_COMMA: | |
106 generate_code(n -> children, output); | |
107 generate_code(n -> children -> next_child, output); | |
108 break; | |
109 | |
110 case NODE_OPER_BWAND: | |
111 generate_code(n -> children, output); | |
112 fprintf(output, "\tpshs d\n"); | |
113 generate_code(n -> children -> next_child, output); | |
114 fprintf(output, "\tandb 1,s\n\tanda ,s++\n"); | |
115 break; | |
116 | |
117 case NODE_OPER_BWOR: | |
118 generate_code(n -> children, output); | |
119 fprintf(output, "\tpshs d\n"); | |
120 generate_code(n -> children -> next_child, output); | |
121 fprintf(output, "\torb 1,s\n\tora ,s++\n"); | |
122 break; | |
123 | |
124 case NODE_OPER_BWXOR: | |
125 generate_code(n -> children, output); | |
126 fprintf(output, "\tpshs d\n"); | |
127 generate_code(n -> children -> next_child, output); | |
128 fprintf(output, "\teorb 1,s\n\teora ,s++\n"); | |
129 break; | |
130 | |
131 case NODE_OPER_BAND: | |
132 label1 = generate_nextlabel(); | |
133 generate_code(n -> children, output); | |
134 fprintf(output, "\tsubd #0\n\tbeq %s\n", label1); | |
135 generate_code(n -> children -> next_child, output); | |
136 fprintf(output, "\tsubd #0\n\tbeq %s\n\tldd #1\n%s\n", label1, label1); | |
137 lw_free(label1); | |
138 break; | |
139 | |
140 case NODE_OPER_BOR: | |
141 label1 = generate_nextlabel(); | |
142 label2 = generate_nextlabel(); | |
143 generate_code(n -> children, output); | |
144 fprintf(output, "\tsubd #0\n\tbne %s\n", label1); | |
145 generate_code(n -> children -> next_child, output); | |
146 fprintf(output, "\tsubd #0\n\tbeq %s\n%s\tldd #1\n%s\n", label2, label1, label2); | |
147 lw_free(label1); | |
148 lw_free(label2); | |
149 break; | |
150 | |
151 case NODE_OPER_NE: | |
152 case NODE_OPER_EQ: | |
153 case NODE_OPER_LT: | |
154 case NODE_OPER_GT: | |
155 case NODE_OPER_LE: | |
156 case NODE_OPER_GE: | |
157 generate_code(n -> children, output); | |
158 fprintf(output, "\tpshs d\n"); | |
159 generate_code(n -> children -> next_child, output); | |
160 fprintf(output, "\tsubd ,s++\n"); | |
161 label1 = generate_nextlabel(); | |
162 label2 = generate_nextlabel(); | |
163 fprintf(output, "\t%s %s\n", ( | |
164 (n -> type == NODE_OPER_NE ? "bne" : | |
165 (n -> type == NODE_OPER_EQ ? "beq" : | |
166 (n -> type == NODE_OPER_LT ? "bge" : | |
167 (n -> type == NODE_OPER_GT ? "ble" : | |
168 (n -> type == NODE_OPER_LE ? "bgt" : | |
169 (n -> type == NODE_OPER_GE ? "blt" : | |
170 "foobar")))))) | |
171 ), label1); | |
172 fprintf(output, "\tldd #0\n\tbra %s\n%s\tldd #1\n%s\n", label2, label1, label2); | |
173 lw_free(label1); | |
174 lw_free(label2); | |
175 break; | |
176 | |
74 default: | 177 default: |
75 for (nn = n -> children; nn; nn = nn -> next_child) | 178 for (nn = n -> children; nn; nn = nn -> next_child) |
76 generate_code(nn, output); | 179 generate_code(nn, output); |
77 break; | 180 break; |
78 } | 181 } |