arm-protots.h (vfp_mem_operand): Rename ...
authorPaul Brook <paul@codesourcery.com>
Wed, 5 May 2004 23:11:55 +0000 (23:11 +0000)
committerPaul Brook <pbrook@gcc.gnu.org>
Wed, 5 May 2004 23:11:55 +0000 (23:11 +0000)
* config/arm/arm-protots.h (vfp_mem_operand): Rename ...
(arm_coproc_mem_operand): ... To this.
* config/arm/arm.c (arm_legitimate_address_p): Allow ldrd modes.
(arm_legitimate_index_p): Ditto.
(vfp_mem_operand): Rename ...
(arm_coproc_mem_operand): ... To this.  Handle writeback modes.
(vfp_secondary_reload_class): Use it.
(output_move_double): Use doubleword load/store instructions.
(arm_hard_regno_mode_ok): Only allow even reg pairs for ldrd.
* config/arm/arm.h (TARGET_LDRD): Define.
(EXTRA_CONSTRAINT_STR_ARM): Add 'Uy'.
* config/gcc/arm/arm.md (arm_movdi): Allow all valid memory operands.
New splitter for invalid doubleword loads.
* config/arm/iwmmxt.md (iwmmxt_arm_movdi): Use Uy constraint.
* config/arm/vfp.md (arm_movdi_vfp): Allow all valid memory operands.
* doc/md.texi: Document Uy constraint.

From-SVN: r81543

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/iwmmxt.md
gcc/config/arm/vfp.md
gcc/doc/md.texi

index 44e58d7c24014c3780f189fe2087a1c7c6b53bb2..05aa794899cf3afe5ffa62be978401d06618097c 100644 (file)
@@ -1,3 +1,22 @@
+2004-05-06  Paul Brook  <paul@codesourcery.com>
+
+       * config/arm/arm-protots.h (vfp_mem_operand): Rename ...
+       (arm_coproc_mem_operand): ... To this.
+       * config/arm/arm.c (arm_legitimate_address_p): Allow ldrd modes.
+       (arm_legitimate_index_p): Ditto.
+       (vfp_mem_operand): Rename ...
+       (arm_coproc_mem_operand): ... To this.  Handle writeback modes.
+       (vfp_secondary_reload_class): Use it.
+       (output_move_double): Use doubleword load/store instructions.
+       (arm_hard_regno_mode_ok): Only allow even reg pairs for ldrd.
+       * config/arm/arm.h (TARGET_LDRD): Define.
+       (EXTRA_CONSTRAINT_STR_ARM): Add 'Uy'.
+       * config/gcc/arm/arm.md (arm_movdi): Allow all valid memory operands.
+       New splitter for invalid doubleword loads.
+       * config/arm/iwmmxt.md (iwmmxt_arm_movdi): Use Uy constraint.
+       * config/arm/vfp.md (arm_movdi_vfp): Allow all valid memory operands.
+       * doc/md.texi: Document Uy constraint.
+
 2004-05-05  Jan Hubicka  <jh@suse.cz>
 
        PR opt/14980
index 0359fe7711687a347241d97fcccadb7768c5cced..0605803a3fe5223e3307ff7121d8bafd599f217c 100644 (file)
@@ -100,7 +100,7 @@ extern int cirrus_general_operand (rtx, enum machine_mode);
 extern int cirrus_register_operand (rtx, enum machine_mode);
 extern int cirrus_shift_const (rtx, enum machine_mode);
 extern int cirrus_memory_offset (rtx);
-extern int vfp_mem_operand (rtx);
+extern int arm_coproc_mem_operand (rtx, bool);
 extern int vfp_compare_operand (rtx, enum machine_mode);
 extern int arm_float_compare_operand (rtx, enum machine_mode);
 extern int arm_no_early_store_addr_dep (rtx, rtx);
index 02864fb28ea37016b642b258764b13fe38672aba..961dff2278ef7a9503520faa76194aaaff00870a 100644 (file)
@@ -2983,25 +2983,44 @@ int
 arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
                          int strict_p)
 {
+  bool use_ldrd;
+  enum rtx_code code = GET_CODE (x);
+  
   if (arm_address_register_rtx_p (x, strict_p))
     return 1;
 
-  else if (GET_CODE (x) == POST_INC || GET_CODE (x) == PRE_DEC)
+  use_ldrd = (TARGET_LDRD
+             && (mode == DImode
+                 || (mode == DFmode && (TARGET_SOFT_FLOAT || TARGET_VFP))));
+
+  if (code == POST_INC || code == PRE_DEC
+      || ((code == PRE_INC || code == POST_DEC)
+         && (use_ldrd || GET_MODE_SIZE (mode) <= 4)))
     return arm_address_register_rtx_p (XEXP (x, 0), strict_p);
 
-  else if ((GET_CODE (x) == POST_MODIFY || GET_CODE (x) == PRE_MODIFY)
-          && GET_MODE_SIZE (mode) <= 4
+  else if ((code == POST_MODIFY || code == PRE_MODIFY)
           && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
           && GET_CODE (XEXP (x, 1)) == PLUS
           && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
-    return arm_legitimate_index_p (mode, XEXP (XEXP (x, 1), 1), outer,
-                                  strict_p);
+    {
+      rtx addend = XEXP (XEXP (x, 1), 1);
+
+      /* Don't allow ldrd post increment by register becuase it's hard
+        to fixup invalid register choices.  */
+      if (use_ldrd
+         && GET_CODE (x) == POST_MODIFY
+         && GET_CODE (addend) == REG)
+       return 0;
+
+      return ((use_ldrd || GET_MODE_SIZE (mode) <= 4)
+             && arm_legitimate_index_p (mode, addend, outer, strict_p));
+    }
 
   /* After reload constants split into minipools will have addresses
      from a LABEL_REF.  */
   else if (reload_completed
-          && (GET_CODE (x) == LABEL_REF
-              || (GET_CODE (x) == CONST
+          && (code == LABEL_REF
+              || (code == CONST
                   && GET_CODE (XEXP (x, 0)) == PLUS
                   && GET_CODE (XEXP (XEXP (x, 0), 0)) == LABEL_REF
                   && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)))
@@ -3010,38 +3029,7 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
   else if (mode == TImode)
     return 0;
 
-  else if (mode == DImode || (TARGET_SOFT_FLOAT && mode == DFmode))
-    {
-      if (GET_CODE (x) == PLUS
-         && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
-         && GET_CODE (XEXP (x, 1)) == CONST_INT)
-       {
-         HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-
-          if (val == 4 || val == -4 || val == -8)
-           return 1;
-       }
-    }
-
-  else if (TARGET_HARD_FLOAT && TARGET_VFP && mode == DFmode)
-    {
-      if (GET_CODE (x) == PLUS
-         && arm_address_register_rtx_p (XEXP (x, 0), strict_p)
-         && GET_CODE (XEXP (x, 1)) == CONST_INT)
-       {
-         HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
-
-         /* ??? valid arm offsets are a subset of VFP offsets.
-            For now only allow this subset.  Proper fix is to add an
-            additional memory constraint for arm address modes.
-            Alternatively allow full vfp addressing and let
-            output_move_double fix it up with a sub-optimal sequence.  */
-          if (val == 4 || val == -4 || val == -8)
-           return 1;
-       }
-    }
-
-  else if (GET_CODE (x) == PLUS)
+  else if (code == PLUS)
     {
       rtx xop0 = XEXP (x, 0);
       rtx xop1 = XEXP (x, 1);
@@ -3065,17 +3053,12 @@ arm_legitimate_address_p (enum machine_mode mode, rtx x, RTX_CODE outer,
 #endif
 
   else if (GET_MODE_CLASS (mode) != MODE_FLOAT
-          && GET_CODE (x) == SYMBOL_REF
+          && code == SYMBOL_REF
           && CONSTANT_POOL_ADDRESS_P (x)
           && ! (flag_pic
                 && symbol_mentioned_p (get_pool_constant (x))))
     return 1;
 
-  else if ((GET_CODE (x) == PRE_INC || GET_CODE (x) == POST_DEC)
-          && (GET_MODE_SIZE (mode) <= 4)
-          && arm_address_register_rtx_p (XEXP (x, 0), strict_p))
-    return 1;
-
   return 0;
 }
 
@@ -3097,16 +3080,31 @@ arm_legitimate_index_p (enum machine_mode mode, rtx index, RTX_CODE outer,
            && INTVAL (index) > -1024
            && (INTVAL (index) & 3) == 0);
 
-  if (arm_address_register_rtx_p (index, strict_p)
-      && GET_MODE_SIZE (mode) <= 4)
-    return 1;
-
   if (TARGET_REALLY_IWMMXT && VALID_IWMMXT_REG_MODE (mode))
     return (code == CONST_INT
            && INTVAL (index) < 1024
            && INTVAL (index) > -1024
            && (INTVAL (index) & 3) == 0);
 
+  if (arm_address_register_rtx_p (index, strict_p)
+      && (GET_MODE_SIZE (mode) <= 4))
+    return 1;
+
+  if (mode == DImode || mode == DFmode)
+    {
+      if (code == CONST_INT)
+       {
+         HOST_WIDE_INT val = INTVAL (index);
+
+         if (TARGET_LDRD)
+           return val > -256 && val < 256;
+         else
+           return val == 4 || val == -4 || val == -8;
+       }
+
+      return TARGET_LDRD && arm_address_register_rtx_p (index, strict_p);
+    }
+
   if (GET_MODE_SIZE (mode) <= 4
       && ! (arm_arch4
            && (mode == HImode
@@ -4614,14 +4612,15 @@ cirrus_shift_const (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
 }
 
 
-/* Return TRUE if OP is a valid VFP memory address pattern.  */
-/* Copied from cirrus_memory_offset but with restricted offset range.  */
+/* Return TRUE if OP is a valid VFP memory address pattern.
+   WB if true if writeback address modes are allowed.  */
 
 int
-vfp_mem_operand (rtx op)
+arm_coproc_mem_operand (rtx op, bool wb)
 {
-  /* Reject eliminable registers.  */
+  rtx ind;
 
+  /* Reject eliminable registers.  */
   if (! (reload_in_progress || reload_completed)
       && (   reg_mentioned_p (frame_pointer_rtx, op)
          || reg_mentioned_p (arg_pointer_rtx, op)
@@ -4632,35 +4631,49 @@ vfp_mem_operand (rtx op)
     return FALSE;
 
   /* Constants are converted into offsets from labels.  */
-  if (GET_CODE (op) == MEM)
-    {
-      rtx ind;
-
-      ind = XEXP (op, 0);
+  if (GET_CODE (op) != MEM)
+    return FALSE;
 
-      if (reload_completed
-         && (GET_CODE (ind) == LABEL_REF
-             || (GET_CODE (ind) == CONST
-                 && GET_CODE (XEXP (ind, 0)) == PLUS
-                 && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
-                 && GET_CODE (XEXP (XEXP (ind, 0), 1)) == CONST_INT)))
-       return TRUE;
+  ind = XEXP (op, 0);
 
-      /* Match: (mem (reg)).  */
-      if (GET_CODE (ind) == REG)
-       return arm_address_register_rtx_p (ind, 0);
+  if (reload_completed
+      && (GET_CODE (ind) == LABEL_REF
+         || (GET_CODE (ind) == CONST
+             && GET_CODE (XEXP (ind, 0)) == PLUS
+             && GET_CODE (XEXP (XEXP (ind, 0), 0)) == LABEL_REF
+             && GET_CODE (XEXP (XEXP (ind, 0), 1)) == CONST_INT)))
+    return TRUE;
 
-      /* Match:
-        (mem (plus (reg)
-                   (const))).  */
-      if (GET_CODE (ind) == PLUS
-         && GET_CODE (XEXP (ind, 0)) == REG
-         && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
-         && GET_CODE (XEXP (ind, 1)) == CONST_INT
-         && INTVAL (XEXP (ind, 1)) > -1024
-         && INTVAL (XEXP (ind, 1)) <  1024)
-       return TRUE;
-    }
+  /* Match: (mem (reg)).  */
+  if (GET_CODE (ind) == REG)
+    return arm_address_register_rtx_p (ind, 0);
+
+  /* Autoincremment addressing modes.  */
+  if (wb
+      && (GET_CODE (ind) == PRE_INC
+         || GET_CODE (ind) == POST_INC
+         || GET_CODE (ind) == PRE_DEC
+         || GET_CODE (ind) == POST_DEC))
+    return arm_address_register_rtx_p (XEXP (ind, 0), 0);
+
+  if (wb
+      && (GET_CODE (ind) == POST_MODIFY || GET_CODE (ind) == PRE_MODIFY)
+      && arm_address_register_rtx_p (XEXP (ind, 0), 0)
+      && GET_CODE (XEXP (ind, 1)) == PLUS
+      && rtx_equal_p (XEXP (XEXP (ind, 1), 0), XEXP (ind, 0)))
+    ind = XEXP (ind, 1);
+
+  /* Match:
+     (plus (reg)
+          (const)).  */
+  if (GET_CODE (ind) == PLUS
+      && GET_CODE (XEXP (ind, 0)) == REG
+      && REG_MODE_OK_FOR_BASE_P (XEXP (ind, 0), VOIDmode)
+      && GET_CODE (XEXP (ind, 1)) == CONST_INT
+      && INTVAL (XEXP (ind, 1)) > -1024
+      && INTVAL (XEXP (ind, 1)) <  1024
+      && (INTVAL (XEXP (ind, 1)) & 3) == 0)
+    return TRUE;
 
   return FALSE;
 }
@@ -4684,7 +4697,7 @@ vfp_compare_operand (rtx op, enum machine_mode mode)
 enum reg_class
 vfp_secondary_reload_class (enum machine_mode mode, rtx x)
 {
-  if (vfp_mem_operand (x) || s_register_operand (x, mode))
+  if (arm_coproc_mem_operand (x, FALSE) || s_register_operand (x, mode))
     return NO_REGS;
 
   return GENERAL_REGS;
@@ -8384,7 +8397,9 @@ output_move_double (rtx *operands)
              break;
 
            case PRE_INC:
-             abort (); /* Should never happen now.  */
+             if (!TARGET_LDRD)
+               abort (); /* Should never happen now.  */
+             output_asm_insn ("ldr%?d\t%0, [%m1, #8]!", operands);
              break;
 
            case PRE_DEC:
@@ -8396,7 +8411,33 @@ output_move_double (rtx *operands)
              break;
 
            case POST_DEC:
-             abort (); /* Should never happen now.  */
+             if (!TARGET_LDRD)
+               abort (); /* Should never happen now.  */
+             output_asm_insn ("ldr%?d\t%0, [%m1], #-8", operands);
+             break;
+
+           case PRE_MODIFY:
+           case POST_MODIFY:
+             otherops[0] = operands[0];
+             otherops[1] = XEXP (XEXP (XEXP (operands[1], 0), 1), 0);
+             otherops[2] = XEXP (XEXP (XEXP (operands[1], 0), 1), 1);
+
+             if (GET_CODE (XEXP (operands[1], 0)) == PRE_MODIFY)
+               {
+                 if (reg_overlap_mentioned_p (otherops[0], otherops[2]))
+                   {
+                     /* Registers overlap so split out the increment.  */
+                     output_asm_insn ("add%?\t%1, %1, %2", otherops);
+                     output_asm_insn ("ldr%?d\t%0, [%1] @split", otherops);
+                   }
+                 else
+                   output_asm_insn ("ldr%?d\t%0, [%1, %2]!", otherops);
+               }
+             else
+               {
+                 /* We only allow constant increments, so this is safe.  */
+                 output_asm_insn ("ldr%?d\t%0, [%1], %2", otherops);
+               }
              break;
 
            case LABEL_REF:
@@ -8429,7 +8470,41 @@ output_move_double (rtx *operands)
                              output_asm_insn ("ldm%?ib\t%1, %M0", otherops);
                              return "";
                            }
-
+                       }
+                     if (TARGET_LDRD
+                         && (GET_CODE (otherops[2]) == REG
+                             || (GET_CODE (otherops[2]) == CONST_INT
+                                 && INTVAL (otherops[2]) > -256
+                                 && INTVAL (otherops[2]) < 256)))
+                       {
+                         if (reg_overlap_mentioned_p (otherops[0],
+                                                      otherops[2]))
+                           {
+                             /* Swap base and index registers over to
+                                avoid a conflict.  */
+                             otherops[1] = XEXP (XEXP (operands[1], 0), 1);
+                             otherops[2] = XEXP (XEXP (operands[1], 0), 0);
+                             
+                           }
+                         /* If both registers conflict, it will usually
+                            have been fixed by a splitter.  */
+                         if (reg_overlap_mentioned_p (otherops[0],
+                                                       otherops[2]))
+                           {
+                             output_asm_insn ("add%?\t%1, %1, %2", otherops);
+                             output_asm_insn ("ldr%?d\t%0, [%1]",
+                                              otherops);
+                             return "";
+                           }
+                         else
+                           {
+                             output_asm_insn ("ldr%?d\t%0, [%1, %2]",
+                                              otherops);
+                             return "";
+                           }
+                       }
+                     if (GET_CODE (otherops[2]) == CONST_INT)
+                       {
                          if (!(const_ok_for_arm (INTVAL (otherops[2]))))
                            output_asm_insn ("sub%?\t%0, %1, #%n2", otherops);
                          else
@@ -8475,7 +8550,9 @@ output_move_double (rtx *operands)
          break;
 
         case PRE_INC:
-         abort (); /* Should never happen now.  */
+         if (!TARGET_LDRD)
+           abort (); /* Should never happen now.  */
+         output_asm_insn ("str%?d\t%1, [%m0, #8]!", operands);
          break;
 
         case PRE_DEC:
@@ -8487,11 +8564,26 @@ output_move_double (rtx *operands)
          break;
 
         case POST_DEC:
-         abort (); /* Should never happen now.  */
+         if (!TARGET_LDRD)
+           abort (); /* Should never happen now.  */
+         output_asm_insn ("str%?d\t%1, [%m0], #-8", operands);
+         break;
+
+       case PRE_MODIFY:
+       case POST_MODIFY:
+         otherops[0] = operands[1];
+         otherops[1] = XEXP (XEXP (XEXP (operands[0], 0), 1), 0);
+         otherops[2] = XEXP (XEXP (XEXP (operands[0], 0), 1), 1);
+
+         if (GET_CODE (XEXP (operands[0], 0)) == PRE_MODIFY)
+           output_asm_insn ("str%?d\t%0, [%1, %2]!", otherops);
+         else
+           output_asm_insn ("str%?d\t%0, [%1], %2", otherops);
          break;
 
        case PLUS:
-         if (GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
+         otherops[2] = XEXP (XEXP (operands[0], 0), 1);
+         if (GET_CODE (otherops[2]) == CONST_INT)
            {
              switch ((int) INTVAL (XEXP (XEXP (operands[0], 0), 1)))
                {
@@ -8508,6 +8600,17 @@ output_move_double (rtx *operands)
                  return "";
                }
            }
+         if (TARGET_LDRD
+             && (GET_CODE (otherops[2]) == REG
+                 || (GET_CODE (otherops[2]) == CONST_INT
+                     && INTVAL (otherops[2]) > -256
+                     && INTVAL (otherops[2]) < 256)))
+           {
+             otherops[0] = operands[1];
+             otherops[1] = XEXP (XEXP (operands[0], 0), 0);
+             output_asm_insn ("str%?d\t%0, [%1, %2]", otherops);
+             return "";
+           }
          /* Fall through */
 
         default:
@@ -11393,9 +11496,11 @@ arm_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
   if (IS_IWMMXT_REGNUM (regno))
     return VALID_IWMMXT_REG_MODE (mode);
 
+  /* We allow any value to be stored in the general registers.
+     Restrict doubleword quantities to even register pairs so that we can
+     use ldrd.  */
   if (regno <= LAST_ARM_REGNUM)
-    /* We allow any value to be stored in the general registers.  */
-    return 1;
+    return !(TARGET_LDRD && GET_MODE_SIZE (mode) > 4 && (regno & 1) != 0);
 
   if (   regno == FRAME_POINTER_REGNUM
       || regno == ARG_POINTER_REGNUM)
index f64d3381b5ea69f35634fd60c4b1a10c4d1e3b4c..c870af0052f513f390b6ffc7dfa6cfa942aafda7 100644 (file)
@@ -306,6 +306,7 @@ extern GTY(()) rtx aof_pic_label;
                                         ? (target_flags & THUMB_FLAG_LEAF_BACKTRACE)   \
                                         : (target_flags & THUMB_FLAG_BACKTRACE))
 #define TARGET_CIRRUS_FIX_INVALID_INSNS        (target_flags & CIRRUS_FIX_INVALID_INSNS)
+#define TARGET_LDRD                    (arm_arch5e && ARM_DOUBLEWORD_ALIGN)
 
 /* SUBTARGET_SWITCHES is used to add flags on a per-config basis.  */
 #ifndef SUBTARGET_SWITCHES
@@ -1292,6 +1293,7 @@ enum reg_class
    accessed without using a load.
    'U' Prefixes an extended memory constraint where:
    'Uv' is an address valid for VFP load/store insns.  
+   'Uy' is an address valid for iwmmxt load/store insns.  
    'Uq' is an address valid for ldrsb.  */
 
 #define EXTRA_CONSTRAINT_STR_ARM(OP, C, STR)                   \
@@ -1302,7 +1304,8 @@ enum reg_class
                   && CONSTANT_POOL_ADDRESS_P (XEXP (OP, 0))) : \
    ((C) == 'S') ? (optimize > 0 && CONSTANT_ADDRESS_P (OP)) :  \
    ((C) == 'T') ? cirrus_memory_offset (OP) :                  \
-   ((C) == 'U' && (STR)[1] == 'v') ? vfp_mem_operand (OP) :    \
+   ((C) == 'U' && (STR)[1] == 'v') ? arm_coproc_mem_operand (OP, FALSE) : \
+   ((C) == 'U' && (STR)[1] == 'y') ? arm_coproc_mem_operand (OP, TRUE) : \
    ((C) == 'U' && (STR)[1] == 'q')                             \
     ? arm_extendqisi_mem_op (OP, GET_MODE (OP))                        \
       : 0)
index 7255b325997ee99c351b210dd0b6b367ac95f9e1..554b332283b08df1545d35019f4c8f1af9596b57 100644 (file)
 )
 
 (define_insn "*arm_movdi"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>")
+  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r ,m")
        (match_operand:DI 1 "di_operand"              "rIK,mi,r"))]
   "TARGET_ARM
   && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
    (set_attr "neg_pool_range" "*,1008,*")]
 )
 
+;; We can't actually do base+index doubleword loads if the index and
+;; destination overlap.  Split here so that we at least have chance to
+;; schedule.
+(define_split
+  [(set (match_operand:DI 0 "s_register_operand" "")
+       (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "")
+                        (match_operand:SI 2 "s_register_operand" ""))))]
+  "TARGET_LDRD
+  && reg_overlap_mentioned_p (operands[0], operands[1])
+  && reg_overlap_mentioned_p (operands[0], operands[2])"
+  [(set (match_dup 4)
+       (plus:SI (match_dup 1)
+                (match_dup 2)))
+   (set (match_dup 0)
+       (mem:DI (match_dup 4)))]
+  "
+  operands[4] = gen_rtx_REG (SImode, REGNO(operands[0]));
+  "
+)
+
 ;;; ??? This should have alternatives for constants.
 ;;; ??? This was originally identical to the movdf_insn pattern.
 ;;; ??? The 'i' constraint looks funny, but it should always be replaced by
index e1b00538c1fe2256ea99a41d1ad6bbf5fa50907b..758847fd54706994972608be1584104cfaa98273 100644 (file)
@@ -64,8 +64,8 @@
   [(set_attr "predicable" "yes")])
 
 (define_insn "*iwmmxt_arm_movdi"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>,y,y,yr,y,yrm")
-       (match_operand:DI 1 "di_operand"              "rIK,mi,r  ,y,yr,y,yrm,y"))]
+  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, m,y,y,yr,y,yrUy")
+       (match_operand:DI 1 "di_operand"              "rIK,mi,r,y,yr,y,yrUy,y"))]
   "TARGET_REALLY_IWMMXT"
   "*
 {
index 6f7e2a7a639c4e7b8d6a2488a64603ac691a1530..7008ab40c76b163d79845e7fbbceb736229d7a5d 100644 (file)
 ;; DImode moves
 
 (define_insn "*arm_movdi_vfp"
-  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,o<>,w,r,w,w  ,Uv")
-       (match_operand:DI 1 "di_operand"              "rIK,mi,r ,r,w,w,Uvi,w"))]
+  [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r,m,w,r,w,w, Uv")
+       (match_operand:DI 1 "di_operand"              "rIK,mi,r,r,w,w,Uvi,w"))]
   "TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP"
   "*
   switch (which_alternative)
index 5cff95bd2c22483de92432d4fed0b3763e11563b..b29f8b55fbc68c716706348afcb84f0d2da858b4 100644 (file)
@@ -1363,6 +1363,9 @@ A symbol in the text segment of the current file
 @item Uv
 A memory reference suitable for VFP load/store insns (reg+constant offset)
 
+@item Uy
+A memory reference suitable for iWMMXt load/store instructions.
+
 @item Uq
 A memory reference suitable for for the ARMv4 ldrsb instruction.