From 0a3bcb57f6260124656d88899dcca520f2023c09 Mon Sep 17 00:00:00 2001 From: grischka Date: Sat, 14 Nov 2009 20:05:22 +0100 Subject: [PATCH] fix 32bit asm The new 16bit code was causing wrong 0x66 prefixes in 32bit code. The fix possibly breaks the feature on 16bit asm. --- i386-asm.c | 38 +++++++++++++------------------------- i386-asm.h | 4 ++++ 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/i386-asm.c b/i386-asm.c index 891943ed..d360287b 100644 --- a/i386-asm.c +++ b/i386-asm.c @@ -504,10 +504,12 @@ static void asm_opcode(TCCState *s1, int opcode) { const ASMInstr *pa; int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix; - int nb_ops, s, ss; + int nb_ops, s; Operand ops[MAX_OPERANDS], *pop; int op_type[3]; /* decoded op type */ - static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0; + + int a32, o32; + static int addr32 = 0, data32 = 0; /* get operands */ pop = ops; @@ -618,12 +620,12 @@ static void asm_opcode(TCCState *s1, int opcode) if (s1->seg_size == 32) goto bad_prefix; else - o32 = data32 = 1; + data32 = 1; } else if (opcode == TOK_ASM_a32) { if (s1->seg_size == 32) goto bad_prefix; else - a32 = addr32 = 1; + addr32 = 1; } if (b & 0xff00) g(b >> 8); @@ -649,26 +651,13 @@ static void asm_opcode(TCCState *s1, int opcode) } } - for(i = 0; i < nb_ops; i++) { - if (ops[i].type & OP_REG32) { - if (s1->seg_size == 16) - o32 = 1; - } else if (!(ops[i].type & OP_REG32)) { - if (s1->seg_size == 32) - o32 = 1; - } - } - - ss = s; + a32 = o32 = 0; if (s == 1 || (pa->instr_type & OPC_D16)) { if (s1->seg_size == 32) o32 = 1; - } else if (s == 2) { - if (s1->seg_size == 16) { - if (!(pa->instr_type & OPC_D16)) - o32 = 1; - } - s = 1; + } else if (s == 2 && !(pa->instr_type & OPC_D16)) { + if (s1->seg_size == 16) + o32 = 1; } /* generate a16/a32 prefix if needed */ @@ -721,7 +710,7 @@ static void asm_opcode(TCCState *s1, int opcode) v += 7; } if (pa->instr_type & OPC_B) - v += s; + v += s >= 1; if (pa->instr_type & OPC_TEST) v += test_bits[opcode - pa->sym]; if (pa->instr_type & OPC_SHORTJMP) { @@ -824,9 +813,9 @@ static void asm_opcode(TCCState *s1, int opcode) at the op size */ if (v == (OP_IM8 | OP_IM16 | OP_IM32) || v == (OP_IM16 | OP_IM32)) { - if (ss == 0) + if (s == 0) v = OP_IM8; - else if (ss == 1) + else if (s == 1) v = OP_IM16; else v = OP_IM32; @@ -875,7 +864,6 @@ static void asm_opcode(TCCState *s1, int opcode) } } } - a32 = o32 = 0; } #define NB_SAVED_REGS 3 diff --git a/i386-asm.h b/i386-asm.h index 034cfad6..dfcaac86 100644 --- a/i386-asm.h +++ b/i386-asm.h @@ -74,8 +74,12 @@ ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) /* prefixes */ + DEF_ASM_OP0(addr16, 0x67) DEF_ASM_OP0(a32, 0x67) + + DEF_ASM_OP0(data16, 0x66) DEF_ASM_OP0(o32, 0x66) + DEF_ASM_OP0(lock, 0xf0) DEF_ASM_OP0(rep, 0xf3) DEF_ASM_OP0(repe, 0xf3)