OSDN Git Service

PR target/32065
authoruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 May 2007 22:36:10 +0000 (22:36 +0000)
committeruros <uros@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 May 2007 22:36:10 +0000 (22:36 +0000)
        * target/i386/i386.c (ix86_expand_vector_move): Force SUBREGs of
        constants into memory.  Expand unaligned memory references for
        SSE modes via x86_expand_vector_move_misalign() function.

testsuite/ChangeLog:

        PR target/32065
        * gcc.target/i386/pr32065.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125077 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr32065.c [new file with mode: 0644]

index 0fd8e75..4967fc5 100644 (file)
@@ -1,3 +1,10 @@
+2007-05-26  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/32065
+       * target/i386/i386.c (ix86_expand_vector_move): Force SUBREGs of
+       constants into memory.  Expand unaligned memory references for
+       SSE modes via x86_expand_vector_move_misalign() function.
+
 2007-05-25  Uros Bizjak  <ubizjak@gmail.com>
 
        * config/i386/sse.md (*vec_extractv2di_1_sse2): Do not calculate
index ca5df2d..dae841c 100644 (file)
@@ -9727,6 +9727,7 @@ void
 ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
 {
   rtx op0 = operands[0], op1 = operands[1];
+  unsigned int align = GET_MODE_ALIGNMENT (mode);
 
   /* Force constants other than zero into memory.  We do not know how
      the instructions used to build constants modify the upper 64 bits
@@ -9734,10 +9735,39 @@ ix86_expand_vector_move (enum machine_mode mode, rtx operands[])
      to handle some of them more efficiently.  */
   if ((reload_in_progress | reload_completed) == 0
       && register_operand (op0, mode)
-      && CONSTANT_P (op1)
+      && (CONSTANT_P (op1)
+         || (GET_CODE (op1) == SUBREG
+             && CONSTANT_P (SUBREG_REG (op1))))
       && standard_sse_constant_p (op1) <= 0)
     op1 = validize_mem (force_const_mem (mode, op1));
 
+  /* TDmode values are passed as TImode on the stack.  Timode values
+     are moved via xmm registers, and moving them to stack can result in
+     unaligned memory access.  Use ix86_expand_vector_move_misalign()
+     if memory operand is not aligned correctly.  */
+  if (!no_new_pseudos
+      && SSE_REG_MODE_P (mode)
+      && ((MEM_P (op0) && (MEM_ALIGN (op0) < align))
+         || (MEM_P (op1) && (MEM_ALIGN (op1) < align))))
+    {
+      rtx tmp[2];
+
+      /* ix86_expand_vector_move_misalign() does not like constants ... */
+      if (CONSTANT_P (op1)
+         || (GET_CODE (op1) == SUBREG
+             && CONSTANT_P (SUBREG_REG (op1))))
+       op1 = validize_mem (force_const_mem (mode, op1));
+
+      /* ... nor both arguments in memory.  */
+      if (!register_operand (op0, mode)
+         && !register_operand (op1, mode))
+       op1 = force_reg (mode, op1);
+
+      tmp[0] = op0; tmp[1] = op1;
+      ix86_expand_vector_move_misalign (mode, tmp);
+      return;
+    }
+
   /* Make operand1 a register if it isn't already.  */
   if (!no_new_pseudos
       && !register_operand (op0, mode)
index ed0ee7f..59b1939 100644 (file)
@@ -1,3 +1,8 @@
+007-05-26  Uros Bizjak  <ubizjak@gmail.com>
+
+       PR target/32065
+       * gcc.target/i386/pr32065.c: New test.
+
 2007-05-25  Dirk Mueller  <dmueller@suse.de>
            Marcus Meissner <meissner@suse.de>
 
diff --git a/gcc/testsuite/gcc.target/i386/pr32065.c b/gcc/testsuite/gcc.target/i386/pr32065.c
new file mode 100644 (file)
index 0000000..d6692b5
--- /dev/null
@@ -0,0 +1,7 @@
+/* { dg-do compile { target dfp } } */
+/* { dg-options "-msse" } */
+
+_Decimal128 test (void)
+{
+  return 1234123412341234.123412341234dl;
+}