From e3949f17f39bb2cf78561541b0473cd93cb000cf Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 18 Jan 2011 17:08:13 +0000 Subject: Properly sign-extend byte. gas/testsuite/ 2011-01-18 H.J. Lu * gas/i386/intel.d: Updated. * gas/i386/opcode-intel.d: Likewise. * gas/i386/opcode-suffix.d: Likewise. * gas/i386/opcode.d: Likewise. opcodes/ 2011-01-18 H.J. Lu * i386-dis.c (sIbT): New. (b_T_mode): Likewise. (dis386): Replace sIb with sIbT on "pushT". (x86_64_table): Replace sIb with Ib on "aam" and "aad". (OP_sI): Handle b_T_mode. Properly sign-extend byte. --- opcodes/i386-dis.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'opcodes/i386-dis.c') diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index a4e16cb..c9dd17a 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -252,6 +252,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr) #define Rm { OP_R, m_mode } #define Ib { OP_I, b_mode } #define sIb { OP_sI, b_mode } /* sign extened byte */ +#define sIbT { OP_sI, b_T_mode } /* sign extened byte like 'T' */ #define Iv { OP_I, v_mode } #define sIv { OP_sI, v_mode } #define Iq { OP_I, q_mode } @@ -414,6 +415,8 @@ enum b_mode = 1, /* byte operand with operand swapped */ b_swap_mode, + /* byte operand, sign extend like 'T' suffix */ + b_T_mode, /* operand size depends on prefixes */ v_mode, /* operand size depends on prefixes with operand swapped */ @@ -1790,7 +1793,7 @@ static const struct dis386 dis386[] = { /* 68 */ { "pushT", { sIv } }, { "imulS", { Gv, Ev, Iv } }, - { "pushT", { sIb } }, + { "pushT", { sIbT } }, { "imulS", { Gv, Ev, sIb } }, { "ins{b|}", { Ybr, indirDX } }, { X86_64_TABLE (X86_64_6D) }, @@ -5544,12 +5547,12 @@ static const struct dis386 x86_64_table[][2] = { /* X86_64_D4 */ { - { "aam", { sIb } }, + { "aam", { Ib } }, }, /* X86_64_D5 */ { - { "aad", { sIb } }, + { "aad", { Ib } }, }, /* X86_64_EA */ @@ -13731,10 +13734,32 @@ OP_sI (int bytemode, int sizeflag) switch (bytemode) { case b_mode: + case b_T_mode: FETCH_DATA (the_info, codep + 1); op = *codep++; if ((op & 0x80) != 0) op -= 0x100; + if (bytemode == b_T_mode) + { + if (address_mode != mode_64bit + || !(sizeflag & DFLAG)) + { + if (sizeflag & DFLAG) + op &= 0xffffffff; + else + op &= 0xffff; + } + } + else + { + if (!(rex & REX_W)) + { + if (sizeflag & DFLAG) + op &= 0xffffffff; + else + op &= 0xffff; + } + } break; case v_mode: if (sizeflag & DFLAG) -- cgit v1.1