scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

ins.c (5466B)


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