]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
x86/Intel: SHLD/SHRD have dual meaning
authorJan Beulich <jbeulich@suse.com>
Wed, 29 May 2024 08:02:01 +0000 (10:02 +0200)
committerJan Beulich <jbeulich@suse.com>
Wed, 29 May 2024 08:02:01 +0000 (10:02 +0200)
Since we uniformly permit D suffixes in Intel mode whenever in AT&T mode
an L suffix may be used, we need to be consistent with this.

Take the easy route, despite that still leading to an anomaly which is
also visible from the new testcase:

shld eax, ecx, 1
shld eax, ecx, cl

can mean two things with APX: SHL with a D suffix in NDD EVEX encoding,
or the traditional SHLD in legacy encoding.

gas/config/tc-i386.c
gas/testsuite/gas/i386/intel-suffix.d [new file with mode: 0644]
gas/testsuite/gas/i386/intel-suffix.s [new file with mode: 0644]
gas/testsuite/gas/i386/x86-64.exp

index b1cc06851c5d53ac6d60e6ca6ae47936e9fa0b31..65d992311b7d73c436db0454d74d42faad52490f 100644 (file)
@@ -5392,7 +5392,7 @@ static void init_globals (void)
 }
 
 /* Helper for md_assemble() to decide whether to prepare for a possible 2nd
-   parsing pass. Instead of introducing a rarely use new insn attribute this
+   parsing pass. Instead of introducing a rarely used new insn attribute this
    utilizes a common pattern between affected templates. It is deemed
    acceptable that this will lead to unnecessary pass 2 preparations in a
    limited set of cases.  */
@@ -5404,7 +5404,10 @@ static INLINE bool may_need_pass2 (const insn_template *t)
         : (t->opcode_space == SPACE_0F
            && (t->base_opcode | 1) == 0xbf)
           || (t->opcode_space == SPACE_BASE
-              && t->base_opcode == 0x63);
+              && t->base_opcode == 0x63)
+          || (intel_syntax /* shld / shrd may mean suffixed shl / shr.  */
+              && t->opcode_space == SPACE_EVEXMAP4
+              && (t->base_opcode | 8) == 0x2c);
 }
 
 #if defined (OBJ_MAYBE_ELF) || defined (OBJ_ELF)
diff --git a/gas/testsuite/gas/i386/intel-suffix.d b/gas/testsuite/gas/i386/intel-suffix.d
new file mode 100644 (file)
index 0000000..5ac3209
--- /dev/null
@@ -0,0 +1,34 @@
+#objdump: -dw
+#name: Intel syntax w/ suffixes
+
+.*: +file format .*
+
+Disassembly of section \.text:
+0+0 <.*>:
+[      ]*[a-f0-9]+:    0f a4 c8 01[    ]+shld   \$0x1,%ecx,%eax
+[      ]*[a-f0-9]+:    0f a5 c8[       ]+shld   %cl,%ecx,%eax
+[      ]*[a-f0-9]+:    d1 e1[  ]+shl    \$1,%ecx
+[      ]*[a-f0-9]+:    d3 e1[  ]+shl    %cl,%ecx
+[      ]*[a-f0-9]+:    62 f4 7c 18 d1 e1[      ]+shl    \$1,%ecx,%eax
+[      ]*[a-f0-9]+:    62 f4 7c 18 d3 e1[      ]+shl    %cl,%ecx,%eax
+[      ]*[a-f0-9]+:    d1 e1[  ]+shl    \$1,%ecx
+[      ]*[a-f0-9]+:    d3 e1[  ]+shl    %cl,%ecx
+[      ]*[a-f0-9]+:    62 f4 7c 18 d1 c1[      ]+rol    \$1,%ecx,%eax
+[      ]*[a-f0-9]+:    62 f4 7c 18 d3 c1[      ]+rol    %cl,%ecx,%eax
+[      ]*[a-f0-9]+:    d1 c1[  ]+rol    \$1,%ecx
+[      ]*[a-f0-9]+:    d3 c1[  ]+rol    %cl,%ecx
+
+0+[0-9a-f]+ <.*>:
+[      ]*[a-f0-9]+:    0f ac c8 01[    ]+shrd   \$0x1,%ecx,%eax
+[      ]*[a-f0-9]+:    0f ad c8[       ]+shrd   %cl,%ecx,%eax
+[      ]*[a-f0-9]+:    d1 e9[  ]+shr    \$1,%ecx
+[      ]*[a-f0-9]+:    d3 e9[  ]+shr    %cl,%ecx
+[      ]*[a-f0-9]+:    62 f4 7c 18 d1 f9[      ]+sar    \$1,%ecx,%eax
+[      ]*[a-f0-9]+:    62 f4 7c 18 d3 f9[      ]+sar    %cl,%ecx,%eax
+[      ]*[a-f0-9]+:    d1 f9[  ]+sar    \$1,%ecx
+[      ]*[a-f0-9]+:    d3 f9[  ]+sar    %cl,%ecx
+[      ]*[a-f0-9]+:    62 f4 7c 18 d1 c9[      ]+ror    \$1,%ecx,%eax
+[      ]*[a-f0-9]+:    62 f4 7c 18 d3 c9[      ]+ror    %cl,%ecx,%eax
+[      ]*[a-f0-9]+:    d1 c9[  ]+ror    \$1,%ecx
+[      ]*[a-f0-9]+:    d3 c9[  ]+ror    %cl,%ecx
+#pass
diff --git a/gas/testsuite/gas/i386/intel-suffix.s b/gas/testsuite/gas/i386/intel-suffix.s
new file mode 100644 (file)
index 0000000..cc88afa
--- /dev/null
@@ -0,0 +1,39 @@
+       .intel_syntax noprefix
+       .text
+left:
+       shld    eax, ecx, 1
+       shld    eax, ecx, cl
+
+       shld    ecx, 1
+       shld    ecx, cl
+
+       sald    eax, ecx, 1
+       sald    eax, ecx, cl
+
+       sald    ecx, 1
+       sald    ecx, cl
+
+       rold    eax, ecx, 1
+       rold    eax, ecx, cl
+
+       rold    ecx, 1
+       rold    ecx, cl
+
+right:
+       shrd    eax, ecx, 1
+       shrd    eax, ecx, cl
+
+       shrd    ecx, 1
+       shrd    ecx, cl
+
+       sard    eax, ecx, 1
+       sard    eax, ecx, cl
+
+       sard    ecx, 1
+       sard    ecx, cl
+
+       rord    eax, ecx, 1
+       rord    eax, ecx, cl
+
+       rord    ecx, 1
+       rord    ecx, cl
index ef1ad2dfe8ad01f96ce786a3fe939530f2642490..8ac7aca1fec8e2fcbb0d4ff08806d3e5e8af8f8a 100644 (file)
@@ -160,6 +160,7 @@ run_dump_test "x86-64-disp-intel"
 run_list_test "disp-imm-64"
 run_dump_test "intel-movs64"
 run_dump_test "intel-cmps64"
+run_dump_test "intel-suffix"
 run_dump_test "x86-64-disp32"
 run_dump_test "rexw"
 run_list_test "x86-64-specific-reg"