From 85b80b0f9bf628971b1a051d8b89c0caa932e734 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 4 Nov 2019 15:48:38 +0100 Subject: [PATCH] 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. --- gas/ChangeLog | 5 ++ gas/config/tc-i386.c | 106 ++++++++++++++++++++----------------------- 2 files changed, 54 insertions(+), 57 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index fc99adce7f..185469fbfa 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,8 @@ +2019-11-04 Jan Beulich + + * config/tc-i386.c (process_operands): Handle ShortForm insns + later, splitting out their segment register sub-form. + 2019-10-31 H.J. Lu * testsuite/gas/i386/general.s: Add .code16gcc fldenv tests. diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index f26b17c956..5866bd618e 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]