From 52fd6d94163f6cf1a1fbda57ed4c34da53f726a4 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 1 Dec 2006 15:00:12 +0000 Subject: [PATCH] opcodes/ 2006-11-30 Jan Beulich * 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 * 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 | 7 ++ gas/testsuite/gas/i386/i386.exp | 3 + gas/testsuite/gas/i386/x86-64-io-intel.d | 28 ++++++++ gas/testsuite/gas/i386/x86-64-io-suffix.d | 28 ++++++++ gas/testsuite/gas/i386/x86-64-io.d | 27 +++++++ gas/testsuite/gas/i386/x86-64-io.s | 16 +++++ opcodes/ChangeLog | 16 +++++ opcodes/i386-dis.c | 87 ++++++++++++++++++----- 8 files changed, 194 insertions(+), 18 deletions(-) create mode 100644 gas/testsuite/gas/i386/x86-64-io-intel.d create mode 100644 gas/testsuite/gas/i386/x86-64-io-suffix.d create mode 100644 gas/testsuite/gas/i386/x86-64-io.d create mode 100644 gas/testsuite/gas/i386/x86-64-io.s diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 725f9103a75..33821537f94 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2006-11-30 Jan Beulich + + * 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 * gas/i386/intel.s: Use Intel syntax in Intel syntax test. 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,3 +1,19 @@ +2006-11-30 Jan Beulich + + * 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 * i386-dis.c (dis386): Use 'R' and 'O' for cbw/cwd unconditionally. 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 -- 2.30.2