aboutsummaryrefslogtreecommitdiff
path: root/opcodes/i386-dis.c
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2014-09-10 09:38:31 -0700
committerH.J. Lu <hjl.tools@gmail.com>2014-09-10 09:39:24 -0700
commit4b4c407a349620e4a6b9cb36b77778fccb7ff00f (patch)
tree5b55e7862c8bd1c6e9d31b86a9f3446caf89e421 /opcodes/i386-dis.c
parenta485e98ea0cbb61ea9da1e7858da545e0bcf1a46 (diff)
downloadgdb-4b4c407a349620e4a6b9cb36b77778fccb7ff00f.zip
gdb-4b4c407a349620e4a6b9cb36b77778fccb7ff00f.tar.gz
gdb-4b4c407a349620e4a6b9cb36b77778fccb7ff00f.tar.bz2
Properly handle suffix for iret and sysret
gas/testsuite/ * gas/i386/i386.exp: Run suffix-intel, x86-64-suffix and x86-64-suffix-intel. * gas/i386/suffix.s: Add tests for iret and sysret. * gas/i386/suffix.d: Updated. * gas/i386/suffix-intel.d: New file. * gas/i386/x86-64-suffix-intel.d: Likewise. * gas/i386/x86-64-suffix.d: Likewise. * gas/i386/x86-64-suffix.s: Likewise. opcodes/ * i386-dis.c (dis386): Replace "P" with "%LP" for iret and sysret. (putop): Handle "%LP".
Diffstat (limited to 'opcodes/i386-dis.c')
-rw-r--r--opcodes/i386-dis.c75
1 files changed, 54 insertions, 21 deletions
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 34bb61d..79abe09 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -2397,6 +2397,9 @@ struct dis386 {
"LS" => print "abs" in 64bit mode and behave as 'S' otherwise
"LV" => print "abs" for 64bit operand and behave as 'S' otherwise
"LW" => print 'd', 'q' depending on the VEX.W bit
+ "LP" => print 'w' or 'l' ('d' in Intel mode) if instruction has
+ an operand size prefix, or suffix_always is true. print
+ 'q' if rex prefix is present.
Many of the above letters print nothing in Intel mode. See "putop"
for the details.
@@ -2638,7 +2641,7 @@ static const struct dis386 dis386[] = {
{ "int3", { XX } },
{ "int", { Ib } },
{ X86_64_TABLE (X86_64_CE) },
- { "iretP", { XX } },
+ { "iret%LP", { XX } },
/* d0 */
{ REG_TABLE (REG_D0) },
{ REG_TABLE (REG_D1) },
@@ -2704,7 +2707,7 @@ static const struct dis386 dis386_twobyte[] = {
{ Bad_Opcode },
{ "syscall", { XX } },
{ "clts", { XX } },
- { "sysretP", { XX } },
+ { "sysret%LP", { XX } },
/* 08 */
{ "invd", { XX } },
{ "wbinvd", { XX } },
@@ -13835,32 +13838,62 @@ case_L:
break;
}
/* Fall through. */
+ goto case_P;
case 'P':
- if (intel_syntax)
+ if (l == 0 && len == 1)
{
- if ((rex & REX_W) == 0
- && (prefixes & PREFIX_DATA))
+case_P:
+ if (intel_syntax)
{
- if ((sizeflag & DFLAG) == 0)
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
+ if ((rex & REX_W) == 0
+ && (prefixes & PREFIX_DATA))
+ {
+ if ((sizeflag & DFLAG) == 0)
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
+ break;
+ }
+ if ((prefixes & PREFIX_DATA)
+ || (rex & REX_W)
+ || (sizeflag & SUFFIX_ALWAYS))
+ {
+ USED_REX (REX_W);
+ if (rex & REX_W)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
}
- break;
}
- if ((prefixes & PREFIX_DATA)
- || (rex & REX_W)
- || (sizeflag & SUFFIX_ALWAYS))
+ else
{
- USED_REX (REX_W);
- if (rex & REX_W)
- *obufp++ = 'q';
- else
+ if (l != 1 || len != 2 || last[0] != 'L')
+ {
+ SAVE_LAST (*p);
+ break;
+ }
+
+ if ((prefixes & PREFIX_DATA)
+ || (rex & REX_W)
+ || (sizeflag & SUFFIX_ALWAYS))
{
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
+ USED_REX (REX_W);
+ if (rex & REX_W)
+ *obufp++ = 'q';
+ else
+ {
+ if (sizeflag & DFLAG)
+ *obufp++ = intel_syntax ? 'd' : 'l';
+ else
+ *obufp++ = 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
+ }
}
}
break;