aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2019-07-16 09:31:36 +0200
committerJan Beulich <jbeulich@suse.com>2019-07-16 09:31:36 +0200
commitdfd6917457a3030ea4a4b6356f65216fab92d0b8 (patch)
tree564ff316e799585e35f21a1cec2393a4d5d11e4d /gas
parent21df382b918888de64749e977f185c4e10a5b838 (diff)
downloadgdb-dfd6917457a3030ea4a4b6356f65216fab92d0b8.zip
gdb-dfd6917457a3030ea4a4b6356f65216fab92d0b8.tar.gz
gdb-dfd6917457a3030ea4a4b6356f65216fab92d0b8.tar.bz2
x86: make RegMem an opcode modifier
... instead of an operand type bit: It's an insn property, not an operand one. There's just one actual change to be made to the templates: Most are now required to have the (unswapped) destination go into ModR/M.rm, so VMOVD template needs its opcode adjusted accordingly and its operands swapped. {,V}MOVS{S,D}, otoh, are left alone in this regard, as otherwise generated code would differ from what we've been producing so far (which I don't think is wanted). Take the opportunity and add a missing IgnoreSize to pextrb (leading to an error in 16-bit mode), and take the liberty to once again drop stray IgnoreSize attributes from lines changed and neighboring related ones.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-i386.c30
2 files changed, 25 insertions, 12 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index bdff6e4..7219193 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,12 @@
2019-07-16 Jan Beulich <jbeulich@suse.com>
+ * config/tc-i386.c (match_template): Adjust regmem reference.
+ Adjust comment and update regmem when swapping operands.
+ (build_modrm_byte): Drop clearing of regmem and stale part of
+ comment. Correct comment. Adjust regmem reference.
+
+2019-07-16 Jan Beulich <jbeulich@suse.com>
+
* config/tc-i386.c (type_names): Replace SReg entries.
(pi, check_byte_reg, build_modrm_byte, i386_att_operand,
parse_real_register): Switch to using sreg field.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 1f2b298..75fa870 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -5911,13 +5911,13 @@ match_template (char mnem_suffix)
{
case dir_encoding_load:
if (operand_type_check (operand_types[i.operands - 1], anymem)
- || operand_types[i.operands - 1].bitfield.regmem)
+ || t->opcode_modifier.regmem)
goto check_reverse;
break;
case dir_encoding_store:
if (!operand_type_check (operand_types[i.operands - 1], anymem)
- && !operand_types[i.operands - 1].bitfield.regmem)
+ && !t->opcode_modifier.regmem)
goto check_reverse;
break;
@@ -6167,14 +6167,22 @@ check_reverse:
if (found_reverse_match)
{
- /* If we found a reverse match we must alter the opcode
- direction bit. found_reverse_match holds bits to change
- (different for int & float insns). */
+ /* If we found a reverse match we must alter the opcode direction
+ bit and clear/flip the regmem modifier one. found_reverse_match
+ holds bits to change (different for int & float insns). */
i.tm.base_opcode ^= found_reverse_match;
i.tm.operand_types[0] = operand_types[i.operands - 1];
i.tm.operand_types[i.operands - 1] = operand_types[0];
+
+ /* Certain SIMD insns have their load forms specified in the opcode
+ table, and hence we need to _set_ RegMem instead of clearing it.
+ We need to avoid setting the bit though on insns like KMOVW. */
+ i.tm.opcode_modifier.regmem
+ = i.tm.opcode_modifier.modrm && i.tm.opcode_modifier.d
+ && i.tm.operands > 2U - i.tm.opcode_modifier.sse2avx
+ && !i.tm.opcode_modifier.regmem;
}
return t;
@@ -7255,8 +7263,7 @@ build_modrm_byte (void)
{
/* For instructions with VexNDS, the register-only source
operand must be a 32/64bit integer, XMM, YMM, ZMM, or mask
- register. It is encoded in VEX prefix. We need to
- clear RegMem bit before calling operand_type_equal. */
+ register. It is encoded in VEX prefix. */
i386_operand_type op;
unsigned int vvvv;
@@ -7273,7 +7280,6 @@ build_modrm_byte (void)
vvvv = dest;
op = i.tm.operand_types[vvvv];
- op.bitfield.regmem = 0;
if ((dest + 1) >= i.operands
|| ((!op.bitfield.reg
|| (!op.bitfield.dword && !op.bitfield.qword))
@@ -7286,13 +7292,13 @@ build_modrm_byte (void)
}
i.rm.mode = 3;
- /* One of the register operands will be encoded in the i.tm.reg
- field, the other in the combined i.tm.mode and i.tm.regmem
+ /* One of the register operands will be encoded in the i.rm.reg
+ field, the other in the combined i.rm.mode and i.rm.regmem
fields. If no form of this instruction supports a memory
destination operand, then we assume the source operand may
sometimes be a memory operand and so we need to store the
destination in the i.rm.reg field. */
- if (!i.tm.operand_types[dest].bitfield.regmem
+ if (!i.tm.opcode_modifier.regmem
&& operand_type_check (i.tm.operand_types[dest], anymem) == 0)
{
i.rm.reg = i.op[dest].regs->reg_num;
@@ -7336,7 +7342,7 @@ build_modrm_byte (void)
}
if (flag_code != CODE_64BIT && (i.rex & REX_R))
{
- if (!i.types[i.tm.operand_types[0].bitfield.regmem].bitfield.control)
+ if (!i.types[!i.tm.opcode_modifier.regmem].bitfield.control)
abort ();
i.rex &= ~REX_R;
add_prefix (LOCK_PREFIX_OPCODE);