From cb712a9ecdc5784b3790aef71852e3bd329a976a Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 6 Dec 2005 12:40:57 +0000 Subject: [PATCH] gas/ 2005-12-06 H.J. Lu PR gas/1874 * config/tc-i386.c (match_template): Handle monitor. (process_suffix): Likewise. gas/testsuite/ 2005-12-06 H.J. Lu PR gas/1874 * gas/i386/i386.exp: Add x86-64-prescott for 64bit. * gas/i386/prescott.s: Test address size override for monitor. * gas/i386/prescott.d: Updated. * gas/i386/x86-64-prescott.d: New file. * gas/i386/x86-64-prescott.s: Likewise. include/opcode/ 2005-12-06 H.J. Lu PR gas/1874 * i386.h (i386_optab): Add 64bit support for monitor and mwait. opcodes/ 2005-12-06 H.J. Lu PR gas/1874 * i386-dis.c (address_mode): New enum type. (address_mode): New variable. (mode_64bit): Removed. (ckprefix): Updated to check address_mode instead of mode_64bit. (prefix_name): Likewise. (print_insn): Likewise. (putop): Likewise. (print_operand_value): Likewise. (intel_operand_size): Likewise. (OP_E): Likewise. (OP_G): Likewise. (set_op): Likewise. (OP_REG): Likewise. (OP_I): Likewise. (OP_I64): Likewise. (OP_OFF): Likewise. (OP_OFF64): Likewise. (ptr_reg): Likewise. (OP_C): Likewise. (SVME_Fixup): Likewise. (print_insn): Set address_mode. (PNI_Fixup): Add 64bit and address size override support for monitor and mwait. --- gas/ChangeLog | 6 ++ gas/config/tc-i386.c | 35 ++++++--- gas/testsuite/ChangeLog | 11 +++ gas/testsuite/gas/i386/i386.exp | 1 + gas/testsuite/gas/i386/prescott.d | 3 +- gas/testsuite/gas/i386/prescott.s | 3 + gas/testsuite/gas/i386/x86-64-prescott.d | 37 ++++++++++ gas/testsuite/gas/i386/x86-64-prescott.s | 35 +++++++++ include/opcode/ChangeLog | 5 ++ include/opcode/i386.h | 16 ++++- opcodes/ChangeLog | 27 +++++++ opcodes/i386-dis.c | 119 +++++++++++++++++++------------ 12 files changed, 237 insertions(+), 61 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-prescott.d create mode 100644 gas/testsuite/gas/i386/x86-64-prescott.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 4bd00a3..90b1f99 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2005-12-06 H.J. Lu + + PR gas/1874 + * config/tc-i386.c (match_template): Handle monitor. + (process_suffix): Likewise. + 2005-12-05 John David Anglin Bug gas/1948 diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index 1828c48..b95a664 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -2275,10 +2275,15 @@ match_template () overlap1 = i.types[1] & t->operand_types[1]; if (!MATCH (overlap0, i.types[0], t->operand_types[0]) || !MATCH (overlap1, i.types[1], t->operand_types[1]) - || !CONSISTENT_REGISTER_MATCH (overlap0, i.types[0], - t->operand_types[0], - overlap1, i.types[1], - t->operand_types[1])) + /* monitor in SSE3 is a very special case. The first + register and the second register may have differnet + sizes. */ + || !((t->base_opcode == 0x0f01 + && t->extension_opcode == 0xc8) + || CONSISTENT_REGISTER_MATCH (overlap0, i.types[0], + t->operand_types[0], + overlap1, i.types[1], + t->operand_types[1]))) { /* Check if other direction is valid ... */ if ((t->opcode_modifier & (D | FloatD)) == 0) @@ -2546,12 +2551,22 @@ process_suffix (void) /* Now select between word & dword operations via the operand size prefix, except for instructions that will ignore this prefix anyway. */ - if (i.suffix != QWORD_MNEM_SUFFIX - && i.suffix != LONG_DOUBLE_MNEM_SUFFIX - && !(i.tm.opcode_modifier & (IgnoreSize | FloatMF)) - && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) - || (flag_code == CODE_64BIT - && (i.tm.opcode_modifier & JumpByte)))) + if (i.tm.base_opcode == 0x0f01 && i.tm.extension_opcode == 0xc8) + { + /* monitor in SSE3 is a very special case. The default size + of AX is the size of mode. The address size override + prefix will change the size of AX. */ + if (i.op->regs[0].reg_type & + (flag_code == CODE_32BIT ? Reg16 : Reg32)) + if (!add_prefix (ADDR_PREFIX_OPCODE)) + return 0; + } + else if (i.suffix != QWORD_MNEM_SUFFIX + && i.suffix != LONG_DOUBLE_MNEM_SUFFIX + && !(i.tm.opcode_modifier & (IgnoreSize | FloatMF)) + && ((i.suffix == LONG_MNEM_SUFFIX) == (flag_code == CODE_16BIT) + || (flag_code == CODE_64BIT + && (i.tm.opcode_modifier & JumpByte)))) { unsigned int prefix = DATA_PREFIX_OPCODE; diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 849c885..43f0588 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2005-12-06 H.J. Lu + + PR gas/1874 + * gas/i386/i386.exp: Add x86-64-prescott for 64bit. + + * gas/i386/prescott.s: Test address size override for monitor. + * gas/i386/prescott.d: Updated. + + * gas/i386/x86-64-prescott.d: New file. + * gas/i386/x86-64-prescott.s: Likewise. + 2005-12-06 Hans-Peter Nilsson * gas/cris/rd-pcplus.s, gas/cris/rd-pcplus.d: New test. diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp index d536da3..718514f 100644 --- a/gas/testsuite/gas/i386/i386.exp +++ b/gas/testsuite/gas/i386/i386.exp @@ -131,6 +131,7 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t run_dump_test "svme64" run_dump_test "x86-64-vmx" run_dump_test "immed64" + run_dump_test "x86-64-prescott" # For ELF targets verify that @unwind works. if { ([istarget "*-*-elf*"] || [istarget "*-*-linux*"] diff --git a/gas/testsuite/gas/i386/prescott.d b/gas/testsuite/gas/i386/prescott.d index 496bb49..1e66065 100644 --- a/gas/testsuite/gas/i386/prescott.d +++ b/gas/testsuite/gas/i386/prescott.d @@ -32,5 +32,6 @@ Disassembly of section .text: 62: f3 0f 12 dc [ ]*movsldup %xmm4,%xmm3 66: 0f 01 c9 [ ]*mwait %eax,%ecx 69: 0f 01 c9 [ ]*mwait %eax,%ecx - 6c: 00 00 [ ]*add %al,\(%eax\) + 6c: 67 0f 01 c8 [ ]*monitor %ax,%ecx,%edx + 70: 67 0f 01 c8 [ ]*monitor %ax,%ecx,%edx ... diff --git a/gas/testsuite/gas/i386/prescott.s b/gas/testsuite/gas/i386/prescott.s index a70c835..95dacf7 100644 --- a/gas/testsuite/gas/i386/prescott.s +++ b/gas/testsuite/gas/i386/prescott.s @@ -29,4 +29,7 @@ foo: mwait mwait %eax,%ecx + monitor %ax,%ecx,%edx + addr16 monitor + .p2align 4,0 diff --git a/gas/testsuite/gas/i386/x86-64-prescott.d b/gas/testsuite/gas/i386/x86-64-prescott.d new file mode 100644 index 0000000..43a2d28 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-prescott.d @@ -0,0 +1,37 @@ +#objdump: -dw +#name: x86-64 prescott + +.*: +file format .* + +Disassembly of section .text: + +0+000 : + 0: 66 0f d0 01 [ ]*addsubpd \(%rcx\),%xmm0 + 4: 66 0f d0 ca [ ]*addsubpd %xmm2,%xmm1 + 8: f2 0f d0 13 [ ]*addsubps \(%rbx\),%xmm2 + c: f2 0f d0 dc [ ]*addsubps %xmm4,%xmm3 + 10: df 88 90 90 90 90 [ ]*fisttp 0xffffffff90909090\(%rax\) + 16: db 88 90 90 90 90 [ ]*fisttpl 0xffffffff90909090\(%rax\) + 1c: dd 88 90 90 90 90 [ ]*fisttpll 0xffffffff90909090\(%rax\) + 22: 66 0f 7c 65 00 [ ]*haddpd 0x0\(%rbp\),%xmm4 + 27: 66 0f 7c ee [ ]*haddpd %xmm6,%xmm5 + 2b: f2 0f 7c 37 [ ]*haddps \(%rdi\),%xmm6 + 2f: f2 0f 7c f8 [ ]*haddps %xmm0,%xmm7 + 33: 66 0f 7d c1 [ ]*hsubpd %xmm1,%xmm0 + 37: 66 0f 7d 0a [ ]*hsubpd \(%rdx\),%xmm1 + 3b: f2 0f 7d d2 [ ]*hsubps %xmm2,%xmm2 + 3f: f2 0f 7d 1c 24 [ ]*hsubps \(%rsp\),%xmm3 + 44: f2 0f f0 2e [ ]*lddqu \(%rsi\),%xmm5 + 48: 0f 01 c8 [ ]*monitor %rax,%rcx,%rdx + 4b: 0f 01 c8 [ ]*monitor %rax,%rcx,%rdx + 4e: f2 0f 12 f7 [ ]*movddup %xmm7,%xmm6 + 52: f2 0f 12 38 [ ]*movddup \(%rax\),%xmm7 + 56: f3 0f 16 01 [ ]*movshdup \(%rcx\),%xmm0 + 5a: f3 0f 16 ca [ ]*movshdup %xmm2,%xmm1 + 5e: f3 0f 12 13 [ ]*movsldup \(%rbx\),%xmm2 + 62: f3 0f 12 dc [ ]*movsldup %xmm4,%xmm3 + 66: 0f 01 c9 [ ]*mwait %rax,%rcx + 69: 0f 01 c9 [ ]*mwait %rax,%rcx + 6c: 67 0f 01 c8 [ ]*monitor %eax,%rcx,%rdx + 70: 67 0f 01 c8 [ ]*monitor %eax,%rcx,%rdx + ... diff --git a/gas/testsuite/gas/i386/x86-64-prescott.s b/gas/testsuite/gas/i386/x86-64-prescott.s new file mode 100644 index 0000000..0f03683 --- /dev/null +++ b/gas/testsuite/gas/i386/x86-64-prescott.s @@ -0,0 +1,35 @@ +#Prescott New Instructions + + .text +foo: + addsubpd (%rcx),%xmm0 + addsubpd %xmm2,%xmm1 + addsubps (%rbx),%xmm2 + addsubps %xmm4,%xmm3 + fisttp 0x90909090(%rax) + fisttpl 0x90909090(%rax) + fisttpll 0x90909090(%rax) + haddpd 0x0(%rbp),%xmm4 + haddpd %xmm6,%xmm5 + haddps (%rdi),%xmm6 + haddps %xmm0,%xmm7 + hsubpd %xmm1,%xmm0 + hsubpd (%rdx),%xmm1 + hsubps %xmm2,%xmm2 + hsubps (%rsp,1),%xmm3 + lddqu (%rsi),%xmm5 + monitor + monitor %rax,%rcx,%rdx + movddup %xmm7,%xmm6 + movddup (%rax),%xmm7 + movshdup (%rcx),%xmm0 + movshdup %xmm2,%xmm1 + movsldup (%rbx),%xmm2 + movsldup %xmm4,%xmm3 + mwait + mwait %rax,%rcx + + monitor %eax,%rcx,%rdx + addr32 monitor + + .p2align 4,0 diff --git a/include/opcode/ChangeLog b/include/opcode/ChangeLog index c9a4a12..b257be4 100644 --- a/include/opcode/ChangeLog +++ b/include/opcode/ChangeLog @@ -1,3 +1,8 @@ +2005-12-06 H.J. Lu + + PR gas/1874 + * i386.h (i386_optab): Add 64bit support for monitor and mwait. + 2005-11-14 David Ung * mips.h: Assign 'm'/'M' codes to MIPS16e save/restore diff --git a/include/opcode/i386.h b/include/opcode/i386.h index 59b5e3c..33f94cc 100644 --- a/include/opcode/i386.h +++ b/include/opcode/i386.h @@ -1346,14 +1346,24 @@ static const template i386_optab[] = {"hsubps", 2, 0xf20f7d, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"lddqu", 2, 0xf20ff0, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { LLongMem, RegXMM, 0 } }, {"monitor", 0, 0x0f01, 0xc8, CpuPNI, NoSuf|ImmExt, { 0, 0, 0} }, -/* Need to ensure only "monitor %eax,%ecx,%edx" is accepted. */ -{"monitor", 3, 0x0f01, 0xc8, CpuPNI, NoSuf|ImmExt, { Reg32, Reg32, Reg32} }, +/* monitor is very special. CX and DX are always 64bits with zero upper + 32bits in 64bit mode, and 32bits in 16bit and 32bit modes. The + address size override prefix can be used to overrride the AX size in + all modes. */ +/* Need to ensure only "monitor %eax/%ax,%ecx,%edx" is accepted. */ +{"monitor", 3, 0x0f01, 0xc8, CpuPNI|CpuNo64, NoSuf|ImmExt, { Reg16|Reg32, Reg32, Reg32 } }, +/* Need to ensure only "monitor %rax/%eax,%rcx,%rdx" is accepted. */ +{"monitor", 3, 0x0f01, 0xc8, CpuPNI|Cpu64, NoSuf|ImmExt|NoRex64, { Reg32|Reg64, Reg64, Reg64 } }, {"movddup", 2, 0xf20f12, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"movshdup", 2, 0xf30f16, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"movsldup", 2, 0xf30f12, X, CpuPNI, NoSuf|IgnoreSize|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, {"mwait", 0, 0x0f01, 0xc9, CpuPNI, NoSuf|ImmExt, { 0, 0, 0} }, +/* mwait is very special. AX and CX are always 64bits with zero upper + 32bits in 64bit mode, and 32bits in 16bit and 32bit modes. */ /* Need to ensure only "mwait %eax,%ecx" is accepted. */ -{"mwait", 2, 0x0f01, 0xc9, CpuPNI, NoSuf|ImmExt, { Reg32, Reg32, 0} }, +{"mwait", 2, 0x0f01, 0xc9, CpuPNI|CpuNo64, NoSuf|ImmExt, { Reg32, Reg32, 0} }, +/* Need to ensure only "mwait %rax,%rcx" is accepted. */ +{"mwait", 2, 0x0f01, 0xc9, CpuPNI|Cpu64, NoSuf|ImmExt|NoRex64, { Reg64, Reg64, 0} }, /* VMX instructions. */ {"vmcall", 0, 0x0f01, 0xc1, CpuVMX, NoSuf|ImmExt, { 0, 0, 0} }, diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index c5b400f..61e6e5d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,30 @@ +2005-12-06 H.J. Lu + + PR gas/1874 + * i386-dis.c (address_mode): New enum type. + (address_mode): New variable. + (mode_64bit): Removed. + (ckprefix): Updated to check address_mode instead of mode_64bit. + (prefix_name): Likewise. + (print_insn): Likewise. + (putop): Likewise. + (print_operand_value): Likewise. + (intel_operand_size): Likewise. + (OP_E): Likewise. + (OP_G): Likewise. + (set_op): Likewise. + (OP_REG): Likewise. + (OP_I): Likewise. + (OP_I64): Likewise. + (OP_OFF): Likewise. + (OP_OFF64): Likewise. + (ptr_reg): Likewise. + (OP_C): Likewise. + (SVME_Fixup): Likewise. + (print_insn): Set address_mode. + (PNI_Fixup): Add 64bit and address size override support for + monitor and mwait. + 2005-12-06 Hans-Peter Nilsson * cris-dis.c (bytes_to_skip): Handle new parameter prefix_matchedp. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 47455e3..5adf4af 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -115,8 +115,14 @@ struct dis_private { when we can. */ #define FWAIT_OPCODE (0x9b) -/* Set to 1 for 64bit mode disassembly. */ -static int mode_64bit; +enum address_mode +{ + mode_16bit, + mode_32bit, + mode_64bit +}; + +enum address_mode address_mode; /* Flags for the prefixes for the current instruction. See below. */ static int prefixes; @@ -1772,7 +1778,7 @@ ckprefix (void) case 0x4d: case 0x4e: case 0x4f: - if (mode_64bit) + if (address_mode == mode_64bit) newrex = *codep; else return; @@ -1898,7 +1904,7 @@ prefix_name (int pref, int sizeflag) case 0x66: return (sizeflag & DFLAG) ? "data16" : "data32"; case 0x67: - if (mode_64bit) + if (address_mode == mode_64bit) return (sizeflag & AFLAG) ? "addr32" : "addr64"; else return (sizeflag & AFLAG) ? "addr16" : "addr32"; @@ -1970,8 +1976,11 @@ print_insn (bfd_vma pc, disassemble_info *info) const char *p; struct dis_private priv; - mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax - || info->mach == bfd_mach_x86_64); + if (info->mach == bfd_mach_x86_64_intel_syntax + || info->mach == bfd_mach_x86_64) + address_mode = mode_64bit; + else + address_mode = mode_32bit; if (intel_syntax == (char) -1) intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax @@ -1991,17 +2000,17 @@ print_insn (bfd_vma pc, disassemble_info *info) { if (strncmp (p, "x86-64", 6) == 0) { - mode_64bit = 1; + address_mode = mode_64bit; priv.orig_sizeflag = AFLAG | DFLAG; } else if (strncmp (p, "i386", 4) == 0) { - mode_64bit = 0; + address_mode = mode_32bit; priv.orig_sizeflag = AFLAG | DFLAG; } else if (strncmp (p, "i8086", 5) == 0) { - mode_64bit = 0; + address_mode = mode_16bit; priv.orig_sizeflag = 0; } else if (strncmp (p, "intel", 5) == 0) @@ -2170,7 +2179,7 @@ print_insn (bfd_vma pc, disassemble_info *info) sizeflag ^= AFLAG; if (dp->bytemode3 != loop_jcxz_mode || intel_syntax) { - if ((sizeflag & AFLAG) || mode_64bit) + if ((sizeflag & AFLAG) || address_mode == mode_64bit) oappend ("addr32 "); else oappend ("addr16 "); @@ -2237,7 +2246,8 @@ print_insn (bfd_vma pc, disassemble_info *info) break; case X86_64_SPECIAL: - dp = &x86_64_table[dp->bytemode2][mode_64bit]; + index = address_mode == mode_64bit ? 1 : 0; + dp = &x86_64_table[dp->bytemode2][index]; break; default: @@ -2739,7 +2749,7 @@ putop (const char *template, int sizeflag) alt = 0; if (intel_syntax) alt += 1; - if (mode_64bit) + if (address_mode == mode_64bit) alt += 2; while (alt != 0) { @@ -2795,7 +2805,7 @@ putop (const char *template, int sizeflag) } break; case 'E': /* For jcxz/jecxz */ - if (mode_64bit) + if (address_mode == mode_64bit) { if (sizeflag & AFLAG) *obufp++ = 'r'; @@ -2813,9 +2823,9 @@ putop (const char *template, int sizeflag) if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS)) { if (sizeflag & AFLAG) - *obufp++ = mode_64bit ? 'q' : 'l'; + *obufp++ = address_mode == mode_64bit ? 'q' : 'l'; else - *obufp++ = mode_64bit ? 'l' : 'w'; + *obufp++ = address_mode == mode_64bit ? 'l' : 'w'; used_prefixes |= (prefixes & PREFIX_ADDR); } break; @@ -2861,7 +2871,7 @@ putop (const char *template, int sizeflag) case 'T': if (intel_syntax) break; - if (mode_64bit && (sizeflag & DFLAG)) + if (address_mode == mode_64bit && (sizeflag & DFLAG)) { *obufp++ = 'q'; break; @@ -2890,7 +2900,7 @@ putop (const char *template, int sizeflag) case 'U': if (intel_syntax) break; - if (mode_64bit && (sizeflag & DFLAG)) + if (address_mode == mode_64bit && (sizeflag & DFLAG)) { if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) *obufp++ = 'q'; @@ -2950,7 +2960,7 @@ putop (const char *template, int sizeflag) case 'V': if (intel_syntax) break; - if (mode_64bit && (sizeflag & DFLAG)) + if (address_mode == mode_64bit && (sizeflag & DFLAG)) { if (sizeflag & SUFFIX_ALWAYS) *obufp++ = 'q'; @@ -3080,7 +3090,7 @@ OP_indirE (int bytemode, int sizeflag) static void print_operand_value (char *buf, int hex, bfd_vma disp) { - if (mode_64bit) + if (address_mode == mode_64bit) { if (hex) { @@ -3147,7 +3157,7 @@ intel_operand_size (int bytemode, int sizeflag) oappend ("WORD PTR "); break; case stack_v_mode: - if (mode_64bit && (sizeflag & DFLAG)) + if (address_mode == mode_64bit && (sizeflag & DFLAG)) { oappend ("QWORD PTR "); used_prefixes |= (prefixes & PREFIX_DATA); @@ -3172,7 +3182,7 @@ intel_operand_size (int bytemode, int sizeflag) oappend ("QWORD PTR "); break; case m_mode: - if (mode_64bit) + if (address_mode == mode_64bit) oappend ("QWORD PTR "); else oappend ("DWORD PTR "); @@ -3230,13 +3240,13 @@ OP_E (int bytemode, int sizeflag) oappend (names64[rm + add]); break; case m_mode: - if (mode_64bit) + if (address_mode == mode_64bit) oappend (names64[rm + add]); else oappend (names32[rm + add]); break; case stack_v_mode: - if (mode_64bit && (sizeflag & DFLAG)) + if (address_mode == mode_64bit && (sizeflag & DFLAG)) { oappend (names64[rm + add]); used_prefixes |= (prefixes & PREFIX_DATA); @@ -3270,7 +3280,7 @@ OP_E (int bytemode, int sizeflag) intel_operand_size (bytemode, sizeflag); append_seg (); - if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */ + if ((sizeflag & AFLAG) || address_mode == mode_64bit) /* 32 bit address mode */ { int havesib; int havebase; @@ -3287,7 +3297,7 @@ OP_E (int bytemode, int sizeflag) havesib = 1; FETCH_DATA (the_info, codep + 1); index = (*codep >> 3) & 7; - if (mode_64bit || index != 0x4) + if (address_mode == mode_64bit || index != 0x4) /* When INDEX == 0x4 in 32 bit mode, SCALE is ignored. */ scale = (*codep >> 6) & 3; base = *codep & 7; @@ -3304,7 +3314,7 @@ OP_E (int bytemode, int sizeflag) if ((base & 7) == 5) { havebase = 0; - if (mode_64bit && !havesib) + if (address_mode == mode_64bit && !havesib) riprel = 1; disp = get32s (); } @@ -3339,7 +3349,7 @@ OP_E (int bytemode, int sizeflag) oappend ("rip + "); *obufp = '\0'; if (havebase) - oappend (mode_64bit && (sizeflag & AFLAG) + oappend (address_mode == mode_64bit && (sizeflag & AFLAG) ? names64[base] : names32[base]); if (havesib) { @@ -3350,7 +3360,7 @@ OP_E (int bytemode, int sizeflag) *obufp++ = separator_char; *obufp = '\0'; } - oappend (mode_64bit && (sizeflag & AFLAG) + oappend (address_mode == mode_64bit && (sizeflag & AFLAG) ? names64[index] : names32[index]); } if (scale != 0 || (!intel_syntax && index != 4)) @@ -3511,7 +3521,7 @@ OP_G (int bytemode, int sizeflag) used_prefixes |= (prefixes & PREFIX_DATA); break; case m_mode: - if (mode_64bit) + if (address_mode == mode_64bit) oappend (names64[reg + add]); else oappend (names32[reg + add]); @@ -3591,7 +3601,7 @@ static void set_op (bfd_vma op, int riprel) { op_index[op_ad] = op_ad; - if (mode_64bit) + if (address_mode == mode_64bit) { op_address[op_ad] = op; op_riprel[op_ad] = riprel; @@ -3639,7 +3649,7 @@ OP_REG (int code, int sizeflag) break; case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg: case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg: - if (mode_64bit && (sizeflag & DFLAG)) + if (address_mode == mode_64bit && (sizeflag & DFLAG)) { s = names64[code - rAX_reg + add]; break; @@ -3725,7 +3735,7 @@ OP_I (int bytemode, int sizeflag) mask = 0xff; break; case q_mode: - if (mode_64bit) + if (address_mode == mode_64bit) { op = get32s (); break; @@ -3773,7 +3783,7 @@ OP_I64 (int bytemode, int sizeflag) bfd_signed_vma op; bfd_signed_vma mask = -1; - if (!mode_64bit) + if (address_mode != mode_64bit) { OP_I (bytemode, sizeflag); return; @@ -3941,7 +3951,7 @@ OP_OFF (int bytemode, int sizeflag) intel_operand_size (bytemode, sizeflag); append_seg (); - if ((sizeflag & AFLAG) || mode_64bit) + if ((sizeflag & AFLAG) || address_mode == mode_64bit) off = get32 (); else off = get16 (); @@ -3964,7 +3974,7 @@ OP_OFF64 (int bytemode, int sizeflag) { bfd_vma off; - if (!mode_64bit) + if (address_mode != mode_64bit) { OP_OFF (bytemode, sizeflag); return; @@ -3996,7 +4006,7 @@ ptr_reg (int code, int sizeflag) *obufp++ = open_char; used_prefixes |= (prefixes & PREFIX_ADDR); - if (mode_64bit) + if (address_mode == mode_64bit) { if (!(sizeflag & AFLAG)) s = names32[code - eAX_reg]; @@ -4050,7 +4060,7 @@ OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) USED_REX (REX_EXTX); add = 8; } - else if (!mode_64bit && (prefixes & PREFIX_LOCK)) + else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK)) { used_prefixes |= PREFIX_LOCK; add = 8; @@ -4412,18 +4422,31 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) if (mod == 3 && reg == 1 && rm <= 1) { /* Override "sidt". */ - char *p = obuf + strlen (obuf) - 4; + size_t olen = strlen (obuf); + char *p = obuf + olen - 4; + const char **names = (address_mode == mode_64bit + ? names64 : names32); /* We might have a suffix when disassembling with -Msuffix. */ if (*p == 'i') --p; + /* Remove "addr16/addr32" if we aren't in Intel mode. */ + if (!intel_syntax + && (prefixes & PREFIX_ADDR) + && olen >= (4 + 7) + && *(p - 1) == ' ' + && strncmp (p - 7, "addr", 4) == 0 + && (strncmp (p - 3, "16", 2) == 0 + || strncmp (p - 3, "32", 2) == 0)) + p -= 7; + if (rm) { /* mwait %eax,%ecx */ strcpy (p, "mwait"); if (!intel_syntax) - strcpy (op1out, names32[0]); + strcpy (op1out, names[0]); } else { @@ -4431,21 +4454,23 @@ PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag) strcpy (p, "monitor"); if (!intel_syntax) { - if (!mode_64bit) - strcpy (op1out, names32[0]); - else if (!(prefixes & PREFIX_ADDR)) - strcpy (op1out, names64[0]); + const char **op1_names; + if (!(prefixes & PREFIX_ADDR)) + op1_names = (address_mode == mode_16bit + ? names16 : names); else { - strcpy (op1out, names32[0]); + op1_names = (address_mode != mode_32bit + ? names32 : names16); used_prefixes |= PREFIX_ADDR; } - strcpy (op3out, names32[2]); + strcpy (op1out, op1_names[0]); + strcpy (op3out, names[2]); } } if (!intel_syntax) { - strcpy (op2out, names32[1]); + strcpy (op2out, names[1]); two_source_ops = 1; } @@ -4513,7 +4538,7 @@ SVME_Fixup (int bytemode, int sizeflag) case 0xda: case 0xdb: *obufp++ = open_char; - if (mode_64bit || (sizeflag & AFLAG)) + if (address_mode == mode_64bit || (sizeflag & AFLAG)) alt = names32[0]; else alt = names16[0]; -- 2.7.4