[PATCH 2/2] x86/APX: support JMPABS also in assembler

Jan Beulich jbeulich@suse.com
Tue Oct 8 10:26:46 GMT 2024


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.
+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, {}



More information about the Binutils mailing list