diff options
Diffstat (limited to 'opcodes')
-rw-r--r-- | opcodes/ChangeLog | 8 | ||||
-rw-r--r-- | opcodes/i386-dis.c | 31 |
2 files changed, 36 insertions, 3 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 80d3aaacea..0b7b023422 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,11 @@ +2011-01-18 H.J. Lu <hongjiu.lu@intel.com> + + * 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. + 2011-01-18 Jan Kratochvil <jan.kratochvil@redhat.com> * i386-init.h: Regenerated. diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index a4e16cb615..c9dd17a45f 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) |