scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  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 */
 19enum addr_mode {
 20	MEM_MODE   = 0,
 21	MEM8_MODE  = 1,
 22	MEM16_MODE = 2,
 23	REG_MODE   = 3,
 24};
 25
 26static int
 27getclass(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
189int
190match(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
248Node *
249moperand(void)
250{
251}
252
253static int
254reg8toint(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
269static int
270reg16toint(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
285static int
286reg32toint(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
301void
302reg8_reg8(Op *op, Node **args)
303{
304	int src, dst;
305	unsigned 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
314void
315imm8_reg8(Op *op, Node **args)
316{
317	int src, dst;
318	unsigned 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
329void
330reg16_reg16(Op *op, Node **args)
331{
332	int src, dst;
333	unsigned 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
343void
344reg32_reg32(Op *op, Node **args)
345{
346	int src, dst;
347	unsigned 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}