gas/
authorH.J. Lu <hjl.tools@gmail.com>
Tue, 6 Dec 2005 12:40:57 +0000 (12:40 +0000)
committerH.J. Lu <hjl.tools@gmail.com>
Tue, 6 Dec 2005 12:40:57 +0000 (12:40 +0000)
2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>

PR gas/1874
* config/tc-i386.c (match_template): Handle monitor.
(process_suffix): Likewise.

gas/testsuite/

2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>

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  <hongjiu.lu@intel.com>

PR gas/1874
* i386.h (i386_optab): Add 64bit support for monitor and mwait.

opcodes/

2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>

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.

12 files changed:
gas/ChangeLog
gas/config/tc-i386.c
gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/prescott.d
gas/testsuite/gas/i386/prescott.s
gas/testsuite/gas/i386/x86-64-prescott.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-prescott.s [new file with mode: 0644]
include/opcode/ChangeLog
include/opcode/i386.h
opcodes/ChangeLog
opcodes/i386-dis.c

index 4bd00a3..90b1f99 100644 (file)
@@ -1,3 +1,9 @@
+2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/1874
+       * config/tc-i386.c (match_template): Handle monitor.
+       (process_suffix): Likewise.
+
 2005-12-05  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        Bug gas/1948
index 1828c48..b95a664 100644 (file)
@@ -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;
 
index 849c885..43f0588 100644 (file)
@@ -1,3 +1,14 @@
+2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       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  <hp@axis.com>
 
        * gas/cris/rd-pcplus.s, gas/cris/rd-pcplus.d: New test.
index d536da3..718514f 100644 (file)
@@ -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*"]
index 496bb49..1e66065 100644 (file)
@@ -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
        ...
index a70c835..95dacf7 100644 (file)
@@ -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 (file)
index 0000000..43a2d28
--- /dev/null
@@ -0,0 +1,37 @@
+#objdump: -dw
+#name: x86-64 prescott
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <foo>:
+   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 (file)
index 0000000..0f03683
--- /dev/null
@@ -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
index c9a4a12..b257be4 100644 (file)
@@ -1,3 +1,8 @@
+2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR gas/1874
+       * i386.h (i386_optab): Add 64bit support for monitor and mwait.
+
 2005-11-14  David Ung  <davidu@mips.com>
 
        * mips.h: Assign 'm'/'M' codes to MIPS16e save/restore
index 59b5e3c..33f94cc 100644 (file)
@@ -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} },
index c5b400f..61e6e5d 100644 (file)
@@ -1,3 +1,30 @@
+2005-12-06  H.J. Lu  <hongjiu.lu@intel.com>
+
+       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  <hp@axis.com>
 
        * cris-dis.c (bytes_to_skip): Handle new parameter prefix_matchedp.
index 47455e3..5adf4af 100644 (file)
@@ -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];