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 (5728B)
---
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include <scc/mach.h>
5 #include <scc/scc.h>
6
7 #include "../as.h"
8 #include "proc.h"
9
10 #define addrbyte(mod, reg, rm) ((mod) << 6 | (reg) << 3 | (rm))
11
12 /*
13 * This implementation is based in:
14 * - x86 Opcode Structure and Instruction Overview - Fraunhofer-Institut
15 * fÜr kommunikation, informationsverarbeitung und ergonomie fkie.
16 * - Intel® 64 and IA-32 Architectures Software Developer’s Manual.
17 * - Encoding Real x86 Instructions - CIS-77 lectures.
18 */
19 enum addr_mode {
20 MEM_MODE = 0,
21 MEM8_MODE = 1,
22 MEM16_MODE = 2,
23 REG_MODE = 3,
24 };
25
26 static int
27 getclass(Node *np)
28 {
29 if (np->addr != AREG)
30 return 0;
31
32 switch (np->sym->value) {
33 case AREG_AL:
34 case AREG_AH:
35 case AREG_BL:
36 case AREG_BH:
37 case AREG_CL:
38 case AREG_CH:
39 case AREG_DL:
40 case AREG_DH:
41 return R8CLASS;
42
43 case AREG_AX:
44 case AREG_BX:
45 case AREG_CX:
46 case AREG_DX:
47 case AREG_DI:
48 case AREG_SI:
49 case AREG_SP:
50 case AREG_BP:
51 return R16CLASS;
52
53 case AREG_CS:
54 case AREG_DS:
55 case AREG_SS:
56 case AREG_ES:
57 case AREG_FS:
58 case AREG_GS:
59
60 case AREG_EFLAGS:
61 case AREG_CF:
62 case AREG_PF:
63 case AREG_AF:
64 case AREG_ZF:
65 case AREG_SF:
66 case AREG_TF:
67 case AREG_IF:
68 case AREG_DF:
69 case AREG_OF:
70 case AREG_IOPL:
71 case AREG_NT:
72 case AREG_RF:
73 case AREG_VM:
74 case AREG_AC:
75 case AREG_VIF:
76 case AREG_VIP:
77 case AREG_ID:
78
79 case AREG_EAX:
80 case AREG_RAX:
81
82 case AREG_EBX:
83 case AREG_RBX:
84
85 case AREG_ECX:
86 case AREG_RCX:
87
88 case AREG_EDX:
89 case AREG_RDX:
90
91 case AREG_SIL:
92 case AREG_ESI:
93 case AREG_RSI:
94 case AREG_DIL:
95 case AREG_EDI:
96 case AREG_RDI:
97
98 case AREG_SPL:
99 case AREG_ESP:
100 case AREG_RSP:
101
102 case AREG_BPL:
103 case AREG_EBP:
104 case AREG_RBP:
105
106 case AREG_R0:
107 case AREG_MM0:
108 case AREG_R1:
109 case AREG_MM1:
110 case AREG_R2:
111 case AREG_MM2:
112 case AREG_R3:
113 case AREG_MM3:
114 case AREG_R4:
115 case AREG_MM4:
116 case AREG_R5:
117 case AREG_MM5:
118 case AREG_R6:
119 case AREG_MM6:
120 case AREG_R7:
121 case AREG_MM7:
122
123 case AREG_R8:
124 case AREG_R8L:
125 case AREG_R8W:
126 case AREG_R9:
127 case AREG_R9L:
128 case AREG_R9W:
129 case AREG_R10:
130 case AREG_R10L:
131 case AREG_R10W:
132 case AREG_R11:
133 case AREG_R11L:
134 case AREG_R11W:
135 case AREG_R12:
136 case AREG_R12L:
137 case AREG_R12W:
138 case AREG_R13:
139 case AREG_R13L:
140 case AREG_R13W:
141 case AREG_R14:
142 case AREG_R14L:
143 case AREG_R14W:
144 case AREG_R15:
145 case AREG_R15L:
146 case AREG_R15W:
147
148 case AREG_XMM0:
149 case AREG_XMM1:
150 case AREG_XMM2:
151 case AREG_XMM3:
152 case AREG_XMM4:
153 case AREG_XMM5:
154 case AREG_XMM6:
155 case AREG_XMM7:
156 case AREG_XMM8:
157 case AREG_XMM9:
158 case AREG_XMM10:
159 case AREG_XMM11:
160 case AREG_XMM12:
161 case AREG_XMM13:
162 case AREG_XMM14:
163 case AREG_XMM15:
164
165 case AREG_YMM0:
166 case AREG_YMM1:
167 case AREG_YMM2:
168 case AREG_YMM3:
169 case AREG_YMM4:
170 case AREG_YMM5:
171 case AREG_YMM6:
172 case AREG_YMM7:
173 case AREG_YMM8:
174 case AREG_YMM9:
175 case AREG_YMM10:
176 case AREG_YMM11:
177 case AREG_YMM12:
178 case AREG_YMM13:
179 case AREG_YMM14:
180 case AREG_YMM15:
181
182 case AREG_MXCSR:
183 return 0;
184 default:
185 abort();
186 }
187 }
188
189 int
190 match(Op *op, Node **args)
191 {
192 unsigned char *p;
193 int arg, class, rep, opt;
194 Node *np;
195
196 if (!op->args)
197 return args == NULL;
198
199 opt = rep = 0;
200 for (p = op->args; arg = *p; ++p) {
201 if (rep)
202 --p;
203 if ((np = *args++) == NULL)
204 return (rep|opt) != 0;
205
206 switch (arg) {
207 case AOPT:
208 opt = 1;
209 break;
210 case AREP:
211 rep = 1;
212 break;
213 case AREG_R8CLASS:
214 class = R8CLASS;
215 goto check_class;
216 case AREG_R16CLASS:
217 class = R16CLASS;
218 check_class:
219 if ((getclass(np) & class) == 0)
220 return 0;
221 break;
222 case AIMM8:
223 case AIMM16:
224 case AIMM32:
225 case AIMM64:
226 if (np->addr != AIMM)
227 return 0;
228 if (toobig(np, arg))
229 error("overflow in immediate operand");
230 break;
231 case ASYM:
232 if (np->op != IDEN)
233 return 0;
234 break;
235 case ADIRECT:
236 case ASTR:
237 if (np->addr != arg)
238 return 0;
239 break;
240 default:
241 abort();
242 }
243 }
244
245 return *args == NULL;
246 }
247
248 Node *
249 moperand(void)
250 {
251 }
252
253 static int
254 reg8toint(Node *np)
255 {
256 switch (np->sym->value) {
257 case AREG_AL: return 0;
258 case AREG_CL: return 1;
259 case AREG_DL: return 2;
260 case AREG_BL: return 3;
261 case AREG_AH: return 4;
262 case AREG_CH: return 5;
263 case AREG_DH: return 6;
264 case AREG_BH: return 7;
265 default: abort();
266 }
267 }
268
269 static int
270 reg16toint(Node *np)
271 {
272 switch (np->sym->value) {
273 case AREG_AX: return 0;
274 case AREG_CX: return 1;
275 case AREG_DX: return 2;
276 case AREG_BX: return 3;
277 case AREG_SP: return 4;
278 case AREG_BP: return 5;
279 case AREG_SI: return 6;
280 case AREG_DI: return 7;
281 default: abort();
282 }
283 }
284
285 static int
286 reg32toint(Node *np)
287 {
288 switch (np->sym->value) {
289 case AREG_EAX: return 0;
290 case AREG_ECX: return 1;
291 case AREG_EDX: return 2;
292 case AREG_EBX: return 3;
293 case AREG_ESP: return 4;
294 case AREG_EBP: return 5;
295 case AREG_ESI: return 6;
296 case AREG_EDI: return 7;
297 default: abort();
298 }
299 }
300
301 void
302 reg8_reg8(Op *op, Node **args)
303 {
304 int src, dst;
305 char buf[op->size];
306
307 src = reg8toint(args[0]);
308 dst = reg8toint(args[1]);
309 memcpy(buf, op->bytes, op->size - 1);
310 buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
311 emit(buf, op->size);
312 }
313
314 void
315 imm8_reg8(Op *op, Node **args)
316 {
317 int src, dst;
318 char buf[op->size];
319
320 src = (*args)->sym->value;
321 dst = reg8toint(args[1]);
322 memcpy(buf, op->bytes, op->size - 2);
323 buf[op->size - 2] = addrbyte(REG_MODE, 0, dst);
324 buf[op->size - 1] = src;
325 emit(buf, op->size);
326 }
327
328
329 void
330 reg16_reg16(Op *op, Node **args)
331 {
332 int src, dst;
333 char buf[op->size];
334
335 src = reg16toint(args[0]);
336 dst = reg16toint(args[1]);
337 memcpy(buf, op->bytes, op->size - 1);
338 buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
339 emit(buf, op->size);
340 }
341
342
343 void
344 reg32_reg32(Op *op, Node **args)
345 {
346 int src, dst;
347 char buf[op->size];
348
349 src = reg32toint(args[0]);
350 dst = reg32toint(args[1]);
351 memcpy(buf, op->bytes, op->size - 1);
352 buf[op->size - 1] = addrbyte(REG_MODE, src, dst);
353 emit(buf, op->size);
354 }