From: Jan Beulich Date: Fri, 31 Jan 2025 09:05:36 +0000 (+0100) Subject: x86: RMPUPDATE wants operands in different form X-Git-Tag: binutils-2_45~1782 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4612bba098b1099b52a3285b06e708f1ab6ca8ab;p=thirdparty%2Fbinutils-gdb.git x86: RMPUPDATE wants operands in different form AMD are about to update their doc, to help clarify that what we currently do isn't quite right: In particular it is not %rax but %rcx which is affected by address size. In fact, that's a normal memory operand, just not expressed via ModR/M byte, but fixed to (%rcx) (or (%ecx) with 32-bit addressing). To support this in the assembler, generalize memory operand handling so far specific to XLAT (which isn't really a string insn, but requires its memory operand to be (%bx) / (%ebx) / (%rbx)). In the disassembler mimic handling after XLAT's, too. --- diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index ad1c789a933..8bc67538ebe 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -6999,10 +6999,10 @@ i386_assemble (char *line) /* All Intel opcodes have reversed operands except for "bound", "enter", "invlpg*", "monitor*", "mwait*", "tpause", "umwait", "pvalidate", - "rmpadjust", "rmpupdate", and "rmpquery". We also don't reverse - intersegment "jmp" and "call" instructions with 2 immediate operands so - that the immediate segment precedes the offset consistently in Intel and - AT&T modes. */ + "rmpadjust", "rmpquery", and deprecated forms of "rmpupdate". + We also don't reverse intersegment "jmp" and "call" instructions with + 2 immediate operands so that the immediate segment precedes the offset + consistently in Intel and AT&T modes. */ if (intel_syntax && i.operands > 1 && (t->mnem_off != MN_bound) @@ -7010,7 +7010,7 @@ i386_assemble (char *line) && !startswith (mnemonic, "monitor") && !startswith (mnemonic, "mwait") && (t->mnem_off != MN_pvalidate) - && !startswith (mnemonic, "rmp") + && (!startswith (mnemonic, "rmp") || i.mem_operands) && (t->mnem_off != MN_tpause) && (t->mnem_off != MN_umwait) && !(i.operands == 2 @@ -14874,7 +14874,7 @@ i386_index_check (const char *operand_string) if (t->opcode_modifier.isstring) { /* Memory operands of string insns are special in that they only allow - a single register (rDI, rSI, or rBX) as their memory address. */ + a single register (rDI or rSI) as their memory address. */ const reg_entry *expected_reg; static const char di_si[][2][4] = { @@ -14882,7 +14882,14 @@ i386_index_check (const char *operand_string) { "si", "di" }, { "rsi", "rdi" } }; - static const char bx[][4] = { "ebx", "bx", "rbx" }; + /* For a few other insns with fixed register addressing we (ab)use the + IsString attribute as well. */ + static const char loregs[][4][4] = + { + { "eax", "ecx", "edx", "ebx" }, + { "ax", "cx", "dx", "bx" }, + { "rax", "rcx", "rdx", "rbx" } + }; kind = "string address"; @@ -14900,8 +14907,16 @@ i386_index_check (const char *operand_string) di_si[addr_mode][op == es_op]); } else - expected_reg - = (const reg_entry *)str_hash_find (reg_hash, bx[addr_mode]); + { + unsigned int op = t->operand_types[0].bitfield.baseindex ? 0 : 1; + + if (!t->operand_types[op].bitfield.instance) + return 1; /* Operand mismatch will be detected elsewhere. */ + expected_reg + = str_hash_find (reg_hash, + loregs[addr_mode][t->operand_types[op] + .bitfield.instance - 1]); + } if (i.base_reg != expected_reg || i.index_reg diff --git a/gas/testsuite/gas/i386/snp.s b/gas/testsuite/gas/i386/snp.s index 0ac0dfc77a9..51473381661 100644 --- a/gas/testsuite/gas/i386/snp.s +++ b/gas/testsuite/gas/i386/snp.s @@ -11,7 +11,8 @@ att: psmash %eax rmpupdate rmpupdate %rax, %rcx - rmpupdate %eax, %rcx + rmpupdate (%rcx), %rax + rmpupdate (%ecx), %rax rmpadjust rmpadjust %rax, %rcx, %rdx rmpadjust %eax, %rcx, %rdx @@ -30,7 +31,8 @@ intel: psmash eax rmpupdate rmpupdate rax, rcx - rmpupdate eax, rcx + rmpupdate rax, [rcx] + rmpupdate rax, [ecx] rmpadjust rmpadjust rax, rcx, rdx rmpadjust eax, rcx, rdx diff --git a/gas/testsuite/gas/i386/snp64.d b/gas/testsuite/gas/i386/snp64.d index e7ba8c63b2b..810acc2c033 100644 --- a/gas/testsuite/gas/i386/snp64.d +++ b/gas/testsuite/gas/i386/snp64.d @@ -14,9 +14,10 @@ Disassembly of section \.text: [ ]*[a-f0-9]+:[ ]+f3 0f 01 ff[ ]+psmash [ ]*[a-f0-9]+:[ ]+f3 0f 01 ff[ ]+psmash [ ]*[a-f0-9]+:[ ]+67 f3 0f 01 ff[ ]+addr32 psmash -[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate -[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate -[ ]*[a-f0-9]+:[ ]+67 f2 0f 01 fe[ ]+addr32 rmpupdate +[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax +[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax +[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax +[ ]*[a-f0-9]+:[ ]+67 f2 0f 01 fe[ ]+rmpupdate \(%ecx\),%rax [ ]*[a-f0-9]+:[ ]+f3 0f 01 fe[ ]+rmpadjust [ ]*[a-f0-9]+:[ ]+f3 0f 01 fe[ ]+rmpadjust [ ]*[a-f0-9]+:[ ]+67 f3 0f 01 fe[ ]+addr32 rmpadjust @@ -28,9 +29,10 @@ Disassembly of section \.text: [ ]*[a-f0-9]+:[ ]+f3 0f 01 ff[ ]+psmash [ ]*[a-f0-9]+:[ ]+f3 0f 01 ff[ ]+psmash [ ]*[a-f0-9]+:[ ]+67 f3 0f 01 ff[ ]+addr32 psmash -[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate -[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate -[ ]*[a-f0-9]+:[ ]+67 f2 0f 01 fe[ ]+addr32 rmpupdate +[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax +[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax +[ ]*[a-f0-9]+:[ ]+f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax +[ ]*[a-f0-9]+:[ ]+67 f2 0f 01 fe[ ]+rmpupdate \(%ecx\),%rax [ ]*[a-f0-9]+:[ ]+f3 0f 01 fe[ ]+rmpadjust [ ]*[a-f0-9]+:[ ]+f3 0f 01 fe[ ]+rmpadjust [ ]*[a-f0-9]+:[ ]+67 f3 0f 01 fe[ ]+addr32 rmpadjust diff --git a/gas/testsuite/gas/i386/x86-64-arch-4.d b/gas/testsuite/gas/i386/x86-64-arch-4.d index 465b7771c59..3ce96fa45ec 100644 --- a/gas/testsuite/gas/i386/x86-64-arch-4.d +++ b/gas/testsuite/gas/i386/x86-64-arch-4.d @@ -25,7 +25,7 @@ Disassembly of section .text: [ ]*[a-f0-9]+: c4 e2 4d df 39[ ]+vaesdeclast \(%rcx\),%ymm6,%ymm7 [ ]*[a-f0-9]+: f3 0f 01 ff[ ]+psmash [ ]*[a-f0-9]+: f2 0f 01 ff[ ]+pvalidate -[ ]*[a-f0-9]+: f2 0f 01 fe[ ]+rmpupdate +[ ]*[a-f0-9]+: f2 0f 01 fe[ ]+rmpupdate \(%rcx\),%rax [ ]*[a-f0-9]+: f3 0f 01 fe[ ]+rmpadjust [ ]*[a-f0-9]+: 66 0f 38 82 10[ ]+invpcid \(%rax\),%rdx [ ]*[a-f0-9]+: 0f 01 ee[ ]+rdpkru diff --git a/opcodes/i386-dis.c b/opcodes/i386-dis.c index 8059f437d9f..cfc4316fd7d 100644 --- a/opcodes/i386-dis.c +++ b/opcodes/i386-dis.c @@ -524,6 +524,7 @@ fetch_error (const instr_info *ins) #define Xz { OP_DSreg, eSI_reg } #define Yb { OP_ESreg, eDI_reg } #define Yv { OP_ESreg, eDI_reg } +#define DSCX { OP_DSreg, eCX_reg } #define DSBX { OP_DSreg, eBX_reg } #define es { OP_REG, es_reg } @@ -4640,7 +4641,7 @@ static const struct dis386 x86_64_table[][2] = { /* X86_64_0F01_REG_7_MOD_3_RM_6_PREFIX_3 */ { { Bad_Opcode }, - { "rmpupdate", { Skip_MODRM }, 0 }, + { "rmpupdate", { RMrAX, DSCX, Skip_MODRM }, 0 }, }, /* X86_64_0F01_REG_7_MOD_3_RM_7_PREFIX_1 */ @@ -13142,6 +13143,8 @@ OP_DSreg (instr_info *ins, int code, int sizeflag) { switch (ins->codep[-1]) { + case 0x01: /* rmpupdate */ + break; case 0x6f: /* outsw/outsl */ intel_operand_size (ins, z_mode, sizeflag); break; diff --git a/opcodes/i386-opc.tbl b/opcodes/i386-opc.tbl index 06b1a9d8bdf..d75f00bf38b 100644 --- a/opcodes/i386-opc.tbl +++ b/opcodes/i386-opc.tbl @@ -596,7 +596,7 @@ ssto, 0xaa, 0, W|No_sSuf|RepPrefixOk, {} ssto, 0xaa, 0, W|No_sSuf|IsStringEsOp0|RepPrefixOk, { Byte|Word|Dword|Qword|Unspecified|BaseIndex } ssto, 0xaa, 0, W|No_sSuf|IsStringEsOp1|RepPrefixOk, { Acc|Byte|Word|Dword|Qword, Byte|Word|Dword|Qword|Unspecified|BaseIndex } xlat, 0xd7, 0, No_wSuf|No_lSuf|No_sSuf|No_qSuf|IntelSuffix, {} -xlat, 0xd7, 0, No_wSuf|No_lSuf|No_sSuf|No_qSuf|IsString|IntelSuffix, { Byte|Unspecified|BaseIndex } +xlat, 0xd7, 0, No_wSuf|No_lSuf|No_sSuf|No_qSuf|IsString|IntelSuffix, { RegB|Byte|Unspecified|BaseIndex } // Bit manipulation. bsf, 0xfbc, i386, Modrm|CheckOperandSize|No_bSuf|No_sSuf|RepPrefixOk, { Reg16|Reg32|Reg64|Unspecified|BaseIndex, Reg16|Reg32|Reg64 } @@ -3159,6 +3159,7 @@ psmash, 0xf30f01ff, SNP&x64, NoSuf, {} psmash, 0xf30f01ff, SNP&x64, AddrPrefixOpReg|NoSuf, { Acc|Dword|Qword } pvalidate, 0xf20f01ff, SNP, NoSuf, {} pvalidate, 0xf20f01ff, SNP, AddrPrefixOpReg|NoSuf, { Acc|Word|Dword|Qword, RegC|Dword, RegD|Dword } +// These two forms exist only for compatibility with older gas. rmpupdate, 0xf20f01fe, SNP&x64, NoSuf, {} rmpupdate, 0xf20f01fe, SNP&x64, AddrPrefixOpReg|NoSuf, { Acc|Dword|Qword, RegC|Qword } rmpadjust, 0xf30f01fe, SNP&x64, NoSuf, {} @@ -3168,6 +3169,9 @@ pvalidate, 0xf20f01ff, SNP, AddrPrefixOpReg|NoSuf, { Acc|Word|Dword|Qword } rmpupdate, 0xf20f01fe, SNP&x64, AddrPrefixOpReg|NoSuf, { Acc|Dword|Qword } rmpadjust, 0xf30f01fe, SNP&x64, AddrPrefixOpReg|NoSuf, { Acc|Dword|Qword } +// This must come last, for its IsString attribute to take effect. +rmpupdate, 0xf20f01fe, SNP&x64, IsString|NoSuf|NoRex64, { RegC|Unspecified|BaseIndex, Acc|Qword } + // SNP instructions end // RMPQUERY instruction diff --git a/opcodes/i386-tbl.h b/opcodes/i386-tbl.h index b81864f87c1..85908621d4b 100644 --- a/opcodes/i386-tbl.h +++ b/opcodes/i386-tbl.h @@ -6528,7 +6528,7 @@ static const insn_template i386_optab[] = 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, 0, 0, 0, 0, 0, 0, 0 } }, - { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, + { { { 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 } } } }, { MN_bsf, 0xbc, 2, SPACE_0F, None, { 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, @@ -42890,6 +42890,16 @@ static const insn_template i386_optab[] = { { 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, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0 } } } }, + { MN_rmpupdate, 0x01fe, 2, SPACE_0F, None, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0 }, + { { 143, 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, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0 } }, + { { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0 } } } }, { MN_rmpadjust, 0x01fe, 0, SPACE_0F, None, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -48111,54 +48121,54 @@ static const i386_op_off_t i386_op_sets[] = 4040, 4041, 4042, 4043, 4045, 4047, 4048, 4050, 4052, 4053, 4058, 4060, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4071, 4073, 4074, 4075, - 4076, 4078, 4081, 4084, 4087, 4089, 4090, 4091, - 4092, 4093, 4094, 4095, 4096, 4097, 4098, 4099, - 4100, 4101, 4102, 4103, 4104, 4105, 4106, 4107, - 4108, 4109, 4110, 4111, 4112, 4113, 4114, 4115, - 4116, 4117, 4118, 4119, 4120, 4121, 4122, 4123, - 4124, 4125, 4126, 4127, 4128, 4129, 4130, 4131, - 4133, 4135, 4137, 4139, 4141, 4143, 4144, 4145, - 4146, 4147, 4148, 4149, 4150, 4151, 4152, 4153, - 4154, 4155, 4156, 4157, 4158, 4159, 4160, 4161, - 4162, 4163, 4164, 4165, 4166, 4167, 4168, 4169, - 4170, 4171, 4172, 4173, 4174, 4175, 4176, 4177, - 4178, 4179, 4180, 4181, 4182, 4183, 4184, 4185, - 4186, 4187, 4188, 4189, 4190, 4191, 4192, 4193, - 4194, 4195, 4196, 4197, 4198, 4199, 4200, 4201, - 4202, 4203, 4204, 4205, 4206, 4207, 4208, 4209, - 4210, 4211, 4212, 4213, 4214, 4215, 4216, 4217, - 4218, 4219, 4220, 4221, 4222, 4223, 4224, 4225, - 4226, 4227, 4228, 4229, 4230, 4231, 4232, 4233, - 4234, 4235, 4236, 4237, 4238, 4239, 4240, 4241, - 4242, 4243, 4244, 4245, 4246, 4247, 4248, 4249, - 4250, 4251, 4252, 4253, 4254, 4255, 4256, 4257, - 4258, 4259, 4260, 4261, 4262, 4263, 4264, 4265, - 4266, 4269, 4270, 4271, 4274, 4275, 4276, 4278, - 4279, 4280, 4281, 4283, 4284, 4285, 4286, 4288, - 4289, 4290, 4291, 4294, 4295, 4296, 4297, 4298, - 4301, 4304, 4307, 4310, 4313, 4314, 4315, 4316, - 4317, 4319, 4321, 4322, 4323, 4324, 4327, 4330, - 4333, 4336, 4339, 4340, 4341, 4342, 4344, 4345, - 4346, 4347, 4350, 4351, 4352, 4353, 4354, 4355, - 4356, 4357, 4358, 4359, 4360, 4361, 4362, 4363, - 4364, 4365, 4366, 4367, 4368, 4369, 4370, 4371, - 4372, 4373, 4374, 4375, 4376, 4377, 4378, 4379, - 4380, 4381, 4382, 4383, 4384, 4385, 4386, 4388, - 4389, 4390, 4392, 4394, 4396, 4398, 4400, 4401, - 4402, 4405, 4408, 4409, 4410, 4411, 4412, 4413, - 4414, 4416, 4418, 4420, 4422, 4423, 4424, 4425, - 4426, 4429, 4430, 4431, 4434, 4435, 4436, 4439, - 4440, 4441, 4444, 4445, 4446, 4449, 4450, 4451, - 4452, 4453, 4454, 4455, 4456, 4457, 4458, 4459, - 4460, 4461, 4462, 4463, 4464, 4465, 4466, 4467, - 4468, 4469, 4470, 4471, 4472, 4473, 4474, 4475, - 4476, 4477, 4478, 4479, 4480, 4481, 4482, 4483, - 4484, 4485, 4486, 4487, 4488, 4489, 4490, 4491, - 4492, 4493, 4496, 4497, 4498, 4501, 4502, 4503, - 4504, 4505, 4506, 4507, 4510, 4513, 4514, 4515, - 4516, 4517, 4518, 4519, 4520, 4521, 4522, 4523, - 4524, 4525, 4526, 4527, 4528, 4529, 4530, 4531, - 4533, 4534, 4535, 4536, 4537 + 4076, 4078, 4081, 4085, 4088, 4090, 4091, 4092, + 4093, 4094, 4095, 4096, 4097, 4098, 4099, 4100, + 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, + 4109, 4110, 4111, 4112, 4113, 4114, 4115, 4116, + 4117, 4118, 4119, 4120, 4121, 4122, 4123, 4124, + 4125, 4126, 4127, 4128, 4129, 4130, 4131, 4132, + 4134, 4136, 4138, 4140, 4142, 4144, 4145, 4146, + 4147, 4148, 4149, 4150, 4151, 4152, 4153, 4154, + 4155, 4156, 4157, 4158, 4159, 4160, 4161, 4162, + 4163, 4164, 4165, 4166, 4167, 4168, 4169, 4170, + 4171, 4172, 4173, 4174, 4175, 4176, 4177, 4178, + 4179, 4180, 4181, 4182, 4183, 4184, 4185, 4186, + 4187, 4188, 4189, 4190, 4191, 4192, 4193, 4194, + 4195, 4196, 4197, 4198, 4199, 4200, 4201, 4202, + 4203, 4204, 4205, 4206, 4207, 4208, 4209, 4210, + 4211, 4212, 4213, 4214, 4215, 4216, 4217, 4218, + 4219, 4220, 4221, 4222, 4223, 4224, 4225, 4226, + 4227, 4228, 4229, 4230, 4231, 4232, 4233, 4234, + 4235, 4236, 4237, 4238, 4239, 4240, 4241, 4242, + 4243, 4244, 4245, 4246, 4247, 4248, 4249, 4250, + 4251, 4252, 4253, 4254, 4255, 4256, 4257, 4258, + 4259, 4260, 4261, 4262, 4263, 4264, 4265, 4266, + 4267, 4270, 4271, 4272, 4275, 4276, 4277, 4279, + 4280, 4281, 4282, 4284, 4285, 4286, 4287, 4289, + 4290, 4291, 4292, 4295, 4296, 4297, 4298, 4299, + 4302, 4305, 4308, 4311, 4314, 4315, 4316, 4317, + 4318, 4320, 4322, 4323, 4324, 4325, 4328, 4331, + 4334, 4337, 4340, 4341, 4342, 4343, 4345, 4346, + 4347, 4348, 4351, 4352, 4353, 4354, 4355, 4356, + 4357, 4358, 4359, 4360, 4361, 4362, 4363, 4364, + 4365, 4366, 4367, 4368, 4369, 4370, 4371, 4372, + 4373, 4374, 4375, 4376, 4377, 4378, 4379, 4380, + 4381, 4382, 4383, 4384, 4385, 4386, 4387, 4389, + 4390, 4391, 4393, 4395, 4397, 4399, 4401, 4402, + 4403, 4406, 4409, 4410, 4411, 4412, 4413, 4414, + 4415, 4417, 4419, 4421, 4423, 4424, 4425, 4426, + 4427, 4430, 4431, 4432, 4435, 4436, 4437, 4440, + 4441, 4442, 4445, 4446, 4447, 4450, 4451, 4452, + 4453, 4454, 4455, 4456, 4457, 4458, 4459, 4460, + 4461, 4462, 4463, 4464, 4465, 4466, 4467, 4468, + 4469, 4470, 4471, 4472, 4473, 4474, 4475, 4476, + 4477, 4478, 4479, 4480, 4481, 4482, 4483, 4484, + 4485, 4486, 4487, 4488, 4489, 4490, 4491, 4492, + 4493, 4494, 4497, 4498, 4499, 4502, 4503, 4504, + 4505, 4506, 4507, 4508, 4511, 4514, 4515, 4516, + 4517, 4518, 4519, 4520, 4521, 4522, 4523, 4524, + 4525, 4526, 4527, 4528, 4529, 4530, 4531, 4532, + 4534, 4535, 4536, 4537, 4538 }; /* i386 mnemonics table. */