From e2f489aaffdc5806a993a04c121a5b75ac08daaf Mon Sep 17 00:00:00 2001 From: Michael Matz Date: Mon, 16 May 2016 05:58:30 +0200 Subject: [PATCH] x86-asm: Get rid of OPC_JMP and OPC_SHORTJMP Those two insn types are nicer to handle as operand types, because the pressure for bits on instr_type is higher than for operands. --- i386-asm.c | 20 ++++++++++---------- i386-asm.h | 18 +++++++++--------- x86_64-asm.h | 18 +++++++++--------- 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/i386-asm.c b/i386-asm.c index a087188..e7449bf 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -41,12 +41,8 @@ #define OPC_ARITH 0x30 /* arithmetic opcodes */ #define OPC_FARITH 0x40 /* FPU arithmetic opcodes */ #define OPC_TEST 0x50 /* test opcodes */ -#define OPC_JMP_TEST 0x60 /* A test and jmp opcode */ -#define OPC_JMP 0x70 /* A non-testing jmp opcode */ #define OPCT_IS(v,i) (((v) & OPCT_MASK) == (i)) -#define OPC_SHORTJMP 0x80 /* short jmp operand */ - #define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */ #ifdef TCC_TARGET_X86_64 # define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */ @@ -96,6 +92,8 @@ enum { OPT_REGW, /* REG16 | REG32 | REG64 */ OPT_IMW, /* IM16 | IM32 */ OPT_MMXSSE, /* MMX | SSE */ + OPT_DISP, /* Like OPT_ADDR, but emitted as displacement (for jumps) */ + OPT_DISP8, /* Like OPT_ADDR, but only 8bit (short jumps) */ /* can be ored with any OPT_xxx */ OPT_EA = 0x80 }; @@ -627,7 +625,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX)) continue; s = (opcode - pa->sym) % NBWLX; - } else if (it == OPC_TEST || it == OPC_JMP_TEST) { + } else if (it == OPC_TEST) { if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES)) continue; /* cmovxx is a test opcode but accepts multiple sizes. @@ -687,6 +685,10 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) case OPT_MMXSSE: v = OP_MMX | OP_SSE; break; + case OPT_DISP: + case OPT_DISP8: + v = OP_ADDR; + break; default: v = 1 << op2; break; @@ -833,7 +835,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) } if (pa->instr_type & OPC_B) v += s >= 1; - if (pa->instr_type & OPC_SHORTJMP) { + if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) { Sym *sym; int jmp_disp; @@ -861,8 +863,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) tcc_error("invalid displacement"); } } - if (OPCT_IS(pa->instr_type, OPC_TEST) - || OPCT_IS(pa->instr_type, OPC_JMP_TEST)) + if (OPCT_IS(pa->instr_type, OPC_TEST)) v += test_bits[opcode - pa->sym]; op1 = v >> 16; if (op1) @@ -955,8 +956,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode) } else if (v & OP_IM64) { gen_expr64(&ops[i].e); #endif - } else if (OPCT_IS (pa->instr_type, OPC_JMP) - || OPCT_IS (pa->instr_type, OPC_JMP_TEST)) { + } else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) { gen_disp32(&ops[i].e); } else { gen_expr32(&ops[i].e); diff --git a/i386-asm.h b/i386-asm.h index 338fa69..7a8fb0d 100644 --- a/i386-asm.h +++ b/i386-asm.h @@ -200,9 +200,9 @@ ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) +ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP)) ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) +ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8)) ALT(DEF_ASM_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32)) 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)) DEF_ASM_OP0(lret, 0xcb) ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) -ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP_TEST, OPT_ADDR)) - DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR) +ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8)) + DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8) + DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8) /* float */ /* specific fcomp handling */ diff --git a/x86_64-asm.h b/x86_64-asm.h index 246c237..cf67e69 100644 --- a/x86_64-asm.h +++ b/x86_64-asm.h @@ -207,9 +207,9 @@ ALT(DEF_ASM_OP3(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_CL, OPT_REGW, OPT_EA ALT(DEF_ASM_OP2(shrdw, 0x0fad, 0, OPC_MODRM | OPC_WLX, OPT_REGW, OPT_EA | OPT_REGW)) ALT(DEF_ASM_OP1(call, 0xff, 2, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(call, 0xe8, 0, OPC_JMP, OPT_ADDR)) +ALT(DEF_ASM_OP1(call, 0xe8, 0, 0, OPT_DISP)) ALT(DEF_ASM_OP1(jmp, 0xff, 4, OPC_MODRM, OPT_INDIR)) -ALT(DEF_ASM_OP1(jmp, 0xeb, 0, OPC_SHORTJMP | OPC_JMP, OPT_ADDR)) +ALT(DEF_ASM_OP1(jmp, 0xeb, 0, 0, OPT_DISP8)) ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA)) 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)) DEF_ASM_OP0(lret, 0xcb) ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16)) -ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP_TEST, OPT_ADDR)) - DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR) - DEF_ASM_OP1(jecxz, 0x67e3, 0, OPC_SHORTJMP, OPT_ADDR) +ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8)) + DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8) + DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8) + DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8) /* float */ /* specific fcomp handling */