mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-03-07 13:39:43 +08:00
x86/APX: correct .insn opcode space determination when REX2 is needed
In this case spaces 0f38 and 0f3a may not be put in place. To achieve the intended effect, operand parsing (but not operand processing) needs pulling ahead, so we know whether eGRP-s are in use.
This commit is contained in:
parent
eb3f3841da
commit
6804f42c67
@ -12922,46 +12922,9 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
|
||||
}
|
||||
}
|
||||
|
||||
/* Trim off encoding space. */
|
||||
if (j > 1 && !i.insn_opcode_space && (val >> ((j - 1) * 8)) == 0x0f)
|
||||
{
|
||||
uint8_t byte = val >> ((--j - 1) * 8);
|
||||
|
||||
i.insn_opcode_space = SPACE_0F;
|
||||
switch (byte & -(j > 1))
|
||||
{
|
||||
case 0x38:
|
||||
i.insn_opcode_space = SPACE_0F38;
|
||||
--j;
|
||||
break;
|
||||
case 0x3a:
|
||||
i.insn_opcode_space = SPACE_0F3A;
|
||||
--j;
|
||||
break;
|
||||
}
|
||||
i.tm.opcode_space = i.insn_opcode_space;
|
||||
val &= ((uint64_t)1 << (j * 8)) - 1;
|
||||
}
|
||||
if (!i.tm.opcode_space && (vex || evex))
|
||||
/* Arrange for build_vex_prefix() to properly emit 0xC4/0xC5.
|
||||
Also avoid hitting abort() there or in build_evex_prefix(). */
|
||||
i.tm.opcode_space = i.insn_opcode_space == SPACE_0F ? SPACE_0F
|
||||
: SPACE_0F38;
|
||||
|
||||
if (j > 2)
|
||||
{
|
||||
as_bad (_("opcode residual (%#"PRIx64") too wide"), (uint64_t) val);
|
||||
goto bad;
|
||||
}
|
||||
i.opcode_length = j;
|
||||
|
||||
/* Handle operands, if any. */
|
||||
/* Parse operands, if any, before evaluating encoding space. */
|
||||
if (*line == ',')
|
||||
{
|
||||
i386_operand_type combined;
|
||||
expressionS *disp_exp = NULL;
|
||||
bool changed;
|
||||
|
||||
i.memshift = -1;
|
||||
|
||||
ptr = parse_operands (line + 1, &i386_mnemonics[MN__insn]);
|
||||
@ -12986,6 +12949,48 @@ s_insn (int dummy ATTRIBUTE_UNUSED)
|
||||
/* No need to distinguish encoding_evex and encoding_evex512. */
|
||||
if (i.encoding == encoding_evex512)
|
||||
i.encoding = encoding_evex;
|
||||
}
|
||||
|
||||
/* Trim off encoding space. */
|
||||
if (j > 1 && !i.insn_opcode_space && (val >> ((j - 1) * 8)) == 0x0f)
|
||||
{
|
||||
uint8_t byte = val >> ((--j - 1) * 8);
|
||||
|
||||
i.insn_opcode_space = SPACE_0F;
|
||||
switch (byte & -(j > 1 && !i.rex2_encoding
|
||||
&& (i.encoding != encoding_egpr || evex)))
|
||||
{
|
||||
case 0x38:
|
||||
i.insn_opcode_space = SPACE_0F38;
|
||||
--j;
|
||||
break;
|
||||
case 0x3a:
|
||||
i.insn_opcode_space = SPACE_0F3A;
|
||||
--j;
|
||||
break;
|
||||
}
|
||||
i.tm.opcode_space = i.insn_opcode_space;
|
||||
val &= ((uint64_t)1 << (j * 8)) - 1;
|
||||
}
|
||||
if (!i.tm.opcode_space && (vex || evex))
|
||||
/* Arrange for build_vex_prefix() to properly emit 0xC4/0xC5.
|
||||
Also avoid hitting abort() there or in build_evex_prefix(). */
|
||||
i.tm.opcode_space = i.insn_opcode_space == SPACE_0F ? SPACE_0F
|
||||
: SPACE_0F38;
|
||||
|
||||
if (j > 2)
|
||||
{
|
||||
as_bad (_("opcode residual (%#"PRIx64") too wide"), (uint64_t) val);
|
||||
goto done;
|
||||
}
|
||||
i.opcode_length = j;
|
||||
|
||||
/* Handle operands, if any. */
|
||||
if (i.operands)
|
||||
{
|
||||
i386_operand_type combined;
|
||||
expressionS *disp_exp = NULL;
|
||||
bool changed;
|
||||
|
||||
if (i.encoding == encoding_egpr)
|
||||
{
|
||||
|
38
gas/testsuite/gas/i386/insn-rex2.l
Normal file
38
gas/testsuite/gas/i386/insn-rex2.l
Normal file
@ -0,0 +1,38 @@
|
||||
[ ]*[0-9]+[ ]+\.text
|
||||
[ ]*[0-9]+[ ]+insn_rex2:
|
||||
[ ]*[0-9]+ .... D58001C0[ ]+\.insn \{rex2\} 0x0f01/0, %eax
|
||||
[ ]*[0-9]+ .... D58038C0[ ]+\.insn \{rex2\} 0x0f38/0, %eax
|
||||
[ ]*[0-9]+ .... D5803801[ ]+\.insn \{rex2\} 0x0f3801/0, %eax
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5803901[ ]+\.insn \{rex2\} 0x0f3901/0, %eax
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5803A01[ ]+\.insn \{rex2\} 0x0f3a01/0, \$0xCC, %eax
|
||||
[ ]*[0-9]+ +C0CC
|
||||
[ ]*[0-9]+[ ]+
|
||||
[ ]*[0-9]+ .... D58801C0[ ]+\.insn \{rex2\} 0x0f01/0, %rax
|
||||
[ ]*[0-9]+ .... D58838C0[ ]+\.insn \{rex2\} 0x0f38/0, %rax
|
||||
[ ]*[0-9]+ .... D5883801[ ]+\.insn \{rex2\} 0x0f3801/0, %rax
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5883901[ ]+\.insn \{rex2\} 0x0f3901/0, %rax
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5883A01[ ]+\.insn \{rex2\} 0x0f3a01/0, \$0xCC, %rax
|
||||
[ ]*[0-9]+ +C0CC
|
||||
[ ]*[0-9]+[ ]+
|
||||
[ ]*[0-9]+ .... D58901C0[ ]+\.insn \{rex2\} 0x0f01/0, %r8
|
||||
[ ]*[0-9]+ .... D58938C0[ ]+\.insn \{rex2\} 0x0f38/0, %r8
|
||||
[ ]*[0-9]+ .... D5893801[ ]+\.insn \{rex2\} 0x0f3801/0, %r8
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5893901[ ]+\.insn \{rex2\} 0x0f3901/0, %r8
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5893A01[ ]+\.insn \{rex2\} 0x0f3a01/0, \$0xCC, %r8
|
||||
[ ]*[0-9]+ +C0CC
|
||||
[ ]*[0-9]+[ ]+
|
||||
[ ]*[0-9]+ .... D59801C0[ ]+\.insn 0x0f01/0, %r16
|
||||
[ ]*[0-9]+ .... D59838C0[ ]+\.insn 0x0f38/0, %r16
|
||||
[ ]*[0-9]+ .... D5983801[ ]+\.insn 0x0f3801/0, %r16
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5983901[ ]+\.insn 0x0f3901/0, %r16
|
||||
[ ]*[0-9]+ +C0
|
||||
[ ]*[0-9]+ .... D5983A01[ ]+\.insn 0x0f3a01/0, \$0xCC, %r16
|
||||
[ ]*[0-9]+[ ]+C0CC
|
||||
#pass
|
25
gas/testsuite/gas/i386/insn-rex2.s
Normal file
25
gas/testsuite/gas/i386/insn-rex2.s
Normal file
@ -0,0 +1,25 @@
|
||||
.text
|
||||
insn_rex2:
|
||||
.insn {rex2} 0x0f01/0, %eax
|
||||
.insn {rex2} 0x0f38/0, %eax
|
||||
.insn {rex2} 0x0f3801/0, %eax
|
||||
.insn {rex2} 0x0f3901/0, %eax
|
||||
.insn {rex2} 0x0f3a01/0, $0xCC, %eax
|
||||
|
||||
.insn {rex2} 0x0f01/0, %rax
|
||||
.insn {rex2} 0x0f38/0, %rax
|
||||
.insn {rex2} 0x0f3801/0, %rax
|
||||
.insn {rex2} 0x0f3901/0, %rax
|
||||
.insn {rex2} 0x0f3a01/0, $0xCC, %rax
|
||||
|
||||
.insn {rex2} 0x0f01/0, %r8
|
||||
.insn {rex2} 0x0f38/0, %r8
|
||||
.insn {rex2} 0x0f3801/0, %r8
|
||||
.insn {rex2} 0x0f3901/0, %r8
|
||||
.insn {rex2} 0x0f3a01/0, $0xCC, %r8
|
||||
|
||||
.insn 0x0f01/0, %r16
|
||||
.insn 0x0f38/0, %r16
|
||||
.insn 0x0f3801/0, %r16
|
||||
.insn 0x0f3901/0, %r16
|
||||
.insn 0x0f3a01/0, $0xCC, %r16
|
@ -126,6 +126,7 @@ run_dump_test "x86-64-sysenter-mixed"
|
||||
run_dump_test "x86-64-sysenter-amd"
|
||||
run_list_test "x86-64-sysenter-amd" "-mamd64"
|
||||
run_dump_test "insn-64"
|
||||
run_list_test "insn-rex2" "-aln --divide"
|
||||
run_dump_test "noreg64"
|
||||
run_list_test "noreg64"
|
||||
run_dump_test "noreg64-data16"
|
||||
|
Loading…
Reference in New Issue
Block a user