Those two insn types are nicer to handle as operand types, because the pressure for bits on instr_type is higher than for operands.
Unified · Split
| @@ -41,12 +41,8 @@ · 40 unmodified lines | |||
| 41 | #define OPC_ARITH 0x30 /* arithmetic opcodes */ | 41 | #define OPC_ARITH 0x30 /* arithmetic opcodes */ |
| 42 | #define OPC_FARITH 0x40 /* FPU arithmetic opcodes */ | 42 | #define OPC_FARITH 0x40 /* FPU arithmetic opcodes */ |
| 43 | #define OPC_TEST 0x50 /* test opcodes */ | 43 | #define OPC_TEST 0x50 /* test opcodes */ |
| 44 | #define OPC_JMP_TEST 0x60 /* A test and jmp opcode */ | ||
| 45 | #define OPC_JMP 0x70 /* A non-testing jmp opcode */ | ||
| 46 | #define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i)) | 44 | #define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i)) |
| 47 | 45 | ||
| 48 | #define OPC_SHORTJMP 0x80 /* short jmp operand */ | ||
| 49 | |||
| 50 | #define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */ | 46 | #define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */ |
| 51 | #ifdef TCC_TARGET_X86_64 | 47 | #ifdef TCC_TARGET_X86_64 |
| 52 | # define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */ | 48 | # define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */ |
| @@ -96,6 +92,8 @@ enum { · 43 unmodified lines | |||
| 96 | OPT_REGW, /* REG16 | REG32 | REG64 */ | 92 | OPT_REGW, /* REG16 | REG32 | REG64 */ |
| 97 | OPT_IMW, /* IM16 | IM32 */ | 93 | OPT_IMW, /* IM16 | IM32 */ |
| 98 | OPT_MMXSSE, /* MMX | SSE */ | 94 | OPT_MMXSSE, /* MMX | SSE */ |
| 95 | OPT_DISP, /* Like OPT_ADDR, but emitted as displacement (for jumps) */ | ||
| 96 | OPT_DISP8, /* Like OPT_ADDR, but only 8bit (short jumps) */ | ||
| 99 | /* can be ored with any OPT_xxx */ | 97 | /* can be ored with any OPT_xxx */ |
| 100 | OPT_EA = 0x80 | 98 | OPT_EA = 0x80 |
| 101 | }; | 99 | }; |
| @@ -627,7 +625,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 525 unmodified lines | |||
| 627 | if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX)) | 625 | if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX)) |
| 628 | continue; | 626 | continue; |
| 629 | s = (opcode - pa->sym) % NBWLX; | 627 | s = (opcode - pa->sym) % NBWLX; |
| 630 | } else if (it == OPC_TEST || it == OPC_JMP_TEST) { | 628 | } else if (it == OPC_TEST) { |
| 631 | if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) | 629 | if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) |
| 632 | continue; | 630 | continue; |
| 633 | /* cmovxx is a test opcode but accepts multiple sizes. | 631 | /* cmovxx is a test opcode but accepts multiple sizes. |
| @@ -687,6 +685,10 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 53 unmodified lines | |||
| 687 | case OPT_MMXSSE: | 685 | case OPT_MMXSSE: |
| 688 | v = OP_MMX | OP_SSE; | 686 | v = OP_MMX | OP_SSE; |
| 689 | break; | 687 | break; |
| 688 | case OPT_DISP: | ||
| 689 | case OPT_DISP8: | ||
| 690 | v = OP_ADDR; | ||
| 691 | break; | ||
| 690 | default: | 692 | default: |
| 691 | v = 1 << op2; | 693 | v = 1 << op2; |
| 692 | break; | 694 | break; |
| @@ -833,7 +835,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 140 unmodified lines | |||
| 833 | } | 835 | } |
| 834 | if (pa->instr_type & OPC_B) | 836 | if (pa->instr_type & OPC_B) |
| 835 | v += s >= 1; | 837 | v += s >= 1; |
| 836 | if (pa->instr_type & OPC_SHORTJMP) { | 838 | if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) { |
| 837 | Sym *sym; | 839 | Sym *sym; |
| 838 | int jmp_disp; | 840 | int jmp_disp; |
| 839 | 841 | ||
| @@ -861,8 +863,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 21 unmodified lines | |||
| 861 | tcc_error("invalid displacement"); | 863 | tcc_error("invalid displacement"); |
| 862 | } | 864 | } |
| 863 | } | 865 | } |
| 864 | if (OPCT_IS(pa->instr_type, OPC_TEST) | 866 | if (OPCT_IS(pa->instr_type, OPC_TEST)) |
| 865 | || OPCT_IS(pa->instr_type, OPC_JMP_TEST)) | ||
| 866 | v += test_bits[opcode - pa->sym]; | 867 | v += test_bits[opcode - pa->sym]; |
| 867 | op1 = v >> 16; | 868 | op1 = v >> 16; |
| 868 | if (op1) | 869 | if (op1) |
| @@ -955,8 +956,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) · 86 unmodified lines | |||
| 955 | } else if (v & OP_IM64) { | 956 | } else if (v & OP_IM64) { |
| 956 | gen_expr64(&ops[i].e); | 957 | gen_expr64(&ops[i].e); |
| 957 | #endif | 958 | #endif |
| 958 | } else if (OPCT_IS (pa->instr_type, OPC_JMP) | 959 | } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) { |
| 959 | || OPCT_IS (pa->instr_type, OPC_JMP_TEST)) { | ||
| 960 | gen_disp32(&ops[i].e); | 960 | gen_disp32(&ops[i].e); |
| 961 | } else { | 961 | } else { |
| 962 | gen_expr32(&ops[i].e); | 962 | gen_expr32(&ops[i].e); |
| @@ -200,9 +200,9 @@ ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA · 199 unmodified lines | |||
| 200 | ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) | 200 | ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) |
| 201 | 201 | ||
| 202 | ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) | 202 | ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) |
| 203 | ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) | 203 | ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP)) |
| 204 | ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) | 204 | ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) |
| 205 | ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) | 205 | ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8)) |
| 206 | 206 | ||
| 207 | ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) | 207 | ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) |
| 208 | ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) | 208 | ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) |
| @@ -221,13 +221,13 @@ ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) · 12 unmodified lines | |||
| 221 | DEF_ASM_OP0(lret, 0xcb) | 221 | DEF_ASM_OP0(lret, 0xcb) |
| 222 | ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) | 222 | ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) |
| 223 | 223 | ||
| 224 | ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP_TEST, OPT_ADDR)) | 224 | ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8)) |
| 225 | DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) | 225 | DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8) |
| 226 | DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) | 226 | DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8) |
| 227 | DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) | 227 | DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8) |
| 228 | DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) | 228 | DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8) |
| 229 | DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) | 229 | DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8) |
| 230 | DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) | 230 | DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8) |
| 231 | 231 | ||
| 232 | /* float */ | 232 | /* float */ |
| 233 | /* specific fcomp handling */ | 233 | /* specific fcomp handling */ |
| @@ -207,9 +207,9 @@ ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA · 206 unmodified lines | |||
| 207 | ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) | 207 | ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) |
| 208 | 208 | ||
| 209 | ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) | 209 | ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) |
| 210 | ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) | 210 | ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP)) |
| 211 | ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) | 211 | ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) |
| 212 | ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) | 212 | ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8)) |
| 213 | 213 | ||
| 214 | ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) | 214 | ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) |
| 215 | ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA)) | 215 | ALT(DEF_ASM_OP1(ljmp, 0xff, 5, OPC_MODRM, OPT_EA)) |
| @@ -226,13 +226,13 @@ ALT(DEF_ASM_OP1(ret, 0xc2, 0, 0, OPT_IM16)) · 10 unmodified lines | |||
| 226 | DEF_ASM_OP0(lret, 0xcb) | 226 | DEF_ASM_OP0(lret, 0xcb) |
| 227 | ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) | 227 | ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) |
| 228 | 228 | ||
| 229 | ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP_TEST, OPT_ADDR)) | 229 | ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8)) |
| 230 | DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) | 230 | DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8) |
| 231 | DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) | 231 | DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8) |
| 232 | DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) | 232 | DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8) |
| 233 | DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) | 233 | DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8) |
| 234 | DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) | 234 | DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8) |
| 235 | DEF_ASM_OP1(jecxz, 0x67e3, 0, OPC_SHORTJMP, OPT_ADDR) | 235 | DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8) |
| 236 | 236 | ||
| 237 | /* float */ | 237 | /* float */ |
| 238 | /* specific fcomp handling */ | 238 | /* specific fcomp handling */ |