From 6ccf16c19d318bae09b7b405825285f7579d820f Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 29 May 2024 10:02:01 +0200 Subject: x86/Intel: SHLD/SHRD have dual meaning 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 | 7 +++++-- gas/testsuite/gas/i386/intel-suffix.d | 34 ++++++++++++++++++++++++++++++ gas/testsuite/gas/i386/intel-suffix.s | 39 +++++++++++++++++++++++++++++++++++ gas/testsuite/gas/i386/x86-64.exp | 1 + 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 gas/testsuite/gas/i386/intel-suffix.d create mode 100644 gas/testsuite/gas/i386/intel-suffix.s (limited to 'gas') diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c index b1cc068..65d9923 100644 --- a/gas/config/tc-i386.c +++ b/gas/config/tc-i386.c @@ -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 index 0000000..5ac3209 --- /dev/null +++ b/gas/testsuite/gas/i386/intel-suffix.d @@ -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 index 0000000..cc88afa --- /dev/null +++ b/gas/testsuite/gas/i386/intel-suffix.s @@ -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 diff --git a/gas/testsuite/gas/i386/x86-64.exp b/gas/testsuite/gas/i386/x86-64.exp index ef1ad2d..8ac7aca 100644 --- a/gas/testsuite/gas/i386/x86-64.exp +++ b/gas/testsuite/gas/i386/x86-64.exp @@ -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" -- cgit v1.1