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.
This commit is contained in:
parent
4094f7c5fc
commit
e2f489aaff
3 changed files with 28 additions and 28 deletions
20
i386-asm.c
20
i386-asm.c
|
|
@ -41,12 +41,8 @@
|
||||||
#define OPC_ARITH 0x30 /* arithmetic opcodes */
|
#define OPC_ARITH 0x30 /* arithmetic opcodes */
|
||||||
#define OPC_FARITH 0x40 /* FPU arithmetic opcodes */
|
#define OPC_FARITH 0x40 /* FPU arithmetic opcodes */
|
||||||
#define OPC_TEST 0x50 /* test 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 OPCT_IS(v,i) (((v) & OPCT_MASK) == (i))
|
||||||
|
|
||||||
#define OPC_SHORTJMP 0x80 /* short jmp operand */
|
|
||||||
|
|
||||||
#define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */
|
#define OPC_0F 0x100 /* Is secondary map (0x0f prefix) */
|
||||||
#ifdef TCC_TARGET_X86_64
|
#ifdef TCC_TARGET_X86_64
|
||||||
# define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */
|
# define OPC_WLQ 0x1000 /* accepts w, l, q or no suffix */
|
||||||
|
|
@ -96,6 +92,8 @@ enum {
|
||||||
OPT_REGW, /* REG16 | REG32 | REG64 */
|
OPT_REGW, /* REG16 | REG32 | REG64 */
|
||||||
OPT_IMW, /* IM16 | IM32 */
|
OPT_IMW, /* IM16 | IM32 */
|
||||||
OPT_MMXSSE, /* MMX | SSE */
|
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 */
|
/* can be ored with any OPT_xxx */
|
||||||
OPT_EA = 0x80
|
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))
|
if (!(opcode >= pa->sym && opcode < pa->sym + 7*NBWLX))
|
||||||
continue;
|
continue;
|
||||||
s = (opcode - pa->sym) % NBWLX;
|
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))
|
if (!(opcode >= pa->sym && opcode < pa->sym + NB_TEST_OPCODES))
|
||||||
continue;
|
continue;
|
||||||
/* cmovxx is a test opcode but accepts multiple sizes.
|
/* 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:
|
case OPT_MMXSSE:
|
||||||
v = OP_MMX | OP_SSE;
|
v = OP_MMX | OP_SSE;
|
||||||
break;
|
break;
|
||||||
|
case OPT_DISP:
|
||||||
|
case OPT_DISP8:
|
||||||
|
v = OP_ADDR;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
v = 1 << op2;
|
v = 1 << op2;
|
||||||
break;
|
break;
|
||||||
|
|
@ -833,7 +835,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
||||||
}
|
}
|
||||||
if (pa->instr_type & OPC_B)
|
if (pa->instr_type & OPC_B)
|
||||||
v += s >= 1;
|
v += s >= 1;
|
||||||
if (pa->instr_type & OPC_SHORTJMP) {
|
if (nb_ops == 1 && pa->op_type[0] == OPT_DISP8) {
|
||||||
Sym *sym;
|
Sym *sym;
|
||||||
int jmp_disp;
|
int jmp_disp;
|
||||||
|
|
||||||
|
|
@ -861,8 +863,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
||||||
tcc_error("invalid displacement");
|
tcc_error("invalid displacement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (OPCT_IS(pa->instr_type, OPC_TEST)
|
if (OPCT_IS(pa->instr_type, OPC_TEST))
|
||||||
|| OPCT_IS(pa->instr_type, OPC_JMP_TEST))
|
|
||||||
v += test_bits[opcode - pa->sym];
|
v += test_bits[opcode - pa->sym];
|
||||||
op1 = v >> 16;
|
op1 = v >> 16;
|
||||||
if (op1)
|
if (op1)
|
||||||
|
|
@ -955,8 +956,7 @@ ST_FUNC void asm_opcode(TCCState *s1, int opcode)
|
||||||
} else if (v & OP_IM64) {
|
} else if (v & OP_IM64) {
|
||||||
gen_expr64(&ops[i].e);
|
gen_expr64(&ops[i].e);
|
||||||
#endif
|
#endif
|
||||||
} else if (OPCT_IS (pa->instr_type, OPC_JMP)
|
} else if (pa->op_type[i] == OPT_DISP || pa->op_type[i] == OPT_DISP8) {
|
||||||
|| OPCT_IS (pa->instr_type, OPC_JMP_TEST)) {
|
|
||||||
gen_disp32(&ops[i].e);
|
gen_disp32(&ops[i].e);
|
||||||
} else {
|
} else {
|
||||||
gen_expr32(&ops[i].e);
|
gen_expr32(&ops[i].e);
|
||||||
|
|
|
||||||
18
i386-asm.h
18
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_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, 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, 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_OP2(lcall, 0x9a, 0, 0, OPT_IM16, OPT_IM32))
|
||||||
ALT(DEF_ASM_OP1(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
|
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)
|
DEF_ASM_OP0(lret, 0xcb)
|
||||||
ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
|
ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
|
||||||
|
|
||||||
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP_TEST, OPT_ADDR))
|
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
|
||||||
DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(jecxz, 0xe3, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(jecxz, 0xe3, 0, 0, OPT_DISP8)
|
||||||
|
|
||||||
/* float */
|
/* float */
|
||||||
/* specific fcomp handling */
|
/* specific fcomp handling */
|
||||||
|
|
|
||||||
18
x86_64-asm.h
18
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_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, 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, 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(lcall, 0xff, 3, OPC_MODRM, OPT_EA))
|
||||||
ALT(DEF_ASM_OP1(ljmp, 0xff, 5, 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)
|
DEF_ASM_OP0(lret, 0xcb)
|
||||||
ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
|
ALT(DEF_ASM_OP1(lret, 0xca, 0, 0, OPT_IM16))
|
||||||
|
|
||||||
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_SHORTJMP | OPC_JMP_TEST, OPT_ADDR))
|
ALT(DEF_ASM_OP1(jo, 0x70, 0, OPC_TEST, OPT_DISP8))
|
||||||
DEF_ASM_OP1(loopne, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopne, 0xe0, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loopnz, 0xe0, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopnz, 0xe0, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loope, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loope, 0xe1, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loopz, 0xe1, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loopz, 0xe1, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(loop, 0xe2, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(loop, 0xe2, 0, 0, OPT_DISP8)
|
||||||
DEF_ASM_OP1(jecxz, 0x67e3, 0, OPC_SHORTJMP, OPT_ADDR)
|
DEF_ASM_OP1(jecxz, 0x67e3, 0, 0, OPT_DISP8)
|
||||||
|
|
||||||
/* float */
|
/* float */
|
||||||
/* specific fcomp handling */
|
/* specific fcomp handling */
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue