-
Notifications
You must be signed in to change notification settings - Fork 0
/
codegen.c
163 lines (159 loc) · 3.61 KB
/
codegen.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include "ycc.h"
int labseq=0;
void gen_lval(Node *node) {
if (node->kind != ND_LVAR)
error("left value is not a var");
printf("LD ACC 1300H\n");
printf("SUB ACC, %d\n", node->offset);
printf("PSH ACC\n");
}
void gen(Node *node) {
switch (node->kind) {
case ND_FOR:{
int seq = labseq++;
gen(node->init);
printf("LLbegin%d:\n", seq);
gen(node->cond);
printf("POP ACC\n");
printf("CMP ACC, 0\n");
printf("BZ LLend%d\n", seq);
gen(node->then);
gen(node->cntr);
printf("BA LLbegin%d\n", seq);
printf("LLend%d:\n", seq);
printf("NOP\n");
}
case ND_WHILE:{
int seq = labseq++;
printf("LLbegin%d:\n", seq);
gen(node->cond);
printf("POP ACC\n");
printf("CMP ACC, 0\n");
printf("BZ LLend%d\n", seq);
gen(node->then);
printf("BA LLbegin%d\n", seq);
printf("LLend%d:\n", seq);
printf("NOP\n");
}
case ND_IF: {
int seq = labseq++;
if (node->els) {
gen(node->cond);
printf("POP ACC\n");
printf("CMP ACC, 0\n");
printf("BZ LLelse%d\n", seq);
gen(node->then);
printf("BA LLend%d\n", seq);
printf("LLelse%d:\n", seq);
gen(node->els);
printf("LLend%d:\n", seq);
printf("NOP\n");
}
else {
gen(node->cond);
printf("POP ACC\n");
printf("CMP ACC, 0\n");
printf("BZ LLend%d\n", seq);
gen(node->then);
printf("LLend%d:\n", seq);
printf("NOP\n");
}
return;
}
case ND_BLOCK:
for(Node *n=node->body;n;n=n->next){
gen(n);
}
return;
case ND_RETURN:
gen(node->lhs);
printf("POP ACC\n");
printf("OUT\n");
//printf("LD SP, 1300H\n");
//printf("POP ACC\n");
//printf("RET\n");
return;
case ND_NUM:
printf("LD ACC %d\n", node->val);
printf("PSH ACC\n");
return;
case ND_LVAR:
gen_lval(node);
printf("POP IX\n");
printf("LD ACC, [IX]\n");
printf("PSH ACC\n");
return;
case ND_ASSIGN:
gen_lval(node->lhs);
gen(node->rhs);
printf("POP ACC\n");
printf("POP IX\n");
printf("ST ACC [IX]\n");
printf("PSH ACC\n");
return;
case ND_GOTO:
printf("BA LLgoto%d\n",node->str[0]);
return;
case ND_LABEL:
printf("LLgoto%d:\n",node->str[0]);
return;
}
gen(node->lhs);
gen(node->rhs);
printf("POP IX\n");
printf("POP ACC\n");
int seq = labseq++;
switch (node->kind) {
case ND_ADD:
printf("ADD ACC, IX\n");
break;
case ND_SUB:
printf("SUB ACC, IX\n");
break;
case ND_MUL:
printf("imul ACC, IX\n");
break;
case ND_DIV:
printf("cqo\n");
printf("idiv IX\n");
break;
case ND_EQ:
printf("CMP ACC, IX\n");
printf("BZ ND_EQ_JP1%d\n",seq);
printf("LD ACC 0\n");
printf("BA ND_EQ_JP2%d\n",seq);
printf("ND_EQ_JP1%d:\n",seq);
printf("LD ACC 1\n");
printf("ND_EQ_JP2%d:\n",seq);
break;
case ND_NE:
printf("CMP ACC, IX\n");
printf("BNZ ND_EQ_JP1%d\n",seq);
printf("LD ACC 0\n");
printf("BA ND_EQ_JP2%d\n",seq);
printf("ND_EQ_JP1%d:\n",seq);
printf("LD ACC 1\n");
printf("ND_EQ_JP2%d:\n",seq);
break;
case ND_LT:
printf("CMP ACC, IX\n");
printf("BN ND_EQ_JP1%d\n",seq);
printf("LD ACC 0\n");
printf("BA ND_EQ_JP2%d\n",seq);
printf("ND_EQ_JP1%d:\n",seq);
printf("LD ACC 1\n");
printf("ND_EQ_JP2%d:\n",seq);
break;
case ND_LE:
printf("CMP ACC, IX\n");
printf("BZN ND_EQ_JP1%d\n",seq);
printf("LD ACC 0\n");
printf("BA ND_EQ_JP2%d\n",seq);
printf("ND_EQ_JP1%d:\n",seq);
printf("LD ACC 1\n");
printf("ND_EQ_JP2%d:\n",seq);
break;
break;
}
printf("PSH ACC\n");
}