ldmstm.md (ldm2_ia, [...]): Add condition !arm_arch7 to these insns.
authorWei Guozhi <carrot@google.com>
Sat, 11 Jun 2011 02:28:35 +0000 (02:28 +0000)
committerWei Guozhi <carrot@gcc.gnu.org>
Sat, 11 Jun 2011 02:28:35 +0000 (02:28 +0000)
* config/arm/ldmstm.md (ldm2_ia, stm2_ia, ldm2_ib, stm2_ib, ldm2_da,
stm2_da, ldm2_db, stm2_db): Add condition !arm_arch7 to these insns.
(ldrd, ldrd_reg1, ldrd_reg2 and peephole2): New insn patterns and
related peephole2.
(strd, strd_reg1, strd_reg2 and peephole2): New insn patterns and
related peephole2.

* config/arm/arm-protos.h (arm_check_ldrd_operands): New prototype.
(arm_legitimate_ldrd_p): New prototype.
(arm_output_ldrd): New prototype.

* config/arm/arm.c (arm_check_ldrd_operands): New function.
(arm_legitimate_ldrd_p): New function.
(arm_output_ldrd): New function.

* gcc.target/arm/pr45335.c: New test.

* gcc.target/arm/pr45335-2.c: New test.

* gcc.target/arm/pr45335-3.c: New test.

* gcc.target/arm/pr40457-1.c: Add another possible output "ldrd".

* gcc.target/arm/pr40457-2.c: Changed to store 3 words.

* gcc.target/arm/pr40457-3.c: Changed to store 3 words.

From-SVN: r174940

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/ldmstm.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/pr40457-1.c
gcc/testsuite/gcc.target/arm/pr40457-2.c
gcc/testsuite/gcc.target/arm/pr40457-3.c

index 712e22009cca137f2c623555f0e478fd2b9131b9..4857e927109051be5a1f62275e30660142ee9470 100644 (file)
@@ -1,3 +1,19 @@
+2011-06-10  Wei Guozhi  <carrot@google.com>
+
+       PR target/45335
+       * config/arm/ldmstm.md (ldm2_ia, stm2_ia, ldm2_ib, stm2_ib, ldm2_da,
+       stm2_da, ldm2_db, stm2_db): Add condition !arm_arch7 to these insns.
+       (ldrd, ldrd_reg1, ldrd_reg2 and peephole2): New insn patterns and
+       related peephole2.
+       (strd, strd_reg1, strd_reg2 and peephole2): New insn patterns and
+       related peephole2.
+       * config/arm/arm-protos.h (arm_check_ldrd_operands): New prototype.
+       (arm_legitimate_ldrd_p): New prototype.
+       (arm_output_ldrd): New prototype.
+       * config/arm/arm.c (arm_check_ldrd_operands): New function.
+       (arm_legitimate_ldrd_p): New function.
+       (arm_output_ldrd): New function.
+
 2011-06-10  David Li  <davidxl@google.com>
 
        * cgraphunit.c (cgraph_finalize_compilation_unit): Pass dump.
index 67aee46e0bfebab873e4b938e99ba3c8cd74dbaa..9132b6d0910467c5664c03ad3899242293fe6fa3 100644 (file)
@@ -153,6 +153,9 @@ extern const char *arm_output_memory_barrier (rtx *);
 extern const char *arm_output_sync_insn (rtx, rtx *);
 extern unsigned int arm_sync_loop_insns (rtx , rtx *);
 extern int arm_attr_length_push_multi(rtx, rtx);
+extern bool arm_check_ldrd_operands (rtx, rtx, rtx, rtx);
+extern bool arm_legitimate_ldrd_p (rtx, rtx, rtx, rtx, bool);
+extern int arm_output_ldrd (rtx, rtx, rtx, rtx, rtx, bool);
 
 #if defined TREE_CODE
 extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
index c1bae17be069f0ea7f40c6d93fabea09583cfa54..efc2bcb1ee5ea8ccd4e228466827caf8fb4fef04 100644 (file)
@@ -23853,4 +23853,234 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
   return 4;
 }
 
+/* Check the validity of operands in an ldrd/strd instruction.  */
+bool
+arm_check_ldrd_operands (rtx reg1, rtx reg2, rtx off1, rtx off2)
+{
+  HOST_WIDE_INT offset1 = 0;
+  HOST_WIDE_INT offset2 = 0;
+  int regno1 = REGNO (reg1);
+  int regno2 = REGNO (reg2);
+  HOST_WIDE_INT max_offset = 1020;
+
+  if (TARGET_ARM)
+    max_offset = 255;
+
+  if (off1 != NULL_RTX)
+    offset1 = INTVAL (off1);
+  if (off2 != NULL_RTX)
+    offset2 = INTVAL (off2);
+
+  /* The offset range of LDRD is [-max_offset, max_offset]. Here we check if
+     both offsets lie in the range [-max_offset, max_offset+4]. If one of the
+     offsets is max_offset+4, the following condition
+       ((offset1 + 4) == offset2)
+     will ensure offset1 to be max_offset, suitable for instruction LDRD.  */
+  if ((offset1 > (max_offset + 4)) || (offset1 < -max_offset)
+      || ((offset1 & 3) != 0))
+    return false;
+  if ((offset2 > (max_offset + 4)) || (offset2 < -max_offset)
+      || ((offset2 & 3) != 0))
+    return false;
+
+  if ((offset1 + 4) == offset2)
+    {
+      if (TARGET_THUMB2)
+       return true;
+
+      /* TARGET_ARM  */
+      if (((regno1 & 1) == 0) && ((regno1 + 1) == regno2))           /* ldrd  */
+       return true;
+
+      if ((regno1 < regno2) && ((offset1 <= 4) && (offset1 >= -8)))  /* ldm  */
+       return true;
+    }
+  if ((offset2 + 4) == offset1)
+    {
+      if (TARGET_THUMB2)
+       return true;
+
+      /* TARGET_ARM  */
+      if (((regno2 & 1) == 0) && ((regno2 + 1) == regno1))           /* ldrd  */
+       return true;
+
+      if ((regno2 < regno1) && ((offset2 <= 4) && (offset2 >= -8)))  /* ldm  */
+       return true;
+    }
+
+  return false;
+}
+
+/* Check if the two memory accesses can be merged to an ldrd/strd instruction.
+   That is they use the same base register, and the gap between constant
+   offsets should be 4.  */
+bool
+arm_legitimate_ldrd_p (rtx reg1, rtx reg2, rtx mem1, rtx mem2, bool ldrd)
+{
+  rtx base1, base2;
+  rtx offset1 = NULL_RTX;
+  rtx offset2 = NULL_RTX;
+  rtx addr1 = XEXP (mem1, 0);
+  rtx addr2 = XEXP (mem2, 0);
+
+  if (MEM_VOLATILE_P (mem1) || MEM_VOLATILE_P (mem2))
+    return false;
+
+  if (REG_P (addr1))
+    base1 = addr1;
+  else if (GET_CODE (addr1) == PLUS)
+    {
+      base1 = XEXP (addr1, 0);
+      offset1 = XEXP (addr1, 1);
+      if (!REG_P (base1) || (GET_CODE (offset1) != CONST_INT))
+       return false;
+    }
+  else
+    return false;
+
+  if (REG_P (addr2))
+    base2 = addr2;
+  else if (GET_CODE (addr2) == PLUS)
+    {
+      base2 = XEXP (addr2, 0);
+      offset2 = XEXP (addr2, 1);
+      if (!REG_P (base2) || (GET_CODE (offset2) != CONST_INT))
+       return false;
+    }
+  else
+    return false;
+
+  if (base1 != base2)
+    return false;
+
+  if (ldrd && ((reg1 == reg2) || (reg1 == base1)))
+    return false;
+
+  return arm_check_ldrd_operands (reg1, reg2, offset1, offset2);
+}
+
+/* Output instructions for ldrd and count the number of bytes has been
+   outputted. Do not actually output instructions if EMIT_P is false.  */
+int
+arm_output_ldrd (rtx reg1, rtx reg2, rtx base, rtx off1, rtx off2, bool emit_p)
+{
+  int length = 0;
+  rtx operands[5];
+  HOST_WIDE_INT offset1 = 0;
+  HOST_WIDE_INT offset2 = 0;
+
+  if (off1 != NULL_RTX)
+    offset1 = INTVAL (off1);
+  else
+    off1 = GEN_INT (0);
+  if (off2 != NULL_RTX)
+    offset2 = INTVAL (off2);
+  else
+    off2 = GEN_INT (0);
+  if (offset1 > offset2)
+    {
+      rtx tmp;
+      HOST_WIDE_INT t = offset1;   offset1 = offset2;   offset2 = t;
+      tmp = off1;   off1 = off2;   off2 = tmp;
+      tmp = reg1;   reg1 = reg2;   reg2 = tmp;
+    }
+
+  operands[0] = reg1;
+  operands[1] = reg2;
+  operands[2] = base;
+  operands[3] = off1;
+  operands[4] = off2;
+
+  if (TARGET_THUMB2)
+    {
+      if (fix_cm3_ldrd && (base == reg1))
+       {
+         if (offset1 <= -256)
+           {
+             if (emit_p)
+               output_asm_insn ("sub\t%2, %2, %n3", operands);
+             length = 4;
+
+             if (emit_p)
+               output_asm_insn ("ldr\t%1, [%2, #4]", operands);
+             if (low_register_operand (reg2, SImode)
+                 && low_register_operand (base, SImode))
+               length += 2;
+             else
+               length += 4;
+
+             if (emit_p)
+               output_asm_insn ("ldr\t%0, [%2]", operands);
+             if (low_register_operand (base, SImode))
+               length += 2;
+             else
+               length += 4;
+           }
+         else
+           {
+             if (emit_p)
+               output_asm_insn ("ldr\t%1, [%2, %4]", operands);
+             if (low_register_operand (reg2, SImode) && (offset2 >= 0)
+                 && low_register_operand (base, SImode) && (offset2 < 128))
+               length += 2;
+             else
+               length += 4;
+
+             if (emit_p)
+               output_asm_insn ("ldr\t%0, [%2, %3]", operands);
+             if (low_register_operand (base, SImode)
+                 && (offset1 >= 0) && (offset1 < 128))
+               length += 2;
+             else
+               length += 4;
+           }
+       }
+      else
+       {
+         if (emit_p)
+           output_asm_insn ("ldrd\t%0, %1, [%2, %3]", operands);
+         length = 4;
+       }
+    }
+  else    /* TARGET_ARM  */
+    {
+      if ((REGNO (reg2) == (REGNO (reg1) + 1)) && ((REGNO (reg1) & 1) == 0))
+       {
+         if (emit_p)
+           output_asm_insn ("ldrd\t%0, %1, [%2, %3]", operands);
+         length = 4;
+       }
+      else
+       {
+         if (emit_p)
+           {
+             switch (offset1)
+               {
+               case -8:
+                 output_asm_insn ("ldm%(db%)\t%2, {%0, %1}", operands);
+                 break;
+
+               case -4:
+                 output_asm_insn ("ldm%(da%)\t%2, {%0, %1}", operands);
+                 break;
+
+               case 0:
+                 output_asm_insn ("ldm%(ia%)\t%2, {%0, %1}", operands);
+                 break;
+
+               case 4:
+                 output_asm_insn ("ldm%(ib%)\t%2, {%0, %1}", operands);
+                 break;
+
+               default:
+                 gcc_unreachable ();
+               }
+           }
+         length = 4;
+       }
+    }
+
+  return length;
+}
+
 #include "gt-arm.h"
index 5db4a3269968b396e9ae811dc616e7e1adb3291d..d5451ab48b2a37fb328095d635492fd4729cf916 100644 (file)
      (set (match_operand:SI 2 "arm_hard_register_operand" "")
           (mem:SI (plus:SI (match_dup 3)
                   (const_int 4))))])]
-  "TARGET_32BIT && XVECLEN (operands[0], 0) == 2"
+  "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "ldm%(ia%)\t%3, {%1, %2}"
   [(set_attr "type" "load2")
    (set_attr "predicable" "yes")])
           (match_operand:SI 1 "arm_hard_register_operand" ""))
      (set (mem:SI (plus:SI (match_dup 3) (const_int 4)))
           (match_operand:SI 2 "arm_hard_register_operand" ""))])]
-  "TARGET_32BIT && XVECLEN (operands[0], 0) == 2"
+  "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "stm%(ia%)\t%3, {%1, %2}"
   [(set_attr "type" "store2")
    (set_attr "predicable" "yes")])
      (set (match_operand:SI 2 "arm_hard_register_operand" "")
           (mem:SI (plus:SI (match_dup 3)
                   (const_int 8))))])]
-  "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
+  "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "ldm%(ib%)\t%3, {%1, %2}"
   [(set_attr "type" "load2")
    (set_attr "predicable" "yes")])
           (match_operand:SI 1 "arm_hard_register_operand" ""))
      (set (mem:SI (plus:SI (match_dup 3) (const_int 8)))
           (match_operand:SI 2 "arm_hard_register_operand" ""))])]
-  "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
+  "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "stm%(ib%)\t%3, {%1, %2}"
   [(set_attr "type" "store2")
    (set_attr "predicable" "yes")])
                   (const_int -4))))
      (set (match_operand:SI 2 "arm_hard_register_operand" "")
           (mem:SI (match_dup 3)))])]
-  "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
+  "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "ldm%(da%)\t%3, {%1, %2}"
   [(set_attr "type" "load2")
    (set_attr "predicable" "yes")])
           (match_operand:SI 1 "arm_hard_register_operand" ""))
      (set (mem:SI (match_dup 3))
           (match_operand:SI 2 "arm_hard_register_operand" ""))])]
-  "TARGET_ARM && XVECLEN (operands[0], 0) == 2"
+  "TARGET_ARM && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "stm%(da%)\t%3, {%1, %2}"
   [(set_attr "type" "store2")
    (set_attr "predicable" "yes")])
      (set (match_operand:SI 2 "arm_hard_register_operand" "")
           (mem:SI (plus:SI (match_dup 3)
                   (const_int -4))))])]
-  "TARGET_32BIT && XVECLEN (operands[0], 0) == 2"
+  "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "ldm%(db%)\t%3, {%1, %2}"
   [(set_attr "type" "load2")
    (set_attr "predicable" "yes")])
           (match_operand:SI 1 "arm_hard_register_operand" ""))
      (set (mem:SI (plus:SI (match_dup 3) (const_int -4)))
           (match_operand:SI 2 "arm_hard_register_operand" ""))])]
-  "TARGET_32BIT && XVECLEN (operands[0], 0) == 2"
+  "TARGET_32BIT && !arm_arch7 && XVECLEN (operands[0], 0) == 2"
   "stm%(db%)\t%3, {%1, %2}"
   [(set_attr "type" "store2")
    (set_attr "predicable" "yes")])
     FAIL;
 })
 
+(define_insn "*ldrd"
+  [(set (match_operand:SI 0 "arm_hard_register_operand" "")
+       (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk")
+                        (match_operand:SI 3 "const_int_operand" ""))))
+   (set (match_operand:SI 1 "arm_hard_register_operand" "")
+       (mem:SI (plus:SI (match_dup 2)
+                        (match_operand:SI 4 "const_int_operand" ""))))]
+  "TARGET_32BIT && arm_arch7
+   && arm_check_ldrd_operands (operands[0], operands[1],
+                              operands[3], operands[4])"
+  "*
+  arm_output_ldrd (operands[0], operands[1],
+                  operands[2], operands[3], operands[4], true);
+  return \"\";
+  "
+  [(set (attr "length")
+       (symbol_ref ("arm_output_ldrd (operands[0], operands[1], operands[2],
+                                      operands[3], operands[4], false)")))]
+)
+
+(define_insn "*ldrd_reg1"
+  [(set (match_operand:SI 0 "arm_hard_register_operand" "")
+       (mem:SI (match_operand:SI 2 "s_register_operand" "rk")))
+   (set (match_operand:SI 1 "arm_hard_register_operand" "")
+       (mem:SI (plus:SI (match_dup 2)
+                        (match_operand:SI 3 "const_int_operand" ""))))]
+  "TARGET_32BIT && arm_arch7
+   && arm_check_ldrd_operands (operands[0], operands[1], NULL_RTX, operands[3])"
+  "*
+  arm_output_ldrd (operands[0], operands[1],
+                  operands[2], NULL_RTX, operands[3], true);
+  return \"\";
+  "
+  [(set (attr "length")
+       (symbol_ref ("arm_output_ldrd (operands[0], operands[1], operands[2],
+                                      NULL_RTX, operands[3], false)")))]
+)
+
+(define_insn "*ldrd_reg2"
+  [(set (match_operand:SI 0 "arm_hard_register_operand" "")
+       (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk")
+                        (match_operand:SI 3 "const_int_operand" ""))))
+   (set (match_operand:SI 1 "arm_hard_register_operand" "")
+       (mem:SI (match_dup 2)))]
+  "TARGET_32BIT && arm_arch7
+   && arm_check_ldrd_operands (operands[0], operands[1], operands[3], NULL_RTX)"
+  "*
+  arm_output_ldrd (operands[0], operands[1],
+                  operands[2], operands[3], NULL_RTX, true);
+  return \"\";
+  "
+  [(set (attr "length")
+       (symbol_ref ("arm_output_ldrd (operands[0], operands[1], operands[2],
+                                      operands[3], NULL_RTX, false)")))]
+)
+
+(define_peephole2
+  [(set (match_operand:SI 0 "arm_general_register_operand" "")
+       (match_operand:SI 2 "memory_operand" ""))
+   (set (match_operand:SI 1 "arm_general_register_operand" "")
+       (match_operand:SI 3 "memory_operand" ""))]
+  "TARGET_32BIT && arm_arch7
+   && arm_legitimate_ldrd_p (operands[0], operands[1],
+                            operands[2], operands[3], true)"
+  [(parallel [(set (match_operand:SI 0 "arm_general_register_operand" "")
+                  (match_operand:SI 2 "memory_operand" ""))
+             (set (match_operand:SI 1 "arm_general_register_operand" "")
+                  (match_operand:SI 3 "memory_operand" ""))])]
+  ""
+)
+
+(define_insn "*strd"
+  [(set (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk")
+                        (match_operand:SI 3 "const_int_operand" "")))
+       (match_operand:SI 0 "arm_hard_register_operand" ""))
+   (set (mem:SI (plus:SI (match_dup 2)
+                        (match_operand:SI 4 "const_int_operand" "")))
+       (match_operand:SI 1 "arm_hard_register_operand" ""))]
+  "TARGET_32BIT && arm_arch7
+   && arm_check_ldrd_operands (operands[0], operands[1],
+                              operands[3], operands[4])"
+  "*
+  {
+    HOST_WIDE_INT offset1 = INTVAL (operands[3]);
+    HOST_WIDE_INT offset2 = INTVAL (operands[4]);
+    if (offset1 > offset2)
+      {
+       rtx tmp = operands[0];  operands[0] = operands[1];  operands[1] = tmp;
+       tmp = operands[3];  operands[3] = operands[4];  operands[4] = tmp;
+       offset1 = INTVAL (operands[3]);
+       offset2 = INTVAL (operands[4]);
+      }
+    if (TARGET_THUMB2)
+      return \"strd\\t%0, %1, [%2, %3]\";
+    else          /* TARGET_ARM  */
+      {
+       if ((REGNO (operands[1]) == (REGNO (operands[0]) + 1))
+           && ((REGNO (operands[0]) & 1) == 0))
+         return \"strd\\t%0, %1, [%2, %3]\";
+       else if (offset1 == -8)
+         return \"stm%(db%)\\t%2, {%0, %1}\";
+       else      /* offset1 == 4  */
+         return \"stm%(ib%)\\t%2, {%0, %1}\";
+      }
+  }"
+  [(set_attr "length" "4")]
+)
+
+(define_insn "*strd_reg1"
+  [(set (mem:SI (match_operand:SI 2 "s_register_operand" "rk"))
+       (match_operand:SI 0 "arm_hard_register_operand" ""))
+   (set (mem:SI (plus:SI (match_dup 2)
+                        (match_operand:SI 3 "const_int_operand" "")))
+       (match_operand:SI 1 "arm_hard_register_operand" ""))]
+  "TARGET_32BIT && arm_arch7
+   && arm_check_ldrd_operands (operands[0], operands[1], NULL_RTX, operands[3])"
+  "*
+  {
+    HOST_WIDE_INT offset2 = INTVAL (operands[3]);
+    if (TARGET_THUMB2)
+      {
+       if (offset2 == 4)
+         return \"strd\\t%0, %1, [%2]\";
+       else
+         return \"strd\\t%1, %0, [%2, %3]\";
+      }
+    else           /* TARGET_ARM  */
+      {
+       if (offset2 == 4)
+         {
+           if ((REGNO (operands[1]) == (REGNO (operands[0]) + 1))
+               && ((REGNO (operands[0]) & 1) == 0))
+             return \"strd\\t%0, %1, [%2]\";
+           else
+             return \"stm%(ia%)\\t%2, {%0, %1}\";
+         }
+       else      /* offset2 == -4  */
+         {
+           if ((REGNO (operands[0]) == (REGNO (operands[1]) + 1))
+               && ((REGNO (operands[1]) & 1) == 0))
+             return \"strd\\t%1, %0, [%2, %3]\";
+           else
+             return \"stm%(da%)\\t%2, {%1, %0}\";
+         }
+      }
+  }"
+  [(set_attr "length" "4")]
+)
+
+(define_insn "*strd_reg2"
+  [(set (mem:SI (plus:SI (match_operand:SI 2 "s_register_operand" "rk")
+                        (match_operand:SI 3 "const_int_operand" "")))
+       (match_operand:SI 0 "arm_hard_register_operand" ""))
+   (set (mem:SI (match_dup 2))
+       (match_operand:SI 1 "arm_hard_register_operand" ""))]
+  "TARGET_32BIT && arm_arch7
+   && arm_check_ldrd_operands (operands[0], operands[1], operands[3], NULL_RTX)"
+  "*
+  {
+    HOST_WIDE_INT offset1 = INTVAL (operands[3]);
+    if (TARGET_THUMB2)
+      {
+       if (offset1 == -4)
+         return \"strd\\t%0, %1, [%2, %3]\";
+       else
+         return \"strd\\t%1, %0, [%2]\";
+      }
+    else           /* TARGET_ARM  */
+      {
+       if (offset1 == -4)
+         {
+           if ((REGNO (operands[1]) == (REGNO (operands[0]) + 1))
+               && ((REGNO (operands[0]) & 1) == 0))
+             return \"strd\\t%0, %1, [%2, %3]\";
+           else
+             return \"stm%(da%)\\t%2, {%0, %1}\";
+         }
+       else
+         {
+           if ((REGNO (operands[0]) == (REGNO (operands[1]) + 1))
+               && ((REGNO (operands[1]) & 1) == 0))
+             return \"strd\\t%1, %0, [%2]\";
+           else
+             return \"stm%(ia%)\\t%2, {%1, %0}\";
+         }
+      }
+  }"
+  [(set_attr "length" "4")]
+)
+
+(define_peephole2
+  [(set (match_operand:SI 2 "memory_operand" "")
+       (match_operand:SI 0 "arm_general_register_operand" ""))
+   (set (match_operand:SI 3 "memory_operand" "")
+       (match_operand:SI 1 "arm_general_register_operand" ""))]
+  "TARGET_32BIT && arm_arch7
+   && arm_legitimate_ldrd_p (operands[0], operands[1],
+                               operands[2], operands[3], false)"
+  [(parallel [(set (match_operand:SI 2 "memory_operand" "")
+                  (match_operand:SI 0 "arm_general_register_operand" ""))
+             (set (match_operand:SI 3 "memory_operand" "")
+                  (match_operand:SI 1 "arm_general_register_operand" ""))])]
+  ""
+)
index 4b061b36ec7ae1c288d8eb04b550e429a5f4229f..ffbc9f37466629962a51c33adf72ea1cd7fe8413 100644 (file)
@@ -1,3 +1,13 @@
+2011-06-10  Wei Guozhi  <carrot@google.com>
+
+       PR target/45335
+       * gcc.target/arm/pr45335.c: New test.
+       * gcc.target/arm/pr45335-2.c: New test.
+       * gcc.target/arm/pr45335-3.c: New test.
+       * gcc.target/arm/pr40457-1.c: Add another possible output "ldrd".
+       * gcc.target/arm/pr40457-2.c: Changed to store 3 words.
+       * gcc.target/arm/pr40457-3.c: Changed to store 3 words.
+
 2011-06-10  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/41769
index 815fd38f097549168d9c808b53917e7fade9ddb0..5ad4ff12a24e265de4a54cbc0bfaa240702a7b27 100644 (file)
@@ -7,4 +7,4 @@ int bar(int* p)
   return x;
 }
 
-/* { dg-final { scan-assembler "ldm" } } */
+/* { dg-final { scan-assembler "ldm|ldrd" } } */
index 187f7bf7f844f2816978d3c61473f7359053caa3..c2c665e7b6c2e3894443497eca94c934d9c2062a 100644 (file)
@@ -5,6 +5,7 @@ void foo(int* p)
 {
   p[0] = 1;
   p[1] = 0;
+  p[2] = 2;
 }
 
 /* { dg-final { scan-assembler "stm" } } */
index 9bd5a17befeb2257d48b2a87b4c8d4cdf4c57ddd..5e54124254fed4d98484c11c3dafba1a2f56ee5c 100644 (file)
@@ -5,6 +5,7 @@ void foo(int* p)
 {
   p[0] = 1;
   p[1] = 0;
+  p[2] = 2;
 }
 
 /* { dg-final { scan-assembler "stm" } } */