aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2019-11-04 15:48:38 +0100
committerJan Beulich <jbeulich@suse.com>2019-11-04 15:48:38 +0100
commit85b80b0f9bf628971b1a051d8b89c0caa932e734 (patch)
tree98fa89b233a03971ed1a24294cb08add784c8714
parent5103274ffc537711574f9611cb64c51fa9a65546 (diff)
downloadgdb-85b80b0f9bf628971b1a051d8b89c0caa932e734.zip
gdb-85b80b0f9bf628971b1a051d8b89c0caa932e734.tar.gz
gdb-85b80b0f9bf628971b1a051d8b89c0caa932e734.tar.bz2
x86: re-arrange process_operands()
Alter the sequence of conditions evaluated, without affecting the overall result. This is going to help subsequent changes (and as a nice side effect also slightly reduces overall indentation depth). While doing this take the liberty of simplifying the calculation of the operand index of the register operand in ShortForm handling.
-rw-r--r--gas/ChangeLog5
-rw-r--r--gas/config/tc-i386.c106
2 files changed, 54 insertions, 57 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fc99adc..185469f 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2019-11-04 Jan Beulich <jbeulich@suse.com>
+
+ * config/tc-i386.c (process_operands): Handle ShortForm insns
+ later, splitting out their segment register sub-form.
+
2019-10-31 H.J. Lu <hongjiu.lu@intel.com>
* testsuite/gas/i386/general.s: Add .code16gcc fldenv tests.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index f26b17c..5866bd6 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -7004,63 +7004,7 @@ duplicate:
i.reg_operands++;
}
- if (i.tm.opcode_modifier.shortform)
- {
- if (i.types[0].bitfield.sreg)
- {
- if (flag_code != CODE_64BIT
- ? i.tm.base_opcode == POP_SEG_SHORT
- && i.op[0].regs->reg_num == 1
- : (i.tm.base_opcode | 1) == POP_SEG386_SHORT
- && i.op[0].regs->reg_num < 4)
- {
- as_bad (_("you can't `%s %s%s'"),
- i.tm.name, register_prefix, i.op[0].regs->reg_name);
- return 0;
- }
- if ( i.op[0].regs->reg_num > 3 && i.tm.opcode_length == 1 )
- {
- i.tm.base_opcode ^= POP_SEG_SHORT ^ POP_SEG386_SHORT;
- i.tm.opcode_length = 2;
- }
- i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
- }
- else
- {
- /* The register or float register operand is in operand
- 0 or 1. */
- unsigned int op;
-
- if ((i.types[0].bitfield.reg && i.types[0].bitfield.tbyte)
- || operand_type_check (i.types[0], reg))
- op = 0;
- else
- op = 1;
- /* Register goes in low 3 bits of opcode. */
- i.tm.base_opcode |= i.op[op].regs->reg_num;
- if ((i.op[op].regs->reg_flags & RegRex) != 0)
- i.rex |= REX_B;
- if (!quiet_warnings && i.tm.opcode_modifier.ugh)
- {
- /* Warn about some common errors, but press on regardless.
- The first case can be generated by gcc (<= 2.8.1). */
- if (i.operands == 2)
- {
- /* Reversed arguments on faddp, fsubp, etc. */
- as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name,
- register_prefix, i.op[!intel_syntax].regs->reg_name,
- register_prefix, i.op[intel_syntax].regs->reg_name);
- }
- else
- {
- /* Extraneous `l' suffix on fp insn. */
- as_warn (_("translating to `%s %s%s'"), i.tm.name,
- register_prefix, i.op[0].regs->reg_name);
- }
- }
- }
- }
- else if (i.tm.opcode_modifier.modrm)
+ if (i.tm.opcode_modifier.modrm)
{
/* The opcode is completed (modulo i.tm.extension_opcode which
must be put into the modrm byte). Now, we make the modrm and
@@ -7068,6 +7012,25 @@ duplicate:
default_seg = build_modrm_byte ();
}
+ else if (i.types[0].bitfield.sreg)
+ {
+ if (flag_code != CODE_64BIT
+ ? i.tm.base_opcode == POP_SEG_SHORT
+ && i.op[0].regs->reg_num == 1
+ : (i.tm.base_opcode | 1) == POP_SEG386_SHORT
+ && i.op[0].regs->reg_num < 4)
+ {
+ as_bad (_("you can't `%s %s%s'"),
+ i.tm.name, register_prefix, i.op[0].regs->reg_name);
+ return 0;
+ }
+ if ( i.op[0].regs->reg_num > 3 && i.tm.opcode_length == 1 )
+ {
+ i.tm.base_opcode ^= POP_SEG_SHORT ^ POP_SEG386_SHORT;
+ i.tm.opcode_length = 2;
+ }
+ i.tm.base_opcode |= (i.op[0].regs->reg_num << 3);
+ }
else if ((i.tm.base_opcode & ~0x3) == MOV_AX_DISP32)
{
default_seg = &ds;
@@ -7078,6 +7041,35 @@ duplicate:
on one of their operands, the default segment is ds. */
default_seg = &ds;
}
+ else if (i.tm.opcode_modifier.shortform)
+ {
+ /* The register or float register operand is in operand
+ 0 or 1. */
+ unsigned int op = !i.tm.operand_types[0].bitfield.reg;
+
+ /* Register goes in low 3 bits of opcode. */
+ i.tm.base_opcode |= i.op[op].regs->reg_num;
+ if ((i.op[op].regs->reg_flags & RegRex) != 0)
+ i.rex |= REX_B;
+ if (!quiet_warnings && i.tm.opcode_modifier.ugh)
+ {
+ /* Warn about some common errors, but press on regardless.
+ The first case can be generated by gcc (<= 2.8.1). */
+ if (i.operands == 2)
+ {
+ /* Reversed arguments on faddp, fsubp, etc. */
+ as_warn (_("translating to `%s %s%s,%s%s'"), i.tm.name,
+ register_prefix, i.op[!intel_syntax].regs->reg_name,
+ register_prefix, i.op[intel_syntax].regs->reg_name);
+ }
+ else
+ {
+ /* Extraneous `l' suffix on fp insn. */
+ as_warn (_("translating to `%s %s%s'"), i.tm.name,
+ register_prefix, i.op[0].regs->reg_name);
+ }
+ }
+ }
if (i.tm.base_opcode == 0x8d /* lea */
&& i.seg[0]