[PATCH v2] x86: Add -munaligned-vector-move to assembler

H.J. Lu hjl.tools@gmail.com
Thu Oct 21 17:50:28 GMT 2021


Unaligned load/store instructions on aligned memory or register are as
fast as aligned load/store instructions on modern Intel processors.  Add
a command-line option, -munaligned-vector-move, to x86 assembler to
encode encode aligned vector load/store instructions as unaligned
vector load/store instructions.

	* NEWS: Mention -munaligned-vector-move.
	* config/tc-i386.c (unaligned_vector_move): New.
	(optimize_encoding): Encode aligned vector move as unaligned
	vector move if asked.
	(md_assemble): Call optimize_encoding for -munaligned-vector-move.
	(OPTION_MUNALIGNED_VECTOR_MOVE): New.
	(md_longopts): Add -munaligned-vector-move.
	(md_parse_option): Handle -munaligned-vector-move.
	(md_show_usage): Add -munaligned-vector-move.
	* doc/c-i386.texi: Document -munaligned-vector-move.
	* testsuite/gas/i386/i386.exp: Run unaligned-vector-move and
	x86-64-unaligned-vector-move.
	* testsuite/gas/i386/unaligned-vector-move.d: New file.
	* testsuite/gas/i386/unaligned-vector-move.s: Likewise.
	* testsuite/gas/i386/x86-64-unaligned-vector-move.d: Likewise.
---
 gas/NEWS                                      |  3 ++
 gas/config/tc-i386.c                          | 34 ++++++++++++++++++-
 gas/doc/c-i386.texi                           |  6 ++++
 gas/testsuite/gas/i386/i386.exp               |  2 ++
 .../gas/i386/unaligned-vector-move.d          | 22 ++++++++++++
 .../gas/i386/unaligned-vector-move.s          | 15 ++++++++
 .../gas/i386/x86-64-unaligned-vector-move.d   | 23 +++++++++++++
 7 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/i386/unaligned-vector-move.d
 create mode 100644 gas/testsuite/gas/i386/unaligned-vector-move.s
 create mode 100644 gas/testsuite/gas/i386/x86-64-unaligned-vector-move.d

diff --git a/gas/NEWS b/gas/NEWS
index 5de205ecd55..d07d4c15ca8 100644
--- a/gas/NEWS
+++ b/gas/NEWS
@@ -1,5 +1,8 @@
 -*- text -*-
 
+* Add a command-line option, -munaligned-vector-move, for x86 target to
+  encode aligned vector move as unaligned vector move.
+
 * Add support for Cortex-R52+ for Arm.
 
 * Add support for Cortex-A510, Cortex-A710, Cortex-X2 for AArch64.
diff --git a/gas/config/tc-i386.c b/gas/config/tc-i386.c
index 339f9694948..57ca2b6a25d 100644
--- a/gas/config/tc-i386.c
+++ b/gas/config/tc-i386.c
@@ -800,6 +800,9 @@ static unsigned int no_cond_jump_promotion = 0;
 /* Encode SSE instructions with VEX prefix.  */
 static unsigned int sse2avx;
 
+/* Encode aligned vector move as unaligned vector move.  */
+static unsigned int unaligned_vector_move;
+
 /* Encode scalar AVX instructions with specific vector length.  */
 static enum
   {
@@ -4080,6 +4083,26 @@ optimize_encoding (void)
 {
   unsigned int j;
 
+  /* Encode aligned vector move as unaligned vector move if asked.  */
+  if (unaligned_vector_move)
+    switch (i.tm.base_opcode)
+      {
+      case 0x28:
+	/* movaps/movapd/vmovaps/vmovapd.  */
+	if (i.tm.opcode_modifier.opcodespace == 1
+	    && i.tm.opcode_modifier.opcodeprefix <= 1)
+	  i.tm.base_opcode = 0x10;
+	break;
+      case 0x6f:
+	/* movdqa/vmovdqa/vmovdqa64/vmovdqa32 */
+	if (i.tm.opcode_modifier.opcodespace == 1
+	    && i.tm.opcode_modifier.opcodeprefix == 1)
+	  i.tm.opcode_modifier.opcodeprefix = 2;
+	break;
+      default:
+	break;
+      }
+
   if (i.tm.opcode_modifier.opcodespace == SPACE_BASE
       && i.tm.base_opcode == 0x8d)
     {
@@ -5053,7 +5076,8 @@ md_assemble (char *line)
       i.disp_operands = 0;
     }
 
-  if (optimize && !i.no_optimize && i.tm.opcode_modifier.optimize)
+  if (unaligned_vector_move
+      || (optimize && !i.no_optimize && i.tm.opcode_modifier.optimize))
     optimize_encoding ();
 
   if (!process_suffix ())
@@ -13060,6 +13084,7 @@ const char *md_shortopts = "qnO::";
 #define OPTION_MLFENCE_AFTER_LOAD (OPTION_MD_BASE + 31)
 #define OPTION_MLFENCE_BEFORE_INDIRECT_BRANCH (OPTION_MD_BASE + 32)
 #define OPTION_MLFENCE_BEFORE_RET (OPTION_MD_BASE + 33)
+#define OPTION_MUNALIGNED_VECTOR_MOVE (OPTION_MD_BASE + 34)
 
 struct option md_longopts[] =
 {
@@ -13081,6 +13106,7 @@ struct option md_longopts[] =
   {"mindex-reg", no_argument, NULL, OPTION_MINDEX_REG},
   {"mnaked-reg", no_argument, NULL, OPTION_MNAKED_REG},
   {"msse2avx", no_argument, NULL, OPTION_MSSE2AVX},
+  {"munaligned-vector-move", no_argument, NULL, OPTION_MUNALIGNED_VECTOR_MOVE},
   {"msse-check", required_argument, NULL, OPTION_MSSE_CHECK},
   {"moperand-check", required_argument, NULL, OPTION_MOPERAND_CHECK},
   {"mavxscalar", required_argument, NULL, OPTION_MAVXSCALAR},
@@ -13381,6 +13407,10 @@ md_parse_option (int c, const char *arg)
       sse2avx = 1;
       break;
 
+    case OPTION_MUNALIGNED_VECTOR_MOVE:
+      unaligned_vector_move = 1;
+      break;
+
     case OPTION_MSSE_CHECK:
       if (strcasecmp (arg, "error") == 0)
 	sse_check = check_error;
@@ -13796,6 +13826,8 @@ md_show_usage (FILE *stream)
   fprintf (stream, _("\
   -msse2avx               encode SSE instructions with VEX prefix\n"));
   fprintf (stream, _("\
+  -munaligned-vector-move encode aligned vector move as unaligned vector move\n"));
+  fprintf (stream, _("\
   -msse-check=[none|error|warning] (default: warning)\n\
                           check SSE instructions\n"));
   fprintf (stream, _("\
diff --git a/gas/doc/c-i386.texi b/gas/doc/c-i386.texi
index 99576ef2953..caf8fe0a0a7 100644
--- a/gas/doc/c-i386.texi
+++ b/gas/doc/c-i386.texi
@@ -316,6 +316,12 @@ Valid @var{CPU} values are identical to the processor list of
 This option specifies that the assembler should encode SSE instructions
 with VEX prefix.
 
+@cindex @samp{-munaligned-vector-move} option, i386
+@cindex @samp{-munaligned-vector-move} option, x86-64
+@item -munaligned-vector-move
+This option specifies that the assembler should encode encode aligned
+vector move as unaligned vector move.
+
 @cindex @samp{-msse-check=} option, i386
 @cindex @samp{-msse-check=} option, x86-64
 @item -msse-check=@var{none}
diff --git a/gas/testsuite/gas/i386/i386.exp b/gas/testsuite/gas/i386/i386.exp
index 680259b1c4e..378e32b39cb 100644
--- a/gas/testsuite/gas/i386/i386.exp
+++ b/gas/testsuite/gas/i386/i386.exp
@@ -272,6 +272,7 @@ if [gas_32_check] then {
     run_dump_test "evex-wig1-intel"
     run_dump_test "evex-no-scale-32"
     run_dump_test "sse2avx"
+    run_dump_test "unaligned-vector-move"
     run_list_test "inval-avx" "-al"
     run_list_test "inval-avx512f" "-al"
     run_list_test "inval-avx512vl" "-al"
@@ -948,6 +949,7 @@ if [gas_64_check] then {
     run_dump_test "x86-64-evex-wig2"
     run_dump_test "evex-no-scale-64"
     run_dump_test "x86-64-sse2avx"
+    run_dump_test "x86-64-unaligned-vector-move"
     run_list_test "x86-64-inval-avx" "-al"
     run_list_test "x86-64-inval-avx512f" "-al"
     run_list_test "x86-64-inval-avx512vl" "-al"
diff --git a/gas/testsuite/gas/i386/unaligned-vector-move.d b/gas/testsuite/gas/i386/unaligned-vector-move.d
new file mode 100644
index 00000000000..be0d96fd8b2
--- /dev/null
+++ b/gas/testsuite/gas/i386/unaligned-vector-move.d
@@ -0,0 +1,22 @@
+#as: -munaligned-vector-move
+#objdump: -dw
+#name: i386 (Encode aligned vector move as unaligned vector move)
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+:	0f 10 d1             	movups %xmm1,%xmm2
+ +[a-f0-9]+:	66 0f 10 d1          	movupd %xmm1,%xmm2
+ +[a-f0-9]+:	f3 0f 6f d1          	movdqu %xmm1,%xmm2
+ +[a-f0-9]+:	c5 f8 10 d1          	vmovups %xmm1,%xmm2
+ +[a-f0-9]+:	c5 f9 10 d1          	vmovupd %xmm1,%xmm2
+ +[a-f0-9]+:	c5 fa 6f d1          	vmovdqu %xmm1,%xmm2
+ +[a-f0-9]+:	c5 f8 10 d1          	vmovups %xmm1,%xmm2
+ +[a-f0-9]+:	62 f1 fd 09 10 d1    	vmovupd %xmm1,%xmm2\{%k1\}
+ +[a-f0-9]+:	62 f1 7c 09 10 d1    	vmovups %xmm1,%xmm2\{%k1\}
+ +[a-f0-9]+:	62 f1 7e 09 6f d1    	vmovdqu32 %xmm1,%xmm2\{%k1\}
+ +[a-f0-9]+:	62 f1 fe 09 6f d1    	vmovdqu64 %xmm1,%xmm2\{%k1\}
+#pass
diff --git a/gas/testsuite/gas/i386/unaligned-vector-move.s b/gas/testsuite/gas/i386/unaligned-vector-move.s
new file mode 100644
index 00000000000..b88ae232a38
--- /dev/null
+++ b/gas/testsuite/gas/i386/unaligned-vector-move.s
@@ -0,0 +1,15 @@
+# Encode aligned vector move as unaligned vector move.
+
+	.text
+_start:
+	movaps %xmm1, %xmm2
+	movapd %xmm1, %xmm2
+	movdqa %xmm1, %xmm2
+	vmovaps %xmm1, %xmm2
+	vmovapd %xmm1, %xmm2
+	vmovdqa %xmm1, %xmm2
+	vmovaps %xmm1, %xmm2
+	vmovapd %xmm1, %xmm2{%k1}
+	vmovaps %xmm1, %xmm2{%k1}
+	vmovdqa32 %xmm1, %xmm2{%k1}
+	vmovdqa64 %xmm1, %xmm2{%k1}
diff --git a/gas/testsuite/gas/i386/x86-64-unaligned-vector-move.d b/gas/testsuite/gas/i386/x86-64-unaligned-vector-move.d
new file mode 100644
index 00000000000..410d9478dad
--- /dev/null
+++ b/gas/testsuite/gas/i386/x86-64-unaligned-vector-move.d
@@ -0,0 +1,23 @@
+#source: unaligned-vector-move.s
+#as: -munaligned-vector-move
+#objdump: -dw
+#name: x86-64 (Encode aligned vector move as unaligned vector move)
+
+.*: +file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+ +[a-f0-9]+:	0f 10 d1             	movups %xmm1,%xmm2
+ +[a-f0-9]+:	66 0f 10 d1          	movupd %xmm1,%xmm2
+ +[a-f0-9]+:	f3 0f 6f d1          	movdqu %xmm1,%xmm2
+ +[a-f0-9]+:	c5 f8 10 d1          	vmovups %xmm1,%xmm2
+ +[a-f0-9]+:	c5 f9 10 d1          	vmovupd %xmm1,%xmm2
+ +[a-f0-9]+:	c5 fa 6f d1          	vmovdqu %xmm1,%xmm2
+ +[a-f0-9]+:	c5 f8 10 d1          	vmovups %xmm1,%xmm2
+ +[a-f0-9]+:	62 f1 fd 09 10 d1    	vmovupd %xmm1,%xmm2\{%k1\}
+ +[a-f0-9]+:	62 f1 7c 09 10 d1    	vmovups %xmm1,%xmm2\{%k1\}
+ +[a-f0-9]+:	62 f1 7e 09 6f d1    	vmovdqu32 %xmm1,%xmm2\{%k1\}
+ +[a-f0-9]+:	62 f1 fe 09 6f d1    	vmovdqu64 %xmm1,%xmm2\{%k1\}
+#pass
-- 
2.32.0



More information about the Binutils mailing list