Mercurial > hg > index.cgi
annotate lwcc/cc-gencode.c @ 503:17fa03d69df3
Unbork "make install"
The merge of the lwcc stuff borked the Makefile some. This should unbork it.
At least it should install the binaries in .../bin again.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 26 Sep 2019 21:37:49 -0600 |
parents | 14a40f8bb4eb |
children | 59b8c8b15bd4 |
rev | line source |
---|---|
499 | 1 /* |
2 lwcc/cc-gencode.c | |
3 | |
4 Copyright © 2019 William Astle | |
5 | |
6 This file is part of LWTOOLS. | |
7 | |
8 LWTOOLS is free software: you can redistribute it and/or modify it under the | |
9 terms of the GNU General Public License as published by the Free Software | |
10 Foundation, either version 3 of the License, or (at your option) any later | |
11 version. | |
12 | |
13 This program is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 more details. | |
17 | |
18 You should have received a copy of the GNU General Public License along with | |
19 this program. If not, see <http://www.gnu.org/licenses/>. | |
20 */ | |
21 | |
22 #include <stdio.h> | |
23 #include <string.h> | |
24 | |
25 #include <lw_alloc.h> | |
26 #include <lw_string.h> | |
27 | |
28 #include "tree.h" | |
29 | |
502 | 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 | |
499 | 39 void generate_code(node_t *n, FILE *output) |
40 { | |
41 node_t *nn; | |
502 | 42 char *label1, *label2; |
43 | |
499 | 44 switch (n -> type) |
45 { | |
46 // function definition - output prologue, then statements, then epilogue | |
47 case NODE_FUNDEF: | |
48 fprintf(output, "_%s\n", n->children->next_child->strval); | |
49 generate_code(n->children->next_child->next_child->next_child, output); | |
50 fprintf(output, "\trts\n"); | |
51 break; | |
52 | |
53 case NODE_CONST_INT: | |
54 fprintf(output, "\tldd #%s\n", n->strval); | |
55 break; | |
56 | |
501
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
57 case NODE_OPER_PLUS: |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
58 generate_code(n->children, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
59 fprintf(output, "\tpshs d\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
60 generate_code(n->children->next_child, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
61 fprintf(output, "\taddd ,s++\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
62 break; |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
63 |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
64 case NODE_OPER_MINUS: |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
65 generate_code(n->children, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
66 fprintf(output, "\tpshs d,x\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
67 generate_code(n->children->next_child, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
68 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
|
69 break; |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
70 |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
71 case NODE_OPER_TIMES: |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
72 generate_code(n -> children, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
73 fprintf(output, "\tpshs d\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
74 generate_code(n->children->next_child, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
75 fprintf(output, "\tjsr ___mul16i\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
76 break; |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
77 |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
78 case NODE_OPER_DIVIDE: |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
79 generate_code(n -> children, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
80 fprintf(output, "\tpshs d\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
81 generate_code(n->children->next_child, output); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
82 fprintf(output, "\tjsr ___div16i\n"); |
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
83 break; |
502 | 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; | |
501
f3e9732973f1
Add basic integer operations to lwcc
William Astle <lost@l-w.ca>
parents:
499
diff
changeset
|
91 |
502 | 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 | |
499 | 177 default: |
178 for (nn = n -> children; nn; nn = nn -> next_child) | |
179 generate_code(nn, output); | |
180 break; | |
181 } | |
182 } |