aboutsummaryrefslogtreecommitdiff
path: root/opcodes
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2020-07-15 08:53:55 +0200
committerJan Beulich <jbeulich@suse.com>2020-07-15 08:53:55 +0200
commit36938cabf0efcb053d1585e8580a4b3db438ca4e (patch)
treee7193f8c5b4f0cc83b6a76a4d5a35f0b86058abd /opcodes
parenta8a48c756c0da3a49008662e14ae582764ddd0bb (diff)
downloadgdb-36938cabf0efcb053d1585e8580a4b3db438ca4e.zip
gdb-36938cabf0efcb053d1585e8580a4b3db438ca4e.tar.gz
gdb-36938cabf0efcb053d1585e8580a4b3db438ca4e.tar.bz2
x86: avoid attaching suffixes to unambiguous insns
"Unambiguous" is is in particular taking as reference the assembler, which also accepts certain insns - despite them allowing for varying operand size, and hence in principle being ambiguous - without any suffix. For example, from the very beginning of the life of x86-64 I had trouble understanding why a plain and simple RET had to be printed as RETQ. In case someone really used the 16-bit form, RETW disambiguates the two quite fine.
Diffstat (limited to 'opcodes')
-rw-r--r--opcodes/ChangeLog14
-rw-r--r--opcodes/i386-dis.c143
2 files changed, 58 insertions, 99 deletions
diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog
index 9a972d4..7fff032 100644
--- a/opcodes/ChangeLog
+++ b/opcodes/ChangeLog
@@ -1,3 +1,17 @@
+2020-07-15 Jan Beulich <jbeulich@suse.com>
+
+ * i386-dis.c (dis386): Adjust 'P', 'T', 'U', and '@'
+ description. Drop '&' description. Use P for push of immediate,
+ pushf/popf, enter, and leave. Use %LP for lret/retf.
+ (dis386_twobyte): Use P for push/pop of fs/gs.
+ (reg_table): Use P for push/pop. Use @ for near call/jmp.
+ (x86_64_table): Use P for far call/jmp.
+ (putop): Drop handling of 'U' and '&'. Move and adjust handling
+ of '@'. Adjust handling of 'P' and 'T'. Drop case_P and case_Q
+ labels.
+ (OP_J): Drop marking of REX_W as used for v_mode (ISA-dependent)
+ and dqw_mode (unconditional).
+
2020-07-14 H.J. Lu <hongjiu.lu@intel.com>
PR gas/26237
diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c
index 511e632..ef539ca 100644
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1738,16 +1738,15 @@ struct dis386 {
'M' => print 'r' if intel_mnemonic is false.
'N' => print 'n' if instruction has no wait "prefix"
'O' => print 'd' or 'o' (or 'q' in Intel mode)
- 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
- or suffix_always is true. print 'q' if rex prefix is present.
+ 'P' => behave as 'T' except with register operand outside of suffix_always
+ mode
'Q' => print 'w', 'l' or 'q' for memory operand or suffix_always
is true
'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode)
'S' => print 'w', 'l' or 'q' if suffix_always is true
- 'T' => print 'q' in 64bit mode if instruction has no operand size
- prefix and behave as 'P' otherwise
- 'U' => print 'q' in 64bit mode if instruction has no operand size
- prefix and behave as 'Q' otherwise
+ 'T' => print 'w', 'l'/'d', or 'q' if instruction has an operand size
+ prefix or if suffix_always is true.
+ 'U' unused.
'V' => print 'q' in 64bit mode if instruction has no operand size
prefix and behave as 'S' otherwise
'W' => print 'b', 'w' or 'l' ('d' in Intel mode)
@@ -1758,11 +1757,9 @@ struct dis386 {
'%' => add 1 upper case letter to the macro.
'^' => print 'w', 'l', or 'q' (Intel64 ISA only) depending on operand size
prefix or suffix_always is true (lcall/ljmp).
- '@' => print 'q' for Intel64 ISA, 'w' or 'q' for AMD64 ISA depending
- on operand size prefix.
- '&' => print 'q' in 64bit mode for Intel64 ISA or if instruction
- has no operand size prefix for AMD64 ISA, behave as 'P'
- otherwise
+ '@' => in 64bit mode for Intel64 ISA or if instruction
+ has no operand sizing prefix, print 'q' if suffix_always is true or
+ nothing otherwise; behave as 'P' in all other cases
2 upper case letter macros:
"XY" => print 'x' or 'y' if suffix_always is true or no register
@@ -1907,9 +1904,9 @@ static const struct dis386 dis386[] = {
{ Bad_Opcode }, /* op size prefix */
{ Bad_Opcode }, /* adr size prefix */
/* 68 */
- { "pushT", { sIv }, 0 },
+ { "pushP", { sIv }, 0 },
{ "imulS", { Gv, Ev, Iv }, 0 },
- { "pushT", { sIbT }, 0 },
+ { "pushP", { sIbT }, 0 },
{ "imulS", { Gv, Ev, sIb }, 0 },
{ "ins{b|}", { Ybr, indirDX }, 0 },
{ X86_64_TABLE (X86_64_6D) },
@@ -1965,8 +1962,8 @@ static const struct dis386 dis386[] = {
{ "cR{t|}O", { XX }, 0 },
{ X86_64_TABLE (X86_64_9A) },
{ Bad_Opcode }, /* fwait */
- { "pushfT", { XX }, 0 },
- { "popfT", { XX }, 0 },
+ { "pushfP", { XX }, 0 },
+ { "popfP", { XX }, 0 },
{ "sahf", { XX }, 0 },
{ "lahf", { XX }, 0 },
/* a0 */
@@ -2015,10 +2012,10 @@ static const struct dis386 dis386[] = {
{ REG_TABLE (REG_C6) },
{ REG_TABLE (REG_C7) },
/* c8 */
- { "enterT", { Iw, Ib }, 0 },
- { "leaveT", { XX }, 0 },
- { "{l|}ret{|f}P", { Iw }, 0 },
- { "{l|}ret{|f}P", { XX }, 0 },
+ { "enterP", { Iw, Ib }, 0 },
+ { "leaveP", { XX }, 0 },
+ { "{l|}ret{|f}%LP", { Iw }, 0 },
+ { "{l|}ret{|f}%LP", { XX }, 0 },
{ "int3", { XX }, 0 },
{ "int", { Ib }, 0 },
{ X86_64_TABLE (X86_64_CE) },
@@ -2261,8 +2258,8 @@ static const struct dis386 dis386_twobyte[] = {
{ "setle", { Eb }, 0 },
{ "setg", { Eb }, 0 },
/* a0 */
- { "pushT", { fs }, 0 },
- { "popT", { fs }, 0 },
+ { "pushP", { fs }, 0 },
+ { "popP", { fs }, 0 },
{ "cpuid", { XX }, 0 },
{ "btS", { Ev, Gv }, 0 },
{ "shldS", { Ev, Gv, Ib }, 0 },
@@ -2270,8 +2267,8 @@ static const struct dis386 dis386_twobyte[] = {
{ REG_TABLE (REG_0FA6) },
{ REG_TABLE (REG_0FA7) },
/* a8 */
- { "pushT", { gs }, 0 },
- { "popT", { gs }, 0 },
+ { "pushP", { gs }, 0 },
+ { "popP", { gs }, 0 },
{ "rsm", { XX }, 0 },
{ "btsS", { Evh1, Gv }, 0 },
{ "shrdS", { Ev, Gv, Ib }, 0 },
@@ -2695,7 +2692,7 @@ static const struct dis386 reg_table[][8] = {
},
/* REG_8F */
{
- { "popU", { stackEv }, 0 },
+ { "pop{P|}", { stackEv }, 0 },
{ XOP_8F_TABLE (XOP_09) },
{ Bad_Opcode },
{ Bad_Opcode },
@@ -2821,11 +2818,11 @@ static const struct dis386 reg_table[][8] = {
{
{ "incQ", { Evh1 }, 0 },
{ "decQ", { Evh1 }, 0 },
- { "call{&|}", { NOTRACK, indirEv, BND }, 0 },
+ { "call{@|}", { NOTRACK, indirEv, BND }, 0 },
{ MOD_TABLE (MOD_FF_REG_3) },
- { "jmp{&|}", { NOTRACK, indirEv, BND }, 0 },
+ { "jmp{@|}", { NOTRACK, indirEv, BND }, 0 },
{ MOD_TABLE (MOD_FF_REG_5) },
- { "pushU", { stackEv }, 0 },
+ { "push{P|}", { stackEv }, 0 },
{ Bad_Opcode },
},
/* REG_0F00 */
@@ -4072,7 +4069,7 @@ static const struct dis386 x86_64_table[][2] = {
/* X86_64_9A */
{
- { "{l|}call{T|}", { Ap }, 0 },
+ { "{l|}call{P|}", { Ap }, 0 },
},
/* X86_64_C2 */
@@ -4128,7 +4125,7 @@ static const struct dis386 x86_64_table[][2] = {
/* X86_64_EA */
{
- { "{l|}jmp{T|}", { Ap }, 0 },
+ { "{l|}jmp{P|}", { Ap }, 0 },
},
/* X86_64_0F01_REG_0 */
@@ -10637,56 +10634,33 @@ putop (const char *in_template, int sizeflag)
if (!(rex & REX_W))
used_prefixes |= (prefixes & PREFIX_DATA);
break;
- case '&':
- if (!intel_syntax
- && address_mode == mode_64bit
- && isa64 == intel64)
- {
- *obufp++ = 'q';
- break;
- }
- /* Fall through. */
- case 'T':
- if (!intel_syntax
- && address_mode == mode_64bit
- && ((sizeflag & DFLAG) || (rex & REX_W)))
+ case '@':
+ if (address_mode == mode_64bit
+ && (isa64 == intel64 || (rex & REX_W)
+ || !(prefixes & PREFIX_DATA)))
{
- *obufp++ = 'q';
+ if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'q';
break;
}
/* Fall through. */
- goto case_P;
case 'P':
if (l == 0)
{
- case_P:
- if (intel_syntax)
- {
- 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))
+ if (need_modrm && modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS))
+ break;
+ /* Fall through. */
+ case 'T':
+ if ((!(rex & REX_W) && (prefixes & PREFIX_DATA))
+ || ((sizeflag & SUFFIX_ALWAYS)
+ && address_mode != mode_64bit))
{
- USED_REX (REX_W);
- if (rex & REX_W)
- *obufp++ = 'q';
- else
- {
- if (sizeflag & DFLAG)
- *obufp++ = 'l';
- else
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
+ *obufp++ = (sizeflag & DFLAG) ?
+ intel_syntax ? 'd' : 'l' : 'w';
+ used_prefixes |= (prefixes & PREFIX_DATA);
}
+ else if (sizeflag & SUFFIX_ALWAYS)
+ *obufp++ = 'q';
}
else if (l == 1 && last[0] == 'L')
{
@@ -10710,22 +10684,9 @@ putop (const char *in_template, int sizeflag)
else
abort ();
break;
- case 'U':
- if (intel_syntax)
- break;
- if (address_mode == mode_64bit
- && ((sizeflag & DFLAG) || (rex & REX_W)))
- {
- if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS))
- *obufp++ = 'q';
- break;
- }
- /* Fall through. */
- goto case_Q;
case 'Q':
if (l == 0)
{
- case_Q:
if (intel_syntax && !alt)
break;
USED_REX (REX_W);
@@ -10964,20 +10925,6 @@ putop (const char *in_template, int sizeflag)
used_prefixes |= (prefixes & PREFIX_DATA);
}
break;
- case '@':
- if (intel_syntax)
- break;
- if (address_mode == mode_64bit
- && (isa64 == intel64
- || ((sizeflag & DFLAG) || (rex & REX_W))))
- *obufp++ = 'q';
- else if ((prefixes & PREFIX_DATA))
- {
- if (!(sizeflag & DFLAG))
- *obufp++ = 'w';
- used_prefixes |= (prefixes & PREFIX_DATA);
- }
- break;
}
if (len == l)
@@ -12563,9 +12510,7 @@ OP_J (int bytemode, int sizeflag)
disp -= 0x100;
break;
case v_mode:
- if (isa64 != intel64)
case dqw_mode:
- USED_REX (REX_W);
if ((sizeflag & DFLAG)
|| (address_mode == mode_64bit
&& ((isa64 == intel64 && bytemode != dqw_mode)