[PATCH v3 09/10] x86-64: honor vendor specifics for near RET

Jan Beulich JBeulich@suse.com
Fri Dec 27 09:21:00 GMT 2019


While vendors agree about default operand size (64 bits) and hence
unavilability of a 32-bit form, AMD honors a 16-bit operand size
override (0x66) while Intel doesn't.

gas/
2020-01-XX  Jan Beulich  <jbeulich@suse.com>

	* testsuite/gas/i386/x86-64-branch-2.s,
	testsuite/gas/i386/x86-64-branch-4.s,
	testsuite/gas/i386/x86-64-branch.s: Add RETW cases.
	* testsuite/gas/i386/ilp32/x86-64-branch.d,
	testsuite/gas/i386/x86-64-branch-2.d,
	testsuite/gas/i386/x86-64-branch-4.l,
	testsuite/gas/i386/x86-64-branch.d: Adjust expectations.

opcodes/
2020-01-XX  Jan Beulich  <jbeulich@suse.com>

	* i386-dis.c (X86_64_C2, X86_64_C3): New enumerators.
	(dis386): Use them to replace C2/C3 table entries.
	(x86_64_table): Add X86_64_C2 and X86_64_C3 entries.
	* i386-opc.tbl (ret): Split Cpu64 entries into AMD64 and Intel64
	ones. Use Size64 instead of DefaultSize on Intel64 ones.
	* i386-tbl.h: Re-generate.
---
v3: New.

--- a/gas/testsuite/gas/i386/ilp32/x86-64-branch.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-branch.d
@@ -23,6 +23,8 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 e8 00 00 00 00    	data16 callq 0x2a	26: R_X86_64_PLT32	foo-0x4
 [ 	]*[a-f0-9]+:	66 e9 00 00 00 00    	data16 jmpq 0x30	2c: R_X86_64_PLT32	foo-0x4
 [ 	]*[a-f0-9]+:	66 0f 82 00 00 00 00 	data16 jb 0x37	33: R_X86_64_PLT32	foo-0x4
+[ 	]*[a-f0-9]+:	66 c3                	data16 retq *
+[ 	]*[a-f0-9]+:	66 c2 08 00          	data16 retq \$0x8
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	data16 callq \*%rax
@@ -33,6 +35,8 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff e0             	data16 jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	data16 jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 ff 20             	data16 jmpq \*\(%rax\)
-[ 	]*[a-f0-9]+:	e8 00 00 00 00       	callq  0x56	52: R_X86_64_PC32	\*ABS\*\+0x10003c
-[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   0x5b	57: R_X86_64_PC32	\*ABS\*\+0x10003c
+[ 	]*[a-f0-9]+:	e8 00 00 00 00       	callq  0x[0-9a-f]*	[0-9a-f]*: R_X86_64_PC32	\*ABS\*\+0x10003c
+[ 	]*[a-f0-9]+:	e9 00 00 00 00       	jmpq   0x[0-9a-f]*	[0-9a-f]*: R_X86_64_PC32	\*ABS\*\+0x10003c
+[ 	]*[a-f0-9]+:	66 c3                	data16 retq *
+[ 	]*[a-f0-9]+:	66 c2 08 00          	data16 retq \$0x8
 #pass
--- a/gas/testsuite/gas/i386/x86-64-branch-2.d
+++ b/gas/testsuite/gas/i386/x86-64-branch-2.d
@@ -14,4 +14,6 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	89 c3                	mov    %eax,%ebx
 [ 	]*[a-f0-9]+:	66 e8 00 00          	callw  11 <bar\+0x6>	f: R_X86_64_PC16	foo-0x2
 [ 	]*[a-f0-9]+:	66 48 e8 00 00 00 00 	data16 callq 18 <bar\+0xd>	14: R_X86_64_PLT32	foo-0x4
+[ 	]*[a-f0-9]+:	66 c3                	retw *
+[ 	]*[a-f0-9]+:	66 c2 08 00          	retw   \$0x8
 #pass
--- a/gas/testsuite/gas/i386/x86-64-branch-2.s
+++ b/gas/testsuite/gas/i386/x86-64-branch-2.s
@@ -7,3 +7,6 @@ bar:
 
 	data16 call foo
 	data16 rex.w call foo
+
+	retw
+	retw $8
--- a/gas/testsuite/gas/i386/x86-64-branch-4.l
+++ b/gas/testsuite/gas/i386/x86-64-branch-4.l
@@ -4,14 +4,18 @@
 .*:4: Error: operand type mismatch for `jmp'
 .*:5: Error: invalid instruction suffix for `jmp'
 .*:6: Error: invalid instruction suffix for `jmp'
-.*:9: Error: operand type mismatch for `call'
-.*:10: Error: invalid instruction suffix for `call'
-.*:11: Error: invalid instruction suffix for `call'
-.*:12: Error: operand size mismatch for `call'
-.*:13: Error: operand type mismatch for `jmp'
-.*:14: Error: invalid instruction suffix for `jmp'
-.*:15: Error: invalid instruction suffix for `jmp'
-.*:16: Error: operand size mismatch for `jmp'
+.*:7: Error: invalid instruction suffix for `ret'
+.*:8: Error: invalid instruction suffix for `ret'
+.*:11: Error: operand type mismatch for `call'
+.*:12: Error: invalid instruction suffix for `call'
+.*:13: Error: invalid instruction suffix for `call'
+.*:14: Error: operand size mismatch for `call'
+.*:15: Error: operand type mismatch for `jmp'
+.*:16: Error: invalid instruction suffix for `jmp'
+.*:17: Error: invalid instruction suffix for `jmp'
+.*:18: Error: operand size mismatch for `jmp'
+.*:19: Error: invalid instruction suffix for `ret'
+.*:20: Error: invalid instruction suffix for `ret'
 GAS LISTING .*
 #...
 [ 	]*1[ 	]+\.text
@@ -20,14 +24,18 @@ GAS LISTING .*
 [ 	]*4[ 	]+jmp	\*%ax
 [ 	]*5[ 	]+jmpw	\*%ax
 [ 	]*6[ 	]+jmpw	\*\(%rax\)
-[ 	]*7[ 	]+
-[ 	]*8[ 	]+\.intel_syntax noprefix
-[ 	]*9[ 	]+call	ax
-[ 	]*10[ 	]+callw	ax
-[ 	]*11[ 	]+callw	\[rax\]
-[ 	]*12[ 	]+call	WORD PTR \[rax\]
-[ 	]*13[ 	]+jmp	ax
-[ 	]*14[ 	]+jmpw	ax
-[ 	]*15[ 	]+jmpw	\[rax\]
-[ 	]*16[ 	]+jmp	WORD PTR \[rax\]
+[ 	]*7[ 	]+retw
+[ 	]*8[ 	]+retw	\$8
+[ 	]*9[ 	]+
+[ 	]*10[ 	]+\.intel_syntax noprefix
+[ 	]*11[ 	]+call	ax
+[ 	]*12[ 	]+callw	ax
+[ 	]*13[ 	]+callw	\[rax\]
+[ 	]*14[ 	]+call	WORD PTR \[rax\]
+[ 	]*15[ 	]+jmp	ax
+[ 	]*16[ 	]+jmpw	ax
+[ 	]*17[ 	]+jmpw	\[rax\]
+[ 	]*18[ 	]+jmp	WORD PTR \[rax\]
+[ 	]*19[ 	]+retw
+[ 	]*20[ 	]+retw	8
 #pass
--- a/gas/testsuite/gas/i386/x86-64-branch-4.s
+++ b/gas/testsuite/gas/i386/x86-64-branch-4.s
@@ -4,6 +4,8 @@
 	jmp	*%ax
 	jmpw	*%ax
 	jmpw	*(%rax)
+	retw
+	retw	$8
 
 	.intel_syntax noprefix
 	call	ax
@@ -14,3 +16,5 @@
 	jmpw	ax
 	jmpw	[rax]
 	jmp	WORD PTR [rax]
+	retw
+	retw	8
--- a/gas/testsuite/gas/i386/x86-64-branch.d
+++ b/gas/testsuite/gas/i386/x86-64-branch.d
@@ -22,6 +22,8 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 e8 00 00 00 00    	data16 callq (0x2a|2a <.text\+0x2a>)
 [ 	]*[a-f0-9]+:	66 e9 00 00 00 00    	data16 jmpq (0x30|30 <.text\+0x30>)
 [ 	]*[a-f0-9]+:	66 0f 82 00 00 00 00 	data16 jb (0x37|37 <.text\+0x37>)
+[ 	]*[a-f0-9]+:	66 c3                	data16 retq *
+[ 	]*[a-f0-9]+:	66 c2 08 00          	data16 retq \$0x8
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	ff d0                	callq  \*%rax
 [ 	]*[a-f0-9]+:	66 ff d0             	data16 callq \*%rax
@@ -32,6 +34,8 @@ Disassembly of section .text:
 [ 	]*[a-f0-9]+:	66 ff e0             	data16 jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 ff e0             	data16 jmpq \*%rax
 [ 	]*[a-f0-9]+:	66 ff 20             	data16 jmpq \*\(%rax\)
-[ 	]*[a-f0-9]+:	e8 (00|92) 00 (00|10) 00       	callq  (0x56|1000e8 <.text\+0x1000e8>)
-[ 	]*[a-f0-9]+:	e9 (00|97) 00 (00|10) 00       	jmpq   (0x5b|1000f2 <.text\+0x1000f2>)
+[ 	]*[a-f0-9]+:	e8 .. 00 (00|10) 00       	callq  (0x[0-9a-f]*|100[0-9a-f]* <.text\+0x100[0-9a-f]*>)
+[ 	]*[a-f0-9]+:	e9 .. 00 (00|10) 00       	jmpq   (0x[0-9a-f]*|100[0-9a-f]* <.text\+0x100[0-9a-f]*>)
+[ 	]*[a-f0-9]+:	66 c3                	data16 retq *
+[ 	]*[a-f0-9]+:	66 c2 08 00          	data16 retq \$0x8
 #pass
--- a/gas/testsuite/gas/i386/x86-64-branch.s
+++ b/gas/testsuite/gas/i386/x86-64-branch.s
@@ -19,6 +19,9 @@
 	.byte 0x66
 	jb	foo
 
+	retw
+	retw	$8
+
 	.intel_syntax noprefix
 	call	rax
 	callq	rax
@@ -32,3 +35,5 @@
 	jmpw	[rax]
 	call	0x100040
 	jmp	0x100040
+	retw
+	retw	8
--- a/opcodes/i386-dis.c
+++ b/opcodes/i386-dis.c
@@ -1762,6 +1762,8 @@ enum
   X86_64_6F,
   X86_64_82,
   X86_64_9A,
+  X86_64_C2,
+  X86_64_C3,
   X86_64_C4,
   X86_64_C5,
   X86_64_CE,
@@ -2584,8 +2586,8 @@ static const struct dis386 dis386[] = {
   /* c0 */
   { REG_TABLE (REG_C0) },
   { REG_TABLE (REG_C1) },
-  { "retT",		{ Iw, BND }, 0 },
-  { "retT",		{ BND }, 0 },
+  { X86_64_TABLE (X86_64_C2) },
+  { X86_64_TABLE (X86_64_C3) },
   { X86_64_TABLE (X86_64_C4) },
   { X86_64_TABLE (X86_64_C5) },
   { REG_TABLE (REG_C6) },
@@ -6899,6 +6901,18 @@ static const struct dis386 x86_64_table[
     { "Jcall{T|}", { Ap }, 0 },
   },
 
+  /* X86_64_C2 */
+  {
+    { "retP",		{ Iw, BND }, 0 },
+    { "ret@",		{ Iw, BND }, 0 },
+  },
+
+  /* X86_64_C3 */
+  {
+    { "retP",		{ BND }, 0 },
+    { "ret@",		{ BND }, 0 },
+  },
+
   /* X86_64_C4 */
   {
     { MOD_TABLE (MOD_C4_32BIT) },
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -394,8 +394,10 @@ ljmp, 1, 0xff, 0x5, 1, 0, Modrm|JumpAbso
 
 ret, 0, 0xc3, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { 0 }
 ret, 1, 0xc2, None, 1, CpuNo64, DefaultSize|No_bSuf|No_sSuf|No_qSuf|No_ldSuf|RepPrefixOk|BNDPrefixOk, { Imm16 }
-ret, 0, 0xc3, None, 1, Cpu64, DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
-ret, 1, 0xc2, None, 1, Cpu64, DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
+ret, 0, 0xc3, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
+ret, 1, 0xc2, None, 1, Cpu64, AMD64|DefaultSize|No_bSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
+ret, 0, 0xc3, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { 0 }
+ret, 1, 0xc2, None, 1, Cpu64, Intel64|Size64|No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_ldSuf|NoRex64|RepPrefixOk|BNDPrefixOk, { Imm16 }
 lret, 0, 0xcb, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { 0 }
 lret, 1, 0xca, None, 1, 0, DefaultSize|No_bSuf|No_sSuf|No_ldSuf, { Imm16 }
 // Intel Syntax.



More information about the Binutils mailing list