aboutsummaryrefslogtreecommitdiff
path: root/gas/config
diff options
context:
space:
mode:
authorHu, Lin1 <lin1.hu@intel.com>2023-10-31 16:23:53 +0800
committerHaochen Jiang <haochen.jiang@intel.com>2023-10-31 16:24:41 +0800
commit8170af78e17e1ec8b14b40d3ff4c979ccccb8f44 (patch)
tree9ea06e982f648cd3c3d8848ea913ef8f8d9e815f /gas/config
parent1f9e9ea5b7cd1554db5a5e9da92a6882f1cce40e (diff)
downloadgdb-8170af78e17e1ec8b14b40d3ff4c979ccccb8f44.zip
gdb-8170af78e17e1ec8b14b40d3ff4c979ccccb8f44.tar.gz
gdb-8170af78e17e1ec8b14b40d3ff4c979ccccb8f44.tar.bz2
Support Intel USER_MSR
This patches aims to support Intel USER_MSR. In addition to the usual support, this patch includes encoding and decoding support for MAP7 and immediate numbers as the last operand (ATT style). gas/ChangeLog: * NEWS: Support Intel USER_MSR. * config/tc-i386.c (smallest_imm_type): Reject imm32 in 64bit mode. (build_vex_prefix): Add VEXMAP7. (md_assemble): Handling the imm32 of USER_MSR. (match_template): Handling the unusual immediate. * doc/c-i386.texi: Document .user_msr. * testsuite/gas/i386/i386.exp: Run USER_MSR tests. * testsuite/gas/i386/x86-64.exp: Ditto. * testsuite/gas/i386/user_msr-inval.l: New test. * testsuite/gas/i386/user_msr-inval.s: Ditto. * testsuite/gas/i386/x86-64-user_msr-intel.d: Ditto. * testsuite/gas/i386/x86-64-user_msr-inval.l: Ditto. * testsuite/gas/i386/x86-64-user_msr-inval.s: Ditto. * testsuite/gas/i386/x86-64-user_msr.d: Ditto. * testsuite/gas/i386/x86-64-user_msr.s: Ditto. opcodes/ChangeLog: * i386-dis.c (struct instr_info): Add a new attribute has_skipped_modrm. (Gq): New. (Rq): Ditto. (q_mm_mode): Ditto. (Nq): Change mode from q_mode to q_mm_mode. (VEX_LEN_TABLE): (get_valid_dis386): Add VEX_MAP7 in VEX prefix. and handle the map7_f8 for save space. (OP_Skip_MODRM): Set has_skipped_modrm. (OP_E): Skip codep++ when has skipped modrm byte. (OP_R): Support q_mode and q_mm_mode. (REG_VEX_MAP7_F8_L_0_W_0): New. (PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64): Ditto. (X86_64_VEX_MAP7_F8_L_0_W_0_R_0): Ditto. (VEX_LEN_MAP7_F8): Ditto. (VEX_W_MAP7_F8_L_0): Ditto. (MOD_0F38F8): Ditto. (PREFIX_0F38F8_M_0): Ditto. (PREFIX_0F38F8_M_1_X86_64): Ditto. (X86_64_0F38F8_M_1): Ditto. (PREFIX_0F38F8): Remove. (prefix_table): Add PREFIX_0F38F8_M_1_X86_64. Remove PREFIX_0F38F8. (reg_table): Add REG_VEX_MAP7_F8_L_0_W_0, PREFIX_VEX_MAP7_F8_L_0_W_0_R_0_X86_64. (x86_64_table): Add X86_64_0F38F8_PREFIX_3_M_1, X86_64_VEX_MAP7_F8_L_0_W_0_R_0 and X86_64_0F38F8_M_1. (vex_table): Add VEX_MAP7. (vex_len_table): Add VEX_LEN_MAP7_F8, VEX_W_MAP7_F8_L_0. (mod_table): New entry for USER_MSR and add MOD_0F38F8. * i386-gen.c (cpu_flag_init): Add CPU_USER_MSR_FLAGS and CPU_ANY_USER_MSR_FLAGS. Add add VEXMAP7. * i386-init.h: Regenerated. * i386-mnem.h: Ditto. * i386-opc.h (SPACE_VEXMAP7): New. (CPU_USER_MSR_FLAGS): Ditoo. (CPU_ANY_USER_MSR_FLAGS): Ditto. (i386_cpu_flags): Add cpuuser_msr. * i386-opc.tbl: Add USER_MSR instructions. * i386-tbl.h: Regenerated.
Diffstat (limited to 'gas/config')
-rw-r--r--gas/config/tc-i386.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 57ae6c5..c7b9a95 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -1157,6 +1157,7 @@ static const arch_entry cpu_arch[] =
VECARCH (sm4, SM4, ANY_SM4, reset),
SUBARCH (pbndkb, PBNDKB, PBNDKB, false),
VECARCH (avx10.1, AVX10_1, ANY_AVX512F, set),
+ SUBARCH (user_msr, USER_MSR, USER_MSR, false),
};
#undef SUBARCH
@@ -2474,7 +2475,8 @@ smallest_imm_type (offsetT num)
t.bitfield.imm8 = 1;
t.bitfield.imm8s = 1;
t.bitfield.imm16 = 1;
- t.bitfield.imm32 = 1;
+ if (flag_code != CODE_64BIT || fits_in_unsigned_long (num))
+ t.bitfield.imm32 = 1;
t.bitfield.imm32s = 1;
}
else if (fits_in_unsigned_byte (num))
@@ -2487,12 +2489,14 @@ smallest_imm_type (offsetT num)
else if (fits_in_signed_word (num) || fits_in_unsigned_word (num))
{
t.bitfield.imm16 = 1;
- t.bitfield.imm32 = 1;
+ if (flag_code != CODE_64BIT || fits_in_unsigned_long (num))
+ t.bitfield.imm32 = 1;
t.bitfield.imm32s = 1;
}
else if (fits_in_signed_long (num))
{
- t.bitfield.imm32 = 1;
+ if (flag_code != CODE_64BIT || fits_in_unsigned_long (num))
+ t.bitfield.imm32 = 1;
t.bitfield.imm32s = 1;
}
else if (fits_in_unsigned_long (num))
@@ -3833,6 +3837,7 @@ build_vex_prefix (const insn_template *t)
case SPACE_0F:
case SPACE_0F38:
case SPACE_0F3A:
+ case SPACE_VEXMAP7:
i.vex.bytes[0] = 0xc4;
break;
case SPACE_XOP08:
@@ -5203,7 +5208,23 @@ md_assemble (char *line)
swap_2_operands (0, 1);
if (i.imm_operands)
- optimize_imm ();
+ {
+ /* For USER_MSR instructions, imm32 stands for the name of an model specific
+ register (MSR). That's an unsigned quantity, whereas all other insns with
+ 32-bit immediate and 64-bit operand size use sign-extended
+ immediates (imm32s). Therefore these insns are special-cased, bypassing
+ the normal handling of immediates here. */
+ if (is_cpu(current_templates->start, CpuUSER_MSR))
+ {
+ for (j = 0; j < i.operands; j++)
+ {
+ if (operand_type_check(i.types[j], imm))
+ i.types[j] = smallest_imm_type (i.op[j].imms->X_add_number);
+ }
+ }
+ else
+ optimize_imm ();
+ }
if (i.disp_operands && !optimize_disp (t))
return;
@@ -7536,6 +7557,17 @@ 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;
}