opcodes/
authorJan Beulich <jbeulich@novell.com>
Fri, 1 Dec 2006 15:00:12 +0000 (15:00 +0000)
committerJan Beulich <jbeulich@novell.com>
Fri, 1 Dec 2006 15:00:12 +0000 (15:00 +0000)
2006-11-30  Jan Beulich  <jbeulich@novell.com>

* i386-dis.c (zAX): New.
(Xz): New.
(Yzr): New.
(z_mode): New.
(z_mode_ax_reg): New.
(putop): New suffix character 'G'.
(dis386): Use it for in, out, ins, and outs.
(intel_operand_size): Handle z_mode.
(OP_REG): Delete unreachable case indir_dx_reg.
(OP_IMREG): Fix Intel syntax output for case indir_dx_reg. Handle
z_mode_ax_reg.
(OP_ESreg): Fix Intel syntax operand size handling.
(OP_DSreg): Likewise.

gas/testsuite/
2006-11-30  Jan Beulich  <jbeulich@novell.com>

* gas/i386/x86-64-io.[sd]: New.
* gas/i386/x86-64-io-intel.d: New.
* gas/i386/x86-64-io-suffix.d: New.
* gas/i386/i386.exp: Run new tests.

gas/testsuite/ChangeLog
gas/testsuite/gas/i386/i386.exp
gas/testsuite/gas/i386/x86-64-io-intel.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-io-suffix.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-io.d [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64-io.s [new file with mode: 0644]
opcodes/ChangeLog
opcodes/i386-dis.c

index 725f9103a750951a3aaa5527a3f24ec6f8b1024b..33821537f94d389e1f9cf7559748a5ebf0213288 100644 (file)
@@ -1,3 +1,10 @@
+2006-11-30  Jan Beulich  <jbeulich@novell.com>
+
+       * gas/i386/x86-64-io.[sd]: New.
+       * gas/i386/x86-64-io-intel.d: New.
+       * gas/i386/x86-64-io-suffix.d: New.
+       * gas/i386/i386.exp: Run new tests.
+
 2006-11-30  Jan Beulich  <jbeulich@novell.com>
 
        * gas/i386/intel.s: Use Intel syntax in Intel syntax test.
index 699ad652baf2db1f282e4fc2ffc561bc59699ddf..cdf3e14b93cf095409569f1cfa633398b40f1dd3 100644 (file)
@@ -157,6 +157,9 @@ if [expr ([istarget "i*86-*-*"] || [istarget "x86_64-*-*"]) && [gas_64_check]] t
     run_dump_test "x86-64-rep-suffix"
     run_dump_test "x86-64-cbw"
     run_dump_test "x86-64-cbw-intel"
+    run_dump_test "x86-64-io"
+    run_dump_test "x86-64-io-intel"
+    run_dump_test "x86-64-io-suffix"
     run_dump_test "x86-64-gidt"
     run_dump_test "x86-64-nops"
     if ![istarget "*-*-mingw64*"] then {
diff --git a/gas/testsuite/gas/i386/x86-64-io-intel.d b/gas/testsuite/gas/i386/x86-64-io-intel.d
new file mode 100644 (file)
index 0000000..a8787a0
--- /dev/null
@@ -0,0 +1,28 @@
+#source: x86-64-io.s
+#objdump: -dwMintel
+#name: x86-64 rex64 in/out (Intel disassembly)
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <_in>:
+   0:  48 ed                   rex64 in     eax,dx
+   2:  66                      data16
+   3:  48 ed                   rex64 in     eax,dx
+
+0+005 <_out>:
+   5:  48 ef                   rex64 out    dx,eax
+   7:  66                      data16
+   8:  48 ef                   rex64 out    dx,eax
+
+0+00a <_ins>:
+   a:  48 6d                   rex64 ins    DWORD PTR es:\[rdi\],dx
+   c:  66                      data16
+   d:  48 6d                   rex64 ins    DWORD PTR es:\[rdi\],dx
+
+0+00f <_outs>:
+   f:  48 6f                   rex64 outs   dx,DWORD PTR ds:\[rsi\]
+  11:  66                      data16
+  12:  48 6f                   rex64 outs   dx,DWORD PTR ds:\[rsi\]
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-io-suffix.d b/gas/testsuite/gas/i386/x86-64-io-suffix.d
new file mode 100644 (file)
index 0000000..f83b162
--- /dev/null
@@ -0,0 +1,28 @@
+#source: x86-64-io.s
+#objdump: -dwMsuffix
+#name: x86-64 rex64 in/out w/ suffix
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <_in>:
+   0:  48 ed                   rex64 inl    \(%dx\),%eax
+   2:  66                      data16
+   3:  48 ed                   rex64 inl    \(%dx\),%eax
+
+0+005 <_out>:
+   5:  48 ef                   rex64 outl   %eax,\(%dx\)
+   7:  66                      data16
+   8:  48 ef                   rex64 outl   %eax,\(%dx\)
+
+0+00a <_ins>:
+   a:  48 6d                   rex64 insl   \(%dx\),%es:\(%rdi\)
+   c:  66                      data16
+   d:  48 6d                   rex64 insl   \(%dx\),%es:\(%rdi\)
+
+0+00f <_outs>:
+   f:  48 6f                   rex64 outsl  %ds:\(%rsi\),\(%dx\)
+  11:  66                      data16
+  12:  48 6f                   rex64 outsl  %ds:\(%rsi\),\(%dx\)
+#pass
diff --git a/gas/testsuite/gas/i386/x86-64-io.d b/gas/testsuite/gas/i386/x86-64-io.d
new file mode 100644 (file)
index 0000000..7158b75
--- /dev/null
@@ -0,0 +1,27 @@
+#objdump: -dw
+#name: x86-64 rex64 in/out
+
+.*: +file format .*
+
+Disassembly of section .text:
+
+0+000 <_in>:
+   0:  48 ed                   rex64 in     \(%dx\),%eax
+   2:  66                      data16
+   3:  48 ed                   rex64 in     \(%dx\),%eax
+
+0+005 <_out>:
+   5:  48 ef                   rex64 out    %eax,\(%dx\)
+   7:  66                      data16
+   8:  48 ef                   rex64 out    %eax,\(%dx\)
+
+0+00a <_ins>:
+   a:  48 6d                   rex64 insl   \(%dx\),%es:\(%rdi\)
+   c:  66                      data16
+   d:  48 6d                   rex64 insl   \(%dx\),%es:\(%rdi\)
+
+0+00f <_outs>:
+   f:  48 6f                   rex64 outsl  %ds:\(%rsi\),\(%dx\)
+  11:  66                      data16
+  12:  48 6f                   rex64 outsl  %ds:\(%rsi\),\(%dx\)
+#pass
\ No newline at end of file
diff --git a/gas/testsuite/gas/i386/x86-64-io.s b/gas/testsuite/gas/i386/x86-64-io.s
new file mode 100644 (file)
index 0000000..58200c8
--- /dev/null
@@ -0,0 +1,16 @@
+ .intel_syntax noprefix
+ .text
+_in:
+       rex64 in eax,dx
+       rex64 in ax,dx
+_out:
+       rex64 out dx,eax
+       rex64 out dx,ax
+_ins:
+       rex64 insd
+       rex64 insw
+_outs:
+       rex64 outsd
+       rex64 outsw
+
+       .p2align        4,0
index 36a479cb1826539c0c141730440d1bf8a7fc10f1..ffd2326e27bd27f1c3ff39e04f8ebf7954fbb261 100644 (file)
@@ -1,3 +1,19 @@
+2006-11-30  Jan Beulich  <jbeulich@novell.com>
+
+       * i386-dis.c (zAX): New.
+       (Xz): New.
+       (Yzr): New.
+       (z_mode): New.
+       (z_mode_ax_reg): New.
+       (putop): New suffix character 'G'.
+       (dis386): Use it for in, out, ins, and outs.
+       (intel_operand_size): Handle z_mode.
+       (OP_REG): Delete unreachable case indir_dx_reg.
+       (OP_IMREG): Fix Intel syntax output for case indir_dx_reg. Handle
+       z_mode_ax_reg.
+       (OP_ESreg): Fix Intel syntax operand size handling.
+       (OP_DSreg): Likewise.
+
 2006-11-30  Jan Beulich  <jbeulich@novell.com>
 
        * i386-dis.c (dis386): Use 'R' and 'O' for cbw/cwd unconditionally.
index 7873a31dfa1f76a37e4c60f9e7c7a2e245d91388..7e5c30570468e8e0ff2a9c7ff1d8d61a163092ad 100644 (file)
@@ -289,6 +289,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define BH OP_IMREG, bh_reg
 #define AX OP_IMREG, ax_reg
 #define DX OP_IMREG, dx_reg
+#define zAX OP_IMREG, z_mode_ax_reg
 #define indirDX OP_IMREG, indir_dx_reg
 
 #define Sw OP_SEG, w_mode
@@ -297,6 +298,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Ov OP_OFF64, v_mode
 #define Xb OP_DSreg, eSI_reg
 #define Xv OP_DSreg, eSI_reg
+#define Xz OP_DSreg, eSI_reg
 #define Yb OP_ESreg, eDI_reg
 #define Yv OP_ESreg, eDI_reg
 #define DSBX OP_DSreg, eBX_reg
@@ -325,6 +327,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define Xvr REP_Fixup, eSI_reg
 #define Ybr REP_Fixup, eDI_reg
 #define Yvr REP_Fixup, eDI_reg
+#define Yzr REP_Fixup, eDI_reg
 #define indirDXr REP_Fixup, indir_dx_reg
 #define ALr REP_Fixup, al_reg
 #define eAXr REP_Fixup, eAX_reg
@@ -352,6 +355,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define f_mode 13 /* 4- or 6-byte pointer operand */
 #define const_1_mode 14
 #define stack_v_mode 15 /* v_mode for stack-related opcodes.  */
+#define z_mode 16 /* non-quad operand size depends on prefixes */
 
 #define es_reg 100
 #define cs_reg 101
@@ -396,6 +400,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
 #define rSI_reg 138
 #define rDI_reg 139
 
+#define z_mode_ax_reg 149
 #define indir_dx_reg 150
 
 #define FLOATCODE 1
@@ -500,6 +505,7 @@ struct dis386 {
    .      size prefix
    'E' => print 'e' if 32-bit form of jcxz
    'F' => print 'w' or 'l' depending on address size prefix (loop insns)
+   'G' => print 'w' or 'l' depending on operand size prefix (i/o insns)
    'H' => print ",pt" or ",pn" branch hint
    'I' => honor following macro letter even in Intel mode (implemented only
    .      for some of the macro letters)
@@ -654,9 +660,9 @@ static const struct dis386 dis386[] = {
   { "pushT",           sIb, XX, XX, XX },
   { "imulS",           Gv, Ev, sIb, XX },
   { "ins{b||b|}",      Ybr, indirDX, XX, XX },
-  { "ins{R||R|}",      Yvr, indirDX, XX, XX },
+  { "ins{R||G|}",      Yzr, indirDX, XX, XX },
   { "outs{b||b|}",     indirDXr, Xb, XX, XX },
-  { "outs{R||R|}",     indirDXr, Xv, XX, XX },
+  { "outs{R||G|}",     indirDXr, Xz, XX, XX },
   /* 70 */
   { "joH",             Jb, XX, cond_jump_flag, XX },
   { "jnoH",            Jb, XX, cond_jump_flag, XX },
@@ -789,18 +795,18 @@ static const struct dis386 dis386[] = {
   { "loopFH",          Jb, XX, loop_jcxz_flag, XX },
   { "jEcxzH",          Jb, XX, loop_jcxz_flag, XX },
   { "inB",             AL, Ib, XX, XX },
-  { "inS",             eAX, Ib, XX, XX },
+  { "inG",             zAX, Ib, XX, XX },
   { "outB",            Ib, AL, XX, XX },
-  { "outS",            Ib, eAX, XX, XX },
+  { "outG",            Ib, zAX, XX, XX },
   /* e8 */
   { "callT",           Jv, XX, XX, XX },
   { "jmpT",            Jv, XX, XX, XX },
   { "Jjmp{T|}",                Ap, XX, XX, XX },
   { "jmp",             Jb, XX, XX, XX },
   { "inB",             AL, indirDX, XX, XX },
-  { "inS",             eAX, indirDX, XX, XX },
+  { "inG",             zAX, indirDX, XX, XX },
   { "outB",            indirDX, AL, XX, XX },
-  { "outS",            indirDX, eAX, XX, XX },
+  { "outG",            indirDX, zAX, XX, XX },
   /* f0 */
   { "(bad)",           XX, XX, XX, XX },       /* lock prefix */
   { "icebp",           XX, XX, XX, XX },
@@ -3767,6 +3773,16 @@ putop (const char *template, int sizeflag)
              used_prefixes |= (prefixes & PREFIX_ADDR);
            }
          break;
+       case 'G':
+         if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS)))
+           break;
+         if ((rex & REX_MODE64) || (sizeflag & DFLAG))
+           *obufp++ = 'l';
+         else
+           *obufp++ = 'w';
+         if (!(rex & REX_MODE64))
+           used_prefixes |= (prefixes & PREFIX_DATA);
+         break;
        case 'H':
          if (intel_syntax)
            break;
@@ -4101,6 +4117,13 @@ intel_operand_size (int bytemode, int sizeflag)
        oappend ("WORD PTR ");
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
+    case z_mode:
+      if ((rex & REX_MODE64) || (sizeflag & DFLAG))
+       *obufp++ = 'D';
+      oappend ("WORD PTR ");
+      if (!(rex & REX_MODE64))
+       used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
     case d_mode:
       oappend ("DWORD PTR ");
       break;
@@ -4551,12 +4574,6 @@ OP_REG (int code, int sizeflag)
 
   switch (code)
     {
-    case indir_dx_reg:
-      if (intel_syntax)
-       s = "[dx]";
-      else
-       s = "(%dx)";
-      break;
     case ax_reg: case cx_reg: case dx_reg: case bx_reg:
     case sp_reg: case bp_reg: case si_reg: case di_reg:
       s = names16[code - ax_reg + add];
@@ -4609,7 +4626,7 @@ OP_IMREG (int code, int sizeflag)
     {
     case indir_dx_reg:
       if (intel_syntax)
-       s = "[dx]";
+       s = "dx";
       else
        s = "(%dx)";
       break;
@@ -4640,6 +4657,14 @@ OP_IMREG (int code, int sizeflag)
        s = names16[code - eAX_reg];
       used_prefixes |= (prefixes & PREFIX_DATA);
       break;
+    case z_mode_ax_reg:
+      if ((rex & REX_MODE64) || (sizeflag & DFLAG))
+       s = *names32;
+      else
+       s = *names16;
+      if (!(rex & REX_MODE64))
+       used_prefixes |= (prefixes & PREFIX_DATA);
+      break;
     default:
       s = INTERNAL_DISASSEMBLER_ERROR;
       break;
@@ -4953,7 +4978,22 @@ static void
 OP_ESreg (int code, int sizeflag)
 {
   if (intel_syntax)
-    intel_operand_size (codep[-1] & 1 ? v_mode : b_mode, sizeflag);
+    {
+      switch (codep[-1])
+       {
+       case 0x6d:      /* insw/insl */
+         intel_operand_size (z_mode, sizeflag);
+         break;
+       case 0xa5:      /* movsw/movsl/movsq */
+       case 0xa7:      /* cmpsw/cmpsl/cmpsq */
+       case 0xab:      /* stosw/stosl */
+       case 0xaf:      /* scasw/scasl */
+         intel_operand_size (v_mode, sizeflag);
+         break;
+       default:
+         intel_operand_size (b_mode, sizeflag);
+       }
+    }
   oappend ("%es:" + intel_syntax);
   ptr_reg (code, sizeflag);
 }
@@ -4962,10 +5002,21 @@ static void
 OP_DSreg (int code, int sizeflag)
 {
   if (intel_syntax)
-    intel_operand_size (codep[-1] != 0xd7 && (codep[-1] & 1)
-                       ? v_mode
-                       : b_mode,
-                       sizeflag);
+    {
+      switch (codep[-1])
+       {
+       case 0x6f:      /* outsw/outsl */
+         intel_operand_size (z_mode, sizeflag);
+         break;
+       case 0xa5:      /* movsw/movsl/movsq */
+       case 0xa7:      /* cmpsw/cmpsl/cmpsq */
+       case 0xad:      /* lodsw/lodsl/lodsq */
+         intel_operand_size (v_mode, sizeflag);
+         break;
+       default:
+         intel_operand_size (b_mode, sizeflag);
+       }
+    }
   if ((prefixes
        & (PREFIX_CS
          | PREFIX_DS