From e7d74879870833fb0c42282da940e60fee13948e Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 9 Nov 2023 12:55:52 +0100 Subject: [PATCH] x86: rework UWRMSR operand swapping As indicated during review already, doing the swapping early is overall cheaper than doing it only after operand matching. --- gas/config/tc-i386.c | 23 ++++++++--------------- opcodes/i386-opc.tbl | 4 +++- opcodes/i386-tbl.h | 4 ++-- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index a351897c794..235e41e7918 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -5188,10 +5188,14 @@ md_assemble (char *line) && operand_type_check (i.types[1], imm))) swap_operands (); - /* The order of the immediates should be reversed - for 2 immediates extrq and insertq instructions */ - if (i.imm_operands == 2 - && (t->mnem_off == MN_extrq || t->mnem_off == MN_insertq)) + /* The order of the immediates should be reversed for 2-immediates EXTRQ + and INSERTQ instructions. Also UWRMSR wants its immediate to be in the + "canonical" place (first), despite it appearing last (in AT&T syntax, or + because of the swapping above) in the incoming set of operands. */ + if ((i.imm_operands == 2 + && (t->mnem_off == MN_extrq || t->mnem_off == MN_insertq)) + || (t->mnem_off == MN_uwrmsr && i.imm_operands + && i.operands > i.imm_operands)) swap_2_operands (0, 1); if (i.imm_operands) @@ -7544,17 +7548,6 @@ match_template (char mnem_suffix) break; } - /* This pattern aims to put the unusually placed imm operand to a usual - place. The constraints are currently only adapted to uwrmsr, and may - need further tweaking when new similar instructions become available. */ - if (i.imm_operands && i.imm_operands < i.operands - && operand_type_check (operand_types[i.operands - 1], imm)) - { - i.tm.operand_types[0] = operand_types[i.operands - 1]; - i.tm.operand_types[i.operands - 1] = operand_types[0]; - swap_2_operands(0, i.operands - 1); - } - return t; } diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 7020ca10488..c31bf20f2e6 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -3356,6 +3356,8 @@ eretu, 0xf30f01ca, FRED, NoSuf, {} urdmsr, 0xf20f38f8, USER_MSR, RegMem|NoSuf|NoRex64, { Reg64, Reg64 } urdmsr, 0xf2f8/0, USER_MSR, Modrm|Vex128|VexMap7|VexW0|NoSuf, { Imm32, Reg64 } uwrmsr, 0xf30f38f8, USER_MSR, Modrm|NoSuf|NoRex64, { Reg64, Reg64 } -uwrmsr, 0xf3f8/0, USER_MSR, Modrm|Vex128|VexMap7|VexW0|NoSuf, { Reg64, Imm32 } +// Immediates want to be first; md_assemble() takes care of swapping operands +// accordingly. +uwrmsr, 0xf3f8/0, USER_MSR, Modrm|Vex128|VexMap7|VexW0|NoSuf, { Imm32, Reg64 } // USER_MSR instructions end. diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index 5117bda3209..527793c5bf6 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -39668,9 +39668,9 @@ static const insn_template i386_optab[] = 0 }, { { 98, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + { { { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, - { { 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + { { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } } } }, }; -- 2.30.2