The new 16bit code was causing wrong 0x66 prefixes in 32bit code. The fix possibly breaks the feature on 16bit asm.
Unified · Split
| @@ -504,10 +504,12 @@ static void asm_opcode(TCCState *s1, int opcode) · 503 unmodified lines | ||
| 504 | 504 | { |
| 505 | 505 | const ASMInstr *pa; |
| 506 | 506 | int i, modrm_index, reg, v, op1, is_short_jmp, seg_prefix; |
| 507 | − int nb_ops, s, ss; | |
| 507 | + int nb_ops, s; | |
| 508 | 508 | Operand ops[MAX_OPERANDS], *pop; |
| 509 | 509 | int op_type[3]; /* decoded op type */ |
| 510 | − static int a32 = 0, o32 = 0, addr32 = 0, data32 = 0; | |
| 510 | + | |
| 511 | + int a32, o32; | |
| 512 | + static int addr32 = 0, data32 = 0; | |
| 511 | 513 | |
| 512 | 514 | /* get operands */ |
| 513 | 515 | pop = ops; |
| @@ -618,12 +620,12 @@ static void asm_opcode(TCCState *s1, int opcode) · 104 unmodified lines | ||
| 618 | 620 | if (s1->seg_size == 32) |
| 619 | 621 | goto bad_prefix; |
| 620 | 622 | else |
| 621 | − o32 = data32 = 1; | |
| 623 | + data32 = 1; | |
| 622 | 624 | } else if (opcode == TOK_ASM_a32) { |
| 623 | 625 | if (s1->seg_size == 32) |
| 624 | 626 | goto bad_prefix; |
| 625 | 627 | else |
| 626 | − a32 = addr32 = 1; | |
| 628 | + addr32 = 1; | |
| 627 | 629 | } |
| 628 | 630 | if (b & 0xff00) |
| 629 | 631 | g(b >> 8); |
| @@ -649,26 +651,13 @@ static void asm_opcode(TCCState *s1, int opcode) · 19 unmodified lines | ||
| 649 | 651 | } |
| 650 | 652 | } |
| 651 | 653 | |
| 652 | − for(i = 0; i < nb_ops; i++) { | |
| 653 | − if (ops[i].type & OP_REG32) { | |
| 654 | − if (s1->seg_size == 16) | |
| 655 | − o32 = 1; | |
| 656 | − } else if (!(ops[i].type & OP_REG32)) { | |
| 657 | − if (s1->seg_size == 32) | |
| 658 | − o32 = 1; | |
| 659 | − } | |
| 660 | − } | |
| 661 | − | |
| 662 | − ss = s; | |
| 654 | + a32 = o32 = 0; | |
| 663 | 655 | if (s == 1 || (pa->instr_type & OPC_D16)) { |
| 664 | 656 | if (s1->seg_size == 32) |
| 665 | 657 | o32 = 1; |
| 666 | − } else if (s == 2) { | |
| 667 | − if (s1->seg_size == 16) { | |
| 668 | − if (!(pa->instr_type & OPC_D16)) | |
| 669 | − o32 = 1; | |
| 670 | − } | |
| 671 | − s = 1; | |
| 658 | + } else if (s == 2 && !(pa->instr_type & OPC_D16)) { | |
| 659 | + if (s1->seg_size == 16) | |
| 660 | + o32 = 1; | |
| 672 | 661 | } |
| 673 | 662 | |
| 674 | 663 | /* generate a16/a32 prefix if needed */ |
| @@ -721,7 +710,7 @@ static void asm_opcode(TCCState *s1, int opcode) · 46 unmodified lines | ||
| 721 | 710 | v += 7; |
| 722 | 711 | } |
| 723 | 712 | if (pa->instr_type & OPC_B) |
| 724 | − v += s; | |
| 713 | + v += s >= 1; | |
| 725 | 714 | if (pa->instr_type & OPC_TEST) |
| 726 | 715 | v += test_bits[opcode - pa->sym]; |
| 727 | 716 | if (pa->instr_type & OPC_SHORTJMP) { |
| @@ -824,9 +813,9 @@ static void asm_opcode(TCCState *s1, int opcode) · 96 unmodified lines | ||
| 824 | 813 | at the op size */ |
| 825 | 814 | if (v == (OP_IM8 | OP_IM16 | OP_IM32) || |
| 826 | 815 | v == (OP_IM16 | OP_IM32)) { |
| 827 | − if (ss == 0) | |
| 816 | + if (s == 0) | |
| 828 | 817 | v = OP_IM8; |
| 829 | − else if (ss == 1) | |
| 818 | + else if (s == 1) | |
| 830 | 819 | v = OP_IM16; |
| 831 | 820 | else |
| 832 | 821 | v = OP_IM32; |
| @@ -875,7 +864,6 @@ static void asm_opcode(TCCState *s1, int opcode) · 42 unmodified lines | ||
| 875 | 864 | } |
| 876 | 865 | } |
| 877 | 866 | } |
| 878 | − a32 = o32 = 0; | |
| 879 | 867 | } |
| 880 | 868 | |
| 881 | 869 | #define NB_SAVED_REGS 3 |
| @@ -74,8 +74,12 @@ ALT(DEF_ASM_OP2(btcw, 0x0fbb, 0, OPC_MODRM | OPC_WL, OPT_REGW, OPT_REGW | OPT_EA · 73 unmodified lines | ||
| 74 | 74 | ALT(DEF_ASM_OP2(btcw, 0x0fba, 7, OPC_MODRM | OPC_WL, OPT_IM8, OPT_REGW | OPT_EA)) |
| 75 | 75 | |
| 76 | 76 | /* prefixes */ |
| 77 | + DEF_ASM_OP0(addr16, 0x67) | |
| 77 | 78 | DEF_ASM_OP0(a32, 0x67) |
| 79 | + | |
| 80 | + DEF_ASM_OP0(data16, 0x66) | |
| 78 | 81 | DEF_ASM_OP0(o32, 0x66) |
| 82 | + | |
| 79 | 83 | DEF_ASM_OP0(lock, 0xf0) |
| 80 | 84 | DEF_ASM_OP0(rep, 0xf3) |
| 81 | 85 | DEF_ASM_OP0(repe, 0xf3) |