scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | 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 }