[PATCH 2/2] x86/APX: support JMPABS also in assembler
H.J. Lu
hjl.tools@gmail.com
Tue Oct 8 21:00:40 GMT 2024
On Tue, Oct 8, 2024 at 6:26 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> Without this APX support isn't really complete.
>
> Since which operand type to expect in source is ambiguous, permit both
> immediate and displacement forms. Make sure though that in Intel syntax
> truly memory operand forms (<xyz> ptr and/or square-bracketing) aren't
> accepted. Also make sure that no illegal prefixes can be used with the
> insn (LOCK is being dealt with more generally elsewhere).
> ---
> Instead of open-coding the check for JMPABS in establish_rex() we could
> of course also introduce a new "no sizing prefixes" operand constraint.
>
> Because of the similarity with the offset part of directl long/far
> branches, I'm actually inclined to introduce Disp<NN> variants there,
> too. That, when used in source code, would then also make more clear
> which one is which.
>
> --- a/gas/config/tc-i386.c
> +++ b/gas/config/tc-i386.c
> @@ -4673,6 +4673,24 @@ static void establish_rex (void)
>
> if (is_apx_rex2_encoding ())
> {
> + /* Most prefixes are not permitted with JMPABS. */
> + if (i.tm.mnem_off == MN_jmpabs)
> + {
> + if (i.prefix[DATA_PREFIX] || (i.prefix[REX_PREFIX] & REX_W))
> + {
> + as_bad (_("size override not allowed with `%s'"),
> + insn_name (&i.tm));
> + i.prefix[DATA_PREFIX] = 0;
> + i.prefix[REX_PREFIX] &= ~REX_W;
> + }
> + if (i.prefix[ADDR_PREFIX])
> + {
> + as_bad (_("address override not allowed with `%s'"),
> + insn_name (&i.tm));
> + i.prefix[ADDR_PREFIX] = 0;
> + }
> + }
> +
> build_rex2_prefix ();
> /* The individual REX.RXBW bits got consumed. */
> i.rex &= REX_OPCODE;
> @@ -8214,7 +8232,8 @@ optimize_imm (void)
> /* A more generic (but also more involved) way of dealing
> with the special case(s) would be to go look for
> DefaultSize attributes on any of the templates. */
> - && current_templates.start->mnem_off != MN_push))
> + && current_templates.start->mnem_off != MN_push
> + && current_templates.start->mnem_off != MN_jmpabs))
> guess_suffix = LONG_MNEM_SUFFIX;
>
> for (op = i.operands; --op >= 0;)
> @@ -8360,10 +8379,10 @@ optimize_disp (const insn_template *t)
> }
> }
>
> - /* Don't optimize displacement for movabs since it only takes 64bit
> - displacement. */
> + /* Don't optimize displacement for movabs / jmpabs since they only take
> + 64-bit displacement. */
> if (pp.disp_encoding > disp_encoding_8bit
> - || (flag_code == CODE_64BIT && t->mnem_off == MN_movabs))
> + || t->mnem_off == MN_movabs || t->mnem_off == MN_jmpabs)
> return true;
>
> for (op = i.operands; op-- > 0;)
> --- a/gas/config/tc-i386-intel.c
> +++ b/gas/config/tc-i386-intel.c
> @@ -907,7 +907,8 @@ i386_intel_operand (char *operand_string
> /* Operands for jump/call need special consideration. */
> if (current_templates.start->opcode_modifier.jump == JUMP
> || current_templates.start->opcode_modifier.jump == JUMP_DWORD
> - || current_templates.start->opcode_modifier.jump == JUMP_INTERSEGMENT)
> + || current_templates.start->opcode_modifier.jump == JUMP_INTERSEGMENT
> + || current_templates.start->mnem_off == MN_jmpabs)
> {
> bool jumpabsolute = false;
>
> --- a/gas/testsuite/gas/i386/x86-64-apx-jmpabs.d
> +++ b/gas/testsuite/gas/i386/x86-64-apx-jmpabs.d
> @@ -1,5 +1,5 @@
> #as:
> -#objdump: -dw
> +#objdump: -dwr
> #name: x86_64 APX_F JMPABS insns
> #source: x86-64-apx-jmpabs.s
>
> @@ -8,5 +8,16 @@
> Disassembly of section \.text:
>
> 0+ <_start>:
> +\s*[a-f0-9]+:\s*d5 00 a1 00 00 00 00 00 00 00 00[ ]+jmpabs \$0x0\s*[a-f0-9]+: (R_X86_64_|IMAGE_REL_AMD64_ADDR)?64 thunk
> \s*[a-f0-9]+:\s*d5 00 a1 02 00 00 00 00 00 00 00[ ]+jmpabs \$0x2
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 00 00 00 00[ ]+jmpabs \$0x87654321
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 09 00 00 00[ ]+jmpabs \$0x987654321
> +\s*[a-f0-9]+:\s*d5 00 a1 00 00 00 00 00 00 00 00[ ]+jmpabs \$0x0\s*[a-f0-9]+: (R_X86_64_|IMAGE_REL_AMD64_ADDR)?64 thunk
> +\s*[a-f0-9]+:\s*d5 00 a1 78 56 34 12 00 00 00 00[ ]+jmpabs \$0x12345678
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 00 00 00 00[ ]+jmpabs \$0x87654321
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 09 00 00 00[ ]+jmpabs \$0x987654321
> +\s*[a-f0-9]+:\s*d5 00 a1 00 00 00 00 00 00 00 00[ ]+jmpabs \$0x0\s*[a-f0-9]+: (R_X86_64_|IMAGE_REL_AMD64_ADDR)?64 thunk
> +\s*[a-f0-9]+:\s*d5 00 a1 78 56 34 12 00 00 00 00[ ]+jmpabs \$0x12345678
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 00 00 00 00[ ]+jmpabs \$0x87654321
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 09 00 00 00[ ]+jmpabs \$0x987654321
> #pass
> --- a/gas/testsuite/gas/i386/x86-64-apx-jmpabs.s
> +++ b/gas/testsuite/gas/i386/x86-64-apx-jmpabs.s
> @@ -2,4 +2,18 @@
>
> .text
> _start:
> - .byte 0xd5,0x00,0xa1,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00
> + jmpabs thunk
> + jmpabs 2
> + jmpabs 0x87654321
> + jmpabs 0x987654321
> +
> + jmpabs $thunk
> + jmpabs $0x12345678
> + jmpabs $0x87654321
> + jmpabs $0x987654321
> +
> + .intel_syntax noprefix
> + jmpabs thunk
> + jmpabs 0x12345678
> + jmpabs 0x87654321
> + jmpabs 0x987654321
> --- a/gas/testsuite/gas/i386/x86-64-apx-jmpabs-intel.d
> +++ b/gas/testsuite/gas/i386/x86-64-apx-jmpabs-intel.d
> @@ -1,5 +1,5 @@
> #as:
> -#objdump: -dw -Mintel
> +#objdump: -dwr -Mintel
> #name: x86_64 APX_F JMPABS insns (Intel disassembly)
> #source: x86-64-apx-jmpabs.s
>
> @@ -8,5 +8,16 @@
> Disassembly of section \.text:
>
> 0+ <_start>:
> +\s*[a-f0-9]+:\s*d5 00 a1 00 00 00 00 00 00 00 00[ ]+jmpabs 0x0\s*[a-f0-9]+: (R_X86_64_|IMAGE_REL_AMD64_ADDR)?64 thunk
> \s*[a-f0-9]+:\s*d5 00 a1 02 00 00 00 00 00 00 00[ ]+jmpabs 0x2
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 00 00 00 00[ ]+jmpabs 0x87654321
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 09 00 00 00[ ]+jmpabs 0x987654321
> +\s*[a-f0-9]+:\s*d5 00 a1 00 00 00 00 00 00 00 00[ ]+jmpabs 0x0\s*[a-f0-9]+: (R_X86_64_|IMAGE_REL_AMD64_ADDR)?64 thunk
> +\s*[a-f0-9]+:\s*d5 00 a1 78 56 34 12 00 00 00 00[ ]+jmpabs 0x12345678
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 00 00 00 00[ ]+jmpabs 0x87654321
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 09 00 00 00[ ]+jmpabs 0x987654321
> +\s*[a-f0-9]+:\s*d5 00 a1 00 00 00 00 00 00 00 00[ ]+jmpabs 0x0\s*[a-f0-9]+: (R_X86_64_|IMAGE_REL_AMD64_ADDR)?64 thunk
> +\s*[a-f0-9]+:\s*d5 00 a1 78 56 34 12 00 00 00 00[ ]+jmpabs 0x12345678
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 00 00 00 00[ ]+jmpabs 0x87654321
> +\s*[a-f0-9]+:\s*d5 00 a1 21 43 65 87 09 00 00 00[ ]+jmpabs 0x987654321
> #pass
> --- a/opcodes/i386-opc.tbl
> +++ b/opcodes/i386-opc.tbl
> @@ -510,6 +510,11 @@ ljmp, 0xea, No64, JumpInterSegment|No_bS
> ljmp, 0xff/5, 0, Amd64|Modrm|JumpAbsolute|No_bSuf|No_sSuf|No_qSuf, { Unspecified|BaseIndex }
> ljmp, 0xff/5, x64, Intel64|Modrm|JumpAbsolute|No_bSuf|No_sSuf, { Unspecified|BaseIndex }
>
> +// In particular for AT&T syntax permit both immediate and displacement form,
> +// to allow people to use what they see as the better fit.
Why do we need "jmpabs $xxx" when it is encoded the same
as "jmpabs xxx"? "jmpabs xxx" is sufficient.
> +jmpabs, 0xa1, APX_F, NoSuf|Rex2, { Imm64 }
> +jmpabs, 0xa1, APX_F, NoSuf|Rex2, { Disp64|Unspecified }
> +
> ret, 0xc3, No64, ImplicitStackOp|DefaultSize|No_bSuf|No_sSuf|No_qSuf|RepPrefixOk|BNDPrefixOk|IntelSuffix, {}
> ret, 0xc2, No64, ImplicitStackOp|DefaultSize|No_bSuf|No_sSuf|No_qSuf|RepPrefixOk|BNDPrefixOk|IntelSuffix, { Imm16 }
> ret, 0xc3, x64, Amd64|ImplicitStackOp|DefaultSize|No_bSuf|No_lSuf|No_sSuf|NoRex64|RepPrefixOk|BNDPrefixOk|IntelSuffix, {}
>
--
H.J.
More information about the Binutils
mailing list