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 }