code.c - scc - simple c99 compiler
HTML git clone git://git.simple-cc.org/scc
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
code.c (3281B)
---
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <scc/scc.h>
7
8 #include "cc2.h"
9
10 Inst *pc, *prog;
11
12 static void
13 nextpc(void)
14 {
15 Inst *new;
16
17 new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */
18
19 if (!pc) {
20 prog = new;
21 } else {
22 new->next = pc->next;
23 pc->next = new;
24 }
25
26 /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */
27 new->prev = pc;
28 pc = new;
29 }
30
31 static void
32 addr(Node *np, Addr *addr)
33 {
34 Symbol *sym;
35
36 switch (np->op) {
37 case OMREG:
38 addr->kind = SREG;
39 addr->u.reg = np->u.reg;
40 break;
41 case OCONST:
42 addr->kind = SCONST;
43 /* TODO: Add support for more type of constants */
44 addr->u.i = np->u.i;
45 break;
46 case OINDEX:
47 addr->kind = SINDEX;
48 addr->u.off = np->u.off;
49 break;
50 case OREG:
51 case OTMP:
52 case OLABEL:
53 case OAUTO:
54 case OMEM:
55 sym = np->u.sym;
56 addr->kind = sym->kind;
57 addr->u.sym = sym;
58 break;
59 default:
60 abort();
61 }
62 }
63
64 void
65 pprint(char *s)
66 {
67 int c;
68 char *t;
69
70 putchar('"');
71 while ((c = *s++) != '\0') {
72 switch (c) {
73 case '\n':
74 t = "\\n";
75 goto print_str;
76 case '\v':
77 t = "\\v";
78 goto print_str;
79 case '\b':
80 t = "\\b";
81 goto print_str;
82 case '\t':
83 t = "\\t";
84 goto print_str;
85 case '\f':
86 t = "\\f";
87 goto print_str;
88 case '\r':
89 t = "\\r";
90 goto print_str;
91 case '"':
92 t = "\\\"";
93 goto print_str;
94 case '\\':
95 putchar('\\');
96 default:
97 if (!isprint(c))
98 printf("\\x%x", c);
99 else
100 putchar(c);
101 break;
102 print_str:
103 fputs(t, stdout);
104 break;
105 }
106 }
107 putchar('"');
108 }
109
110 Symbol *
111 newlabel(void)
112 {
113 Symbol *sym = getsym(TMPSYM);
114
115 sym->kind = SLABEL;
116 return sym;
117 }
118
119 Node *
120 labelstmt(Node *np, Symbol *sym)
121 {
122 if(!sym)
123 sym = newlabel();
124 if (!np)
125 np = node(ONOP);
126 np->label = sym;
127 sym->u.stmt = np;
128
129 return np;
130 }
131
132 Node *
133 label2node(Node *np, Symbol *sym)
134 {
135 if(!sym)
136 sym = newlabel();
137 if (!np)
138 np = node(OLABEL);
139 np->op = OLABEL;
140 np->u.sym = sym;
141
142 return np;
143 }
144
145 Node *
146 tmpnode(Type *tp, Symbol *sym)
147 {
148 unsigned short flags;
149 Node *np;
150
151 np = node(OTMP);
152 if (!sym) {
153 sym = getsym(TMPSYM);
154 sym->type = np->type = *tp;
155 sym->kind = STMP;
156 }
157
158 flags = tp->flags & ~(PARF|INITF);
159 sym->type.flags = np->type.flags = flags;
160 np->type = *tp;
161 np->left = np->right = NULL;
162 np->u.sym = sym;
163 np->op = OTMP;
164
165 return np;
166 }
167
168 Node *
169 idxnode(Node *np, long off)
170 {
171 if (!np)
172 np = node(OINDEX);
173 np->op = OINDEX;
174 np->left = np->right = NULL;
175 np->type = ptrtype;
176 np->u.off = off;
177 return np;
178 }
179
180 Node *
181 constnode(Node *np, unsigned long long n, Type *tp)
182 {
183 if (!np)
184 np = node(OCONST);
185 np->op = OCONST;
186 np->left = np->right = NULL;
187 np->type = *tp;
188 np->u.i = n;
189 return np;
190 }
191
192 void
193 setlabel(Symbol *sym)
194 {
195 if (!sym)
196 return;
197 code(ASLABEL, NULL, NULL, NULL);
198 pc->label = sym;
199 sym->u.inst = pc;
200 }
201
202 void
203 code(int op, Node *to, Node *from1, Node *from2)
204 {
205 nextpc();
206 if (from1)
207 addr(from1, &pc->from1);
208 if (from2)
209 addr(from2, &pc->from2);
210 if (to)
211 addr(to, &pc->to);
212 pc->op = op;
213 }
214
215 void
216 delcode(void)
217 {
218 Inst *prev = pc->prev, *next = pc->next;
219
220 free(pc);
221 if (!prev) {
222 prog = pc = next;
223 } else {
224 pc = prev;
225 prev->next = next;
226 if (next)
227 next->prev = prev;
228 }
229 }