ins.c (5731B)
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 }