x86-64: accept 64-bit LFS/LGS/LSS forms with suffix or operand size specifier

Message ID b4705ee9-539e-fa41-7bf7-9bdf57371fc6@suse.com
State New
Headers show
Series
  • x86-64: accept 64-bit LFS/LGS/LSS forms with suffix or operand size specifier
Related show

Commit Message

Jan Beulich Nov. 29, 2019, 8:27 a.m.
Since we accept these without suffix / operand size specifier, we should
also do so with one. (The fact that we unilaterally accept these, other
than far branches, rather than limiting them to Intel64 mode, will be
taken care of later on.)

Also take the opportunity and make sure "lfs <reg>, tbyte ptr <mem>"
et al get rejected outside of 64-bit mode. This became broken by
dc2be329b950 ("i386: Only check suffix in instruction mnemonic").
Furthermore cover lgdt et al in the Intel syntax handling as well, which
continued to work after said commit just by coincidence.

gas/
2019-11-XX  Jan Beulich  <jbeulich@suse.com>

	* config/tc-i386-intel.c (i386_intel_operand): Handle LFS et al
	as well as LGDT at al when processing O_tbyte_ptr.
	* testsuite/gas/i386/intelbad.s: Add LDS et al cases.
	* testsuite/gas/i386/x86-64-intel64.s,
	* testsuite/gas/i386/x86-64-opcode.s:  Add LFS et al cases.
	* testsuite/gas/i386/ilp32/x86-64-intel64.d: Add -mintel64
	command line option and fold expectations with parent dir test.
	* testsuite/gas/i386/x86-64-intel64.d: Add -mintel64 command
	line option and adjust expectations.
	* testsuite/gas/i386/intelbad.l,
	testsuite/gas/i386/x86-64-opcode.d: Adjust expectations.

opcodes/
2019-11-XX  Jan Beulich  <jbeulich@suse.com>

	* i386-opc.tbl (lfs, lgs, lss): Drop No_qSuf.
	* i386-tbl.h: Re-generate.

Comments

H.J. Lu Dec. 3, 2019, 5:51 p.m. | #1
On Fri, Nov 29, 2019 at 12:27 AM Jan Beulich <jbeulich@suse.com> wrote:
>

> Since we accept these without suffix / operand size specifier, we should

> also do so with one. (The fact that we unilaterally accept these, other

> than far branches, rather than limiting them to Intel64 mode, will be

> taken care of later on.)

>

> Also take the opportunity and make sure "lfs <reg>, tbyte ptr <mem>"

> et al get rejected outside of 64-bit mode. This became broken by

> dc2be329b950 ("i386: Only check suffix in instruction mnemonic").

> Furthermore cover lgdt et al in the Intel syntax handling as well, which

> continued to work after said commit just by coincidence.

>

> gas/

> 2019-11-XX  Jan Beulich  <jbeulich@suse.com>

>

>         * config/tc-i386-intel.c (i386_intel_operand): Handle LFS et al

>         as well as LGDT at al when processing O_tbyte_ptr.

>         * testsuite/gas/i386/intelbad.s: Add LDS et al cases.

>         * testsuite/gas/i386/x86-64-intel64.s,

>         * testsuite/gas/i386/x86-64-opcode.s:  Add LFS et al cases.

>         * testsuite/gas/i386/ilp32/x86-64-intel64.d: Add -mintel64

>         command line option and fold expectations with parent dir test.

>         * testsuite/gas/i386/x86-64-intel64.d: Add -mintel64 command

>         line option and adjust expectations.

>         * testsuite/gas/i386/intelbad.l,

>         testsuite/gas/i386/x86-64-opcode.d: Adjust expectations.

>

> opcodes/

> 2019-11-XX  Jan Beulich  <jbeulich@suse.com>

>

>         * i386-opc.tbl (lfs, lgs, lss): Drop No_qSuf.

>         * i386-tbl.h: Re-generate.

>


OK.

Thanks.

-- 
H.J.

Patch

--- a/gas/config/tc-i386-intel.c
+++ b/gas/config/tc-i386-intel.c
@@ -698,6 +698,15 @@  i386_intel_operand (char *operand_string
 	  i.types[this_operand].bitfield.tbyte = 1;
 	  if (got_a_float == 1)
 	    suffix = LONG_DOUBLE_MNEM_SUFFIX;
+	  else if (current_templates->start->operand_types[0].bitfield.fword
+		   || current_templates->start->operand_types[0].bitfield.tbyte)
+	    {
+	      /* l[defgs]s, [ls][gi]dt */
+	      if (flag_code == CODE_64BIT)
+		suffix = QWORD_MNEM_SUFFIX;
+	      else
+		i.types[this_operand].bitfield.byte = 1; /* cause an error */
+	    }
 	  else
 	    suffix = BYTE_MNEM_SUFFIX; /* so it will cause an error */
 	  break;
--- a/gas/testsuite/gas/i386/ilp32/x86-64-intel64.d
+++ b/gas/testsuite/gas/i386/ilp32/x86-64-intel64.d
@@ -1,11 +1,5 @@ 
 #source: ../x86-64-intel64.s
+#as: -mintel64
 #objdump: -dw
 #name: x86-64 (ILP32) Intel64
-
-.*: +file format .*
-
-Disassembly of section .text:
-0+ <_start>:
-[ 	]*[a-f0-9]+:	0f 05                	syscall 
-[ 	]*[a-f0-9]+:	0f 07                	sysret 
-#pass
+#dump: ../x86-64-intel64.d
--- a/gas/testsuite/gas/i386/intelbad.l
+++ b/gas/testsuite/gas/i386/intelbad.l
@@ -152,3 +152,8 @@ 
 .*:168: Error: .*
 .*:169: Error: .*
 .*:172: Error: .*
+.*:174: Error: .*
+.*:175: Error: .*
+.*:176: Warning: .*
+.*:177: Error: .*
+.*:178: Error: .*
--- a/gas/testsuite/gas/i386/intelbad.s
+++ b/gas/testsuite/gas/i386/intelbad.s
@@ -170,3 +170,9 @@  start:
 #XXX?	movzx	eax, byte ptr [1]
 
 	mov	eax, 3:5
+
+	lds	eax, byte ptr [eax]
+	les	eax, word ptr [eax]
+	lfs	eax, dword ptr [eax]
+	lgs	eax, qword ptr [eax]
+	lss	eax, tbyte ptr [eax]
--- a/gas/testsuite/gas/i386/x86-64-intel64.d
+++ b/gas/testsuite/gas/i386/x86-64-intel64.d
@@ -1,3 +1,4 @@ 
+#as: -mintel64
 #objdump: -dw
 #name: x86-64 Intel64
 
@@ -5,6 +6,18 @@ 
 
 Disassembly of section .text:
 0+ <_start>:
+[ 	]*[a-f0-9]+:	48 0f b4 08          	lfs    \(%rax\),%rcx
+[ 	]*[a-f0-9]+:	48 0f b4 08          	lfs    \(%rax\),%rcx
+[ 	]*[a-f0-9]+:	48 0f b5 11          	lgs    \(%rcx\),%rdx
+[ 	]*[a-f0-9]+:	48 0f b5 11          	lgs    \(%rcx\),%rdx
+[ 	]*[a-f0-9]+:	48 0f b2 1a          	lss    \(%rdx\),%rbx
+[ 	]*[a-f0-9]+:	48 0f b2 1a          	lss    \(%rdx\),%rbx
 [ 	]*[a-f0-9]+:	0f 05                	syscall 
 [ 	]*[a-f0-9]+:	0f 07                	sysret 
+[ 	]*[a-f0-9]+:	48 0f b4 01          	lfs    \(%rcx\),%rax
+[ 	]*[a-f0-9]+:	48 0f b4 01          	lfs    \(%rcx\),%rax
+[ 	]*[a-f0-9]+:	48 0f b5 0a          	lgs    \(%rdx\),%rcx
+[ 	]*[a-f0-9]+:	48 0f b5 0a          	lgs    \(%rdx\),%rcx
+[ 	]*[a-f0-9]+:	48 0f b2 13          	lss    \(%rbx\),%rdx
+[ 	]*[a-f0-9]+:	48 0f b2 13          	lss    \(%rbx\),%rdx
 #pass
--- a/gas/testsuite/gas/i386/x86-64-intel64.s
+++ b/gas/testsuite/gas/i386/x86-64-intel64.s
@@ -3,5 +3,20 @@ 
 	.text
 	.arch core2
 _start:
+	lfs	(%rax), %rcx
+	lfsq	(%rax), %rcx
+	lgs	(%rcx), %rdx
+	lgsq	(%rcx), %rdx
+	lss	(%rdx), %rbx
+	lssq	(%rdx), %rbx
+
 	syscall
 	sysret
+
+	.intel_syntax noprefix
+	lfs	rax, [rcx]
+	lfs	rax, tbyte ptr [rcx]
+	lgs	rcx, [rdx]
+	lgs	rcx, tbyte ptr [rdx]
+	lss	rdx, [rbx]
+	lss	rdx, tbyte ptr [rbx]
--- a/gas/testsuite/gas/i386/x86-64-opcode.d
+++ b/gas/testsuite/gas/i386/x86-64-opcode.d
@@ -45,6 +45,18 @@  Disassembly of section .text:
 [ 	]*[a-f0-9]+:	c7 00 00 00 00 70    	movl   \$0x70000000,\(%rax\)
 [ 	]*[a-f0-9]+:	49 c7 00 00 00 00 70 	movq   \$0x70000000,\(%r8\)
 [ 	]*[a-f0-9]+:	48 c7 00 00 00 00 70 	movq   \$0x70000000,\(%rax\)
+[ 	]*[a-f0-9]+:	0f b4 08             	lfs    \(%rax\),%ecx
+[ 	]*[a-f0-9]+:	0f b4 01             	lfs    \(%rcx\),%eax
+[ 	]*[a-f0-9]+:	66 0f b4 08          	lfs    \(%rax\),%cx
+[ 	]*[a-f0-9]+:	66 0f b4 01          	lfs    \(%rcx\),%ax
+[ 	]*[a-f0-9]+:	0f b5 11             	lgs    \(%rcx\),%edx
+[ 	]*[a-f0-9]+:	0f b5 0a             	lgs    \(%rdx\),%ecx
+[ 	]*[a-f0-9]+:	66 0f b5 11          	lgs    \(%rcx\),%dx
+[ 	]*[a-f0-9]+:	66 0f b5 0a          	lgs    \(%rdx\),%cx
+[ 	]*[a-f0-9]+:	0f b2 1a             	lss    \(%rdx\),%ebx
+[ 	]*[a-f0-9]+:	0f b2 13             	lss    \(%rbx\),%edx
+[ 	]*[a-f0-9]+:	66 0f b2 1a          	lss    \(%rdx\),%bx
+[ 	]*[a-f0-9]+:	66 0f b2 13          	lss    \(%rbx\),%dx
 [ 	]*[a-f0-9]+:	41 0f c3 00          	movnti %eax,\(%r8\)
 [ 	]*[a-f0-9]+:	0f c3 00             	movnti %eax,\(%rax\)
 [ 	]*[a-f0-9]+:	49 0f c3 00          	movnti %rax,\(%r8\)
--- a/gas/testsuite/gas/i386/x86-64-opcode.s
+++ b/gas/testsuite/gas/i386/x86-64-opcode.s
@@ -50,6 +50,20 @@ 
 	MOVq $0x70000000,(%r8)	      # --  --  -- 49   C7 00 00 00 00 70		 ; REX for 64-bit operand size. REX to access upper reg.
 	MOVq $0x70000000,(%rax)	      # --  --  -- 48   C7 00 00 00 00 70		 ; REX for 64-bit operand size
 
+	# LFS etc
+	LFS  (%rax), %ecx             # --  --  -- --   0F B4 ..
+	LFSl (%rcx), %eax             # --  --  -- --   0F B4 ..
+	LFS  (%rax), %cx              # 66  --  -- --   0F B4 ..
+	LFSw (%rcx), %ax              # 66  --  -- --   0F B4 ..
+	LGS  (%rcx), %edx             # --  --  -- --   0F B5 ..
+	LGSl (%rdx), %ecx             # --  --  -- --   0F B5 ..
+	LGS  (%rcx), %dx              # 66  --  -- --   0F B5 ..
+	LGSw (%rdx), %cx              # 66  --  -- --   0F B5 ..
+	LSS  (%rdx), %ebx             # --  --  -- --   0F B2 ..
+	LSSl (%rbx), %edx             # --  --  -- --   0F B2 ..
+	LSS  (%rdx), %bx              # 66  --  -- --   0F B2 ..
+	LSSw (%rbx), %dx              # 66  --  -- --   0F B2 ..
+
 	# MOVNTI
 	MOVNTI %eax,(%r8)	      # --  --  -- 41   0f c3 00			 ; REX to access upper reg.
 	MOVNTI %eax,(%rax)	      # --  --  -- --   0f c3 00
--- a/opcodes/i386-opc.tbl
+++ b/opcodes/i386-opc.tbl
@@ -201,9 +201,9 @@  lea, 2, 0x8d, None, 1, 0, Modrm|Anysize|
 // Load segment registers from memory.
 lds, 2, 0xc5, None, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
 les, 2, 0xc4, None, 1, CpuNo64, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Unspecified|BaseIndex, Reg16|Reg32 }
-lfs, 2, 0xfb4, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-lgs, 2, 0xfb5, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
-lss, 2, 0xfb2, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_qSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+lfs, 2, 0xfb4, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+lgs, 2, 0xfb5, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
+lss, 2, 0xfb2, None, 2, Cpu386, Modrm|No_bSuf|No_sSuf|No_ldSuf, { DWord|Fword|Tbyte|Unspecified|BaseIndex, Reg16|Reg32|Reg64 }
 
 // Flags register instructions.
 clc, 0, 0xf8, None, 1, 0, No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_qSuf|No_ldSuf, { 0 }