]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
mips-protos.h (mips_expand_ext_as_unaligned_load): Add a bool argument.
authorAndrew Pinski <apinski@cavium.com>
Sat, 21 Jul 2012 10:38:20 +0000 (10:38 +0000)
committerAndrew Pinski <pinskia@gcc.gnu.org>
Sat, 21 Jul 2012 10:38:20 +0000 (03:38 -0700)
2012-07-21  Andrew Pinski  <apinski@cavium.com>

        * config/mips/mips-protos.h (mips_expand_ext_as_unaligned_load):
        Add a bool argument.
        * config/mips/mips.c (mips_block_move_straight): Update call to
        mips_expand_ext_as_unaligned_load.
        (mips_expand_ext_as_unaligned_load): Add unsigned_p argument.
        Accept DImode dest when the width is that of SImode.
        * config/mips/mips.md (extv): Update call to
mips_expand_ext_as_unaligned_load.
(extzv): Likewise.

2012-07-21  Andrew Pinski  <apinski@cavium.com>

        * gcc.target/mips/unaligned-1.c: New testcase.

From-SVN: r189742

gcc/ChangeLog
gcc/config/mips/mips-protos.h
gcc/config/mips/mips.c
gcc/config/mips/mips.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/unaligned-1.c [new file with mode: 0644]

index fec3d36a271929b03ca14067f96599f091bc8a65..40277665f23b751ffb9fe2fb7b6d285cccfff271 100644 (file)
@@ -1,3 +1,15 @@
+2012-07-21  Andrew Pinski  <apinski@cavium.com>
+
+       * config/mips/mips-protos.h (mips_expand_ext_as_unaligned_load):
+       Add a bool argument.
+       * config/mips/mips.c (mips_block_move_straight): Update call to
+       mips_expand_ext_as_unaligned_load.
+       (mips_expand_ext_as_unaligned_load): Add unsigned_p argument.
+       Accept DImode dest when the width is that of SImode.
+        * config/mips/mips.md (extv): Update call to
+       mips_expand_ext_as_unaligned_load.
+       (extzv): Likewise.
+
 2012-07-21  Andrew Pinski  <apinski@cavium.com>
 
        * config/mips/mips.c (mips_get_unaligned_mem): Copy *op after calling
index d1fa160ff1ce85877d82fab56f10b6565e1169a9..cba76b6672b31bc5c9d0b8f08b3ab13271e1b5bb 100644 (file)
@@ -241,7 +241,7 @@ extern bool mips_pad_arg_upward (enum machine_mode, const_tree);
 extern bool mips_pad_reg_upward (enum machine_mode, tree);
 
 extern bool mips_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT,
-                                              HOST_WIDE_INT);
+                                              HOST_WIDE_INT, bool);
 extern bool mips_expand_ins_as_unaligned_store (rtx, rtx, HOST_WIDE_INT,
                                                HOST_WIDE_INT);
 extern bool mips_mem_fits_mode_p (enum machine_mode mode, rtx x);
index 498dc27797a240eedcbf661548b6267ca64f1c22..e4e93e69731ec28356bf01fb9e150101afe4dc74 100644 (file)
@@ -6916,7 +6916,7 @@ mips_block_move_straight (rtx dest, rtx src, HOST_WIDE_INT length)
       else
        {
          rtx part = adjust_address (src, BLKmode, offset);
-         if (!mips_expand_ext_as_unaligned_load (regs[i], part, bits, 0))
+         if (!mips_expand_ext_as_unaligned_load (regs[i], part, bits, 0, 0))
            gcc_unreachable ();
        }
     }
@@ -7249,9 +7249,10 @@ mips_get_unaligned_mem (rtx *op, HOST_WIDE_INT width, HOST_WIDE_INT bitpos,
 
 bool
 mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width,
-                                  HOST_WIDE_INT bitpos)
+                                  HOST_WIDE_INT bitpos, bool unsigned_p)
 {
   rtx left, right, temp;
+  rtx dest1 = NULL_RTX;
 
   /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will
      be a paradoxical word_mode subreg.  This is the only case in which
@@ -7261,6 +7262,16 @@ mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width,
       && GET_MODE (SUBREG_REG (dest)) == SImode)
     dest = SUBREG_REG (dest);
 
+  /* If TARGET_64BIT, the destination of a 32-bit "extz" or "extzv" will
+     be a DImode, create a new temp and emit a zero extend at the end.  */
+  if (GET_MODE (dest) == DImode
+      && REG_P (dest)
+      && GET_MODE_BITSIZE (SImode) == width)
+    {
+      dest1 = dest;
+      dest = gen_reg_rtx (SImode);
+    }
+
   /* After the above adjustment, the destination must be the same
      width as the source.  */
   if (GET_MODE_BITSIZE (GET_MODE (dest)) != width)
@@ -7280,6 +7291,16 @@ mips_expand_ext_as_unaligned_load (rtx dest, rtx src, HOST_WIDE_INT width,
       emit_insn (gen_mov_lwl (temp, src, left));
       emit_insn (gen_mov_lwr (dest, copy_rtx (src), right, temp));
     }
+
+  /* If we were loading 32bits and the original register was DI then
+     sign/zero extend into the orignal dest.  */
+  if (dest1)
+    {
+      if (unsigned_p)
+        emit_insn (gen_zero_extendsidi2 (dest1, dest));
+      else
+        emit_insn (gen_extendsidi2 (dest1, dest));
+    }
   return true;
 }
 
index b6b2beba596dc191702964c2457c91dfbcd5b85c..0edc9d94986a3d779514d6186e0481a064891e5c 100644 (file)
 {
   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
                                         INTVAL (operands[2]),
-                                        INTVAL (operands[3])))
+                                        INTVAL (operands[3]),
+                                        /*unsigned=*/ false))
     DONE;
   else if (register_operand (operands[1], GET_MODE (operands[0]))
           && ISA_HAS_EXTS && UINTVAL (operands[2]) <= 32)
 {
   if (mips_expand_ext_as_unaligned_load (operands[0], operands[1],
                                         INTVAL (operands[2]),
-                                        INTVAL (operands[3])))
+                                        INTVAL (operands[3]),
+                                        /*unsigned=*/true))
     DONE;
   else if (mips_use_ins_ext_p (operands[1], INTVAL (operands[2]),
                               INTVAL (operands[3])))
index 94504842c76ee7c389061066bff4c1590ec92f83..25ca1359f97f142f2c6c2476edf794b3cd0d4bb3 100644 (file)
@@ -1,3 +1,7 @@
+2012-07-21  Andrew Pinski  <apinski@cavium.com>
+
+       * gcc.target/mips/unaligned-1.c: New testcase.
+
 2012-07-21  Hans-Peter Nilsson  <hp@axis.com>
 
        * gcc.c-torture/execute/20101011-1.c (DO_TEST): Define as 0 for CRIS.
diff --git a/gcc/testsuite/gcc.target/mips/unaligned-1.c b/gcc/testsuite/gcc.target/mips/unaligned-1.c
new file mode 100644 (file)
index 0000000..23b6c8c
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-options "-O2 -mgp64" } */
+/* { dg-final { scan-assembler-times "sdl\t" 1 } } */
+/* { dg-final { scan-assembler-times "sdr\t" 1 } } */
+/* { dg-final { scan-assembler-times "ldl\t" 1 } } */
+/* { dg-final { scan-assembler-times "ldr\t" 1 } } */
+/* { dg-final { scan-assembler-times "swl\t" 1 } } */
+/* { dg-final { scan-assembler-times "swr\t" 1 } } */
+/* { dg-final { scan-assembler-times "lwl\t" 1 } } */
+/* { dg-final { scan-assembler-times "lwr\t" 1 } } */
+/* { dg-final { scan-assembler-not "nop" } } */
+
+/* Test to make sure we produce the unaligned load/store for
+   both 64bit and 32bits sized accesses.  */
+
+struct s
+{
+  char c;
+  int i;
+  long long l;
+} __attribute__ ((packed)) s __attribute__((aligned(1) ));
+
+void
+sd (long long l)
+{
+  s.l = l;
+}
+
+long long
+ld ()
+{
+  return s.l;
+}
+
+void
+sw (int i)
+{
+  s.i = i;
+}
+
+int
+lw ()
+{
+  return s.i;
+}