summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/testsuite/ChangeLog7
-rw-r--r--gas/testsuite/gas/i386/i386.exp3
-rw-r--r--gas/testsuite/gas/i386/x86-64-io-intel.d28
-rw-r--r--gas/testsuite/gas/i386/x86-64-io-suffix.d28
-rw-r--r--gas/testsuite/gas/i386/x86-64-io.d27
-rw-r--r--gas/testsuite/gas/i386/x86-64-io.s16
-rw-r--r--opcodes/ChangeLog16
-rw-r--r--opcodes/i386-dis.c87
8 files changed, 194 insertions, 18 deletions
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 725f9103a75..33821537f94 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,12 @@
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.
* gas/i386/x86-64-cbw.[sd]: New.
* gas/i386/x86-64-cbw-intel.d: New.
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 699ad652baf..cdf3e14b93c 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -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
index 00000000000..a8787a00b5c
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-io-intel.d
@@ -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
index 00000000000..f83b1622305
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-io-suffix.d
@@ -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
index 00000000000..7158b75388e
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-io.d
@@ -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
index 00000000000..58200c825b8
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-io.s
@@ -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
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 36a479cb182..ffd2326e27b 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,5 +1,21 @@
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.
(putop): For 'O' suffix, print 'q' in Intel mode, and mark data prefix
used. For 'R' and 'W' suffix, simplify and fix Intel mode.
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 7873a31dfa1..7e5c3057046 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -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