ins.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
ins.c (4576B)
---
1 #include <stdlib.h>
2
3 #include <scc/mach.h>
4 #include <scc/scc.h>
5
6 #include "../as.h"
7 #include "proc.h"
8
9 /*
10 * This code is derived from PowerISA_V2.06B_V2_PUBLIC document.
11 * All the names used in the specification are preserved in
12 * this code.
13 */
14
15 static int
16 getclass(Node *np)
17 {
18 if (np->addr != AREG)
19 return 0;
20
21 switch (np->sym->value) {
22 case AREG_R0:
23 case AREG_R1:
24 case AREG_R2:
25 case AREG_R3:
26 case AREG_R4:
27 case AREG_R5:
28 case AREG_R6:
29 case AREG_R7:
30 case AREG_R8:
31 case AREG_R9:
32 case AREG_R10:
33 case AREG_R11:
34 case AREG_R12:
35 case AREG_R13:
36 case AREG_R14:
37 case AREG_R15:
38 case AREG_R16:
39 case AREG_R17:
40 case AREG_R18:
41 case AREG_R19:
42 case AREG_R20:
43 case AREG_R21:
44 case AREG_R22:
45 case AREG_R23:
46 case AREG_R24:
47 case AREG_R25:
48 case AREG_R26:
49 case AREG_R27:
50 case AREG_R29:
51 case AREG_R30:
52 case AREG_R31:
53 return GPRSCLASS;
54 default:
55 abort();
56 }
57 }
58
59 int
60 match(Op *op, Node **args)
61 {
62 unsigned char *p;
63 int arg, class, rep, opt;
64 Node *np;
65
66 if (!op->args)
67 return args == NULL;
68
69 opt = rep = 0;
70 for (p = op->args; arg = *p; ++p) {
71 if (rep)
72 --p;
73 if ((np = *args++) == NULL)
74 return (rep|opt) != 0;
75
76 switch (arg) {
77 case AOPT:
78 opt = 1;
79 break;
80 case AREP:
81 rep = 1;
82 break;
83 case AREG_GPRSCLASS:
84 class = GPRSCLASS;
85 check_class:
86 if ((getclass(np) & class) == 0)
87 return 0;
88 break;
89 case AIMM2:
90 case AIMM5:
91 case AIMM8:
92 case AIMM16:
93 case AIMM32:
94 case AIMM64:
95 if (np->addr != AIMM)
96 return 0;
97 if (toobig(np, arg))
98 error("overflow in immediate operand");
99 break;
100 case ASYM:
101 if (np->op != IDEN)
102 return 0;
103 break;
104 case ADIRECT:
105 case ASTR:
106 if (np->addr != arg)
107 return 0;
108 break;
109 default:
110 abort();
111 }
112 }
113
114 return *args == NULL;
115 }
116
117 Node *
118 moperand(void)
119 {
120 abort();
121 }
122
123 static void
124 emit_packed(unsigned long ins)
125 {
126 char buff[4];
127
128 if (endian == BIG_ENDIAN) {
129 buff[0] = ins >> 24;
130 buff[1] = ins >> 16;
131 buff[2] = ins >> 8;
132 buff[3] = ins;
133 } else {
134 buff[0] = ins;
135 buff[1] = ins >> 8;
136 buff[2] = ins >> 16;
137 buff[3] = ins >> 24;
138 }
139
140 emit(buff, 4);
141 }
142
143 void
144 i_form(Op *op, Node **args)
145 {
146 unsigned long ins, opcd, li, aa, lk;
147 long long dst;
148 long long max = 1l << 23;
149 long long min = -(1l << 23);
150
151 opcd = op->bytes[0];
152 aa = op->bytes[1];
153 lk = op->bytes[2];
154
155 dst = args[0]->sym->value;
156 if (dst & 0x3)
157 error("unaligned branch");
158 if (aa)
159 dst -= getpc() - 4;
160 if (dst < min || dst > max)
161 error("out of range branch");
162
163 li = dst;
164 li >>= 2;
165 ins = opcd<<26 | li<<2 | aa<<1 | lk;
166 emit_packed(ins);
167 }
168
169 void
170 b_form(Op *op, Node **args)
171 {
172 unsigned long ins, opcd, bo, bi, bd, aa, lk;
173 long long dst;
174 long long max = 1l << 13;
175 long long min = -(1l << 13);
176
177 opcd = op->bytes[0];
178 aa = op->bytes[1];
179 lk = op->bytes[2];
180
181 bo = args[0]->sym->value;
182 bi = args[1]->sym->value;
183
184 dst = args[2]->sym->value;
185 if (dst & 0x3)
186 error("unaligned branch");
187 if (aa)
188 dst -= getpc() - 4;
189
190 if (dst < min || dst > max)
191 error("out of range branch");
192 bd = dst;
193 bd >>= 2;
194
195 ins = opcd<<26 | bo<<21 | bi<<16 | bd<<11 | aa<<1 | lk;
196 emit_packed(ins);
197 }
198
199 void
200 sc_form(Op *op, Node **args)
201 {
202 abort();
203 }
204
205 void
206 d_form(Op *op, Node **args)
207 {
208 abort();
209 }
210
211 void
212 ds_form(Op *op, Node **args)
213 {
214 abort();
215 }
216
217 void
218 dq_form(Op *op, Node **args)
219 {
220 abort();
221 }
222
223 void
224 x_form(Op *op, Node **args)
225 {
226 abort();
227 }
228
229 void
230 xl_form(Op *op, Node **args)
231 {
232 unsigned long ins, bo, bi, bh, lk;
233 unsigned long opcd1, opcd2;
234 long long dst;
235
236 opcd1 = op->bytes[0];
237 opcd2 = op->bytes[1]<<8 | op->bytes[2];
238 lk = op->bytes[3];
239
240 bo = args[0]->sym->value;
241 bi = args[1]->sym->value;
242 bh = args[2]->sym->value;
243
244 ins = opcd1<<26 | bo<<21 | bi<<16 | bh<<11 | opcd2<<1 | lk;
245 emit_packed(ins);
246 }
247
248 void
249 xfx_form(Op *op, Node **args)
250 {
251 abort();
252 }
253
254 void
255 xlfdorm_form(Op *op, Node **args)
256 {
257 abort();
258 }
259
260 void
261 xx1_form(Op *op, Node **args)
262 {
263 abort();
264 }
265
266 void
267 xx2_form(Op *op, Node **args)
268 {
269 abort();
270 }
271
272 void
273 xx3_form(Op *op, Node **args)
274 {
275 abort();
276 }
277
278 void
279 xx4_form(Op *op, Node **args)
280 {
281 abort();
282 }
283
284 void
285 xs_form(Op *op, Node **args)
286 {
287 abort();
288 }
289
290 void
291 xo_form(Op *op, Node **args)
292 {
293 abort();
294 }
295
296 void
297 a_form(Op *op, Node **args)
298 {
299 abort();
300 }
301
302 void
303 m_form(Op *op, Node **args)
304 {
305 abort();
306 }
307
308 void
309 md_form(Op *op, Node **args)
310 {
311 abort();
312 }
313
314 void
315 mds_form(Op *op, Node **args)
316 {
317 abort();
318 }
319
320 void
321 va_form(Op *op, Node **args)
322 {
323 abort();
324 }
325
326 void
327 vc_form(Op *op, Node **args)
328 {
329 abort();
330 }
331
332 void
333 vx_form(Op *op, Node **args)
334 {
335 abort();
336 }
337
338 void
339 evs_form(Op *op, Node **args)
340 {
341 abort();
342 }
343
344 void
345 z22_form(Op *op, Node **args)
346 {
347 abort();
348 }
349
350 void
351 z23_form(Op *op, Node **args)
352 {
353 abort();
354 }