OSDN Git Service

* config/alpha/predicates.md (aligned_memory_operand): Mark
[pf3gnuchains/gcc-fork.git] / gcc / config / alpha / alpha.md
index b86a477..785082a 100644 (file)
    (UNSPECV_SC         16)     ; store-conditional
   ])
 
+;; On non-BWX targets, CQImode must be handled the similarly to HImode
+;; when generating reloads.
+(define_mode_macro RELOAD12 [QI HI CQI])
+(define_mode_attr reloadmode [(QI "qi") (HI "hi") (CQI "hi")])
+
+;; Other mode macros
+(define_mode_macro I12MODE [QI HI])
+(define_mode_macro I48MODE [SI DI])
+(define_mode_attr modesuffix [(SI "l") (DI "q")])
+
 ;; Where necessary, the suffixes _le and _be are used to distinguish between
 ;; little-endian and big-endian patterns.
 ;;
     DONE;
 })
 
-;; Here are the versions for reload.  Note that in the unaligned cases
-;; we know that the operand must not be a pseudo-register because stack
-;; slots are always aligned references.
-
-(define_expand "reload_inqi"
-  [(parallel [(match_operand:QI 0 "register_operand" "=r")
-             (match_operand:QI 1 "any_memory_operand" "m")
-             (match_operand:TI 2 "register_operand" "=&r")])]
-  "! TARGET_BWX"
+;; We need to hook into the extra support that we have for HImode 
+;; reloads when BWX insns are not available.
+(define_expand "movcqi"
+  [(set (match_operand:CQI 0 "nonimmediate_operand" "")
+       (match_operand:CQI 1 "general_operand" ""))]
+  "!TARGET_BWX"
 {
-  rtx scratch, seq;
-
-  if (aligned_memory_operand (operands[1], QImode))
+  if (GET_CODE (operands[0]) == CONCAT || GET_CODE (operands[1]) == CONCAT)
+    ;
+  else if (!any_memory_operand (operands[0], CQImode))
     {
-      seq = gen_reload_inqi_help (operands[0], operands[1],
-                                 gen_rtx_REG (SImode, REGNO (operands[2])));
+      if (!any_memory_operand (operands[1], CQImode))
+       {
+         emit_move_insn (gen_lowpart (HImode, operands[0]),
+                         gen_lowpart (HImode, operands[1]));
+         DONE;
+       }
+      if (aligned_memory_operand (operands[1], CQImode))
+       {
+         bool done;
+       do_aligned1:
+         operands[1] = gen_lowpart (HImode, operands[1]);
+       do_aligned2:
+         operands[0] = gen_lowpart (HImode, operands[0]);
+         done = alpha_expand_mov_nobwx (HImode, operands);
+         gcc_assert (done);
+         DONE;
+       }
     }
-  else
+  else if (aligned_memory_operand (operands[0], CQImode))
     {
-      rtx addr;
-
-      /* It is possible that one of the registers we got for operands[2]
-        might coincide with that of operands[0] (which is why we made
-        it TImode).  Pick the other one to use as our scratch.  */
-      if (REGNO (operands[0]) == REGNO (operands[2]))
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-      else
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
-
-      addr = get_unaligned_address (operands[1]);
-      operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
-      seq = gen_unaligned_loadqi (operands[0], addr, scratch, operands[0]);
-      alpha_set_memflags (seq, operands[1]);
+      if (MEM_P (operands[1]))
+       {
+         rtx x = gen_reg_rtx (HImode);
+         emit_move_insn (gen_lowpart (CQImode, x), operands[1]);
+         operands[1] = x;
+         goto do_aligned2;
+       }
+      goto do_aligned1;
     }
-  emit_insn (seq);
+
+  gcc_assert (!reload_in_progress);
+  emit_move_complex_parts (operands[0], operands[1]);
   DONE;
 })
 
-(define_expand "reload_inhi"
-  [(parallel [(match_operand:HI 0 "register_operand" "=r")
-             (match_operand:HI 1 "any_memory_operand" "m")
+;; Here are the versions for reload.
+;; 
+;; The aligned input case is recognized early in alpha_secondary_reload
+;; in order to avoid allocating an unnecessary scratch register.
+;; 
+;; Note that in the unaligned cases we know that the operand must not be
+;; a pseudo-register because stack slots are always aligned references.
+
+(define_expand "reload_in<mode>"
+  [(parallel [(match_operand:RELOAD12 0 "register_operand" "=r")
+             (match_operand:RELOAD12 1 "any_memory_operand" "m")
              (match_operand:TI 2 "register_operand" "=&r")])]
-  "! TARGET_BWX"
+  "!TARGET_BWX"
 {
-  rtx scratch, seq;
+  rtx scratch, seq, addr;
+  unsigned regno = REGNO (operands[2]);
 
-  if (aligned_memory_operand (operands[1], HImode))
-    {
-      seq = gen_reload_inhi_help (operands[0], operands[1],
-                                 gen_rtx_REG (SImode, REGNO (operands[2])));
-    }
-  else
-    {
-      rtx addr;
+  /* It is possible that one of the registers we got for operands[2]
+     might coincide with that of operands[0] (which is why we made
+     it TImode).  Pick the other one to use as our scratch.  */
+  if (regno == REGNO (operands[0]))
+    regno++;
+  scratch = gen_rtx_REG (DImode, regno);
 
-      /* It is possible that one of the registers we got for operands[2]
-        might coincide with that of operands[0] (which is why we made
-        it TImode).  Pick the other one to use as our scratch.  */
-      if (REGNO (operands[0]) == REGNO (operands[2]))
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-      else
-       scratch = gen_rtx_REG (DImode, REGNO (operands[2]));
+  addr = get_unaligned_address (operands[1]);
+  operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
+  seq = gen_unaligned_load<reloadmode> (operands[0], addr,
+                                       scratch, operands[0]);
+  alpha_set_memflags (seq, operands[1]);
 
-      addr = get_unaligned_address (operands[1]);
-      operands[0] = gen_rtx_REG (DImode, REGNO (operands[0]));
-      seq = gen_unaligned_loadhi (operands[0], addr, scratch, operands[0]);
-      alpha_set_memflags (seq, operands[1]);
-    }
   emit_insn (seq);
   DONE;
 })
 
-(define_expand "reload_outqi"
-  [(parallel [(match_operand:QI 0 "any_memory_operand" "=m")
-             (match_operand:QI 1 "register_operand" "r")
+(define_expand "reload_out<mode>"
+  [(parallel [(match_operand:RELOAD12 0 "any_memory_operand" "=m")
+             (match_operand:RELOAD12 1 "register_operand" "r")
              (match_operand:TI 2 "register_operand" "=&r")])]
   "! TARGET_BWX"
 {
-  if (aligned_memory_operand (operands[0], QImode))
-    {
-      emit_insn (gen_reload_outqi_help
-                (operands[0], operands[1],
-                 gen_rtx_REG (SImode, REGNO (operands[2])),
-                 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
-    }
-  else
-    {
-      rtx addr = get_unaligned_address (operands[0]);
-      rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
-      rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
-      rtx scratch3 = scratch1;
-      rtx seq;
-
-      if (GET_CODE (addr) == REG)
-       scratch1 = addr;
+  unsigned regno = REGNO (operands[2]);
 
-      seq = gen_unaligned_storeqi (addr, operands[1], scratch1,
-                                  scratch2, scratch3);
-      alpha_set_memflags (seq, operands[0]);
-      emit_insn (seq);
+  if (<MODE>mode == CQImode)
+    {
+      operands[0] = gen_lowpart (HImode, operands[0]);
+      operands[1] = gen_lowpart (HImode, operands[1]);
     }
-  DONE;
-})
 
-(define_expand "reload_outhi"
-  [(parallel [(match_operand:HI 0 "any_memory_operand" "=m")
-             (match_operand:HI 1 "register_operand" "r")
-             (match_operand:TI 2 "register_operand" "=&r")])]
-  "! TARGET_BWX"
-{
-  if (aligned_memory_operand (operands[0], HImode))
+  if (aligned_memory_operand (operands[0], <MODE>mode))
     {
-      emit_insn (gen_reload_outhi_help
+      emit_insn (gen_reload_out<reloadmode>_aligned
                 (operands[0], operands[1],
-                 gen_rtx_REG (SImode, REGNO (operands[2])),
-                 gen_rtx_REG (SImode, REGNO (operands[2]) + 1)));
+                 gen_rtx_REG (SImode, regno),
+                 gen_rtx_REG (SImode, regno + 1)));
     }
   else
     {
       rtx addr = get_unaligned_address (operands[0]);
-      rtx scratch1 = gen_rtx_REG (DImode, REGNO (operands[2]));
-      rtx scratch2 = gen_rtx_REG (DImode, REGNO (operands[2]) + 1);
+      rtx scratch1 = gen_rtx_REG (DImode, regno);
+      rtx scratch2 = gen_rtx_REG (DImode, regno + 1);
       rtx scratch3 = scratch1;
       rtx seq;
 
       if (GET_CODE (addr) == REG)
        scratch1 = addr;
 
-      seq = gen_unaligned_storehi (addr, operands[1], scratch1,
-                                  scratch2, scratch3);
+      seq = gen_unaligned_store<reloadmode> (addr, operands[1], scratch1,
+                                            scratch2, scratch3);
       alpha_set_memflags (seq, operands[0]);
       emit_insn (seq);
     }
 ;; always get a proper address for a stack slot during reload_foo
 ;; expansion, so we must delay our address manipulations until after.
 
-(define_insn_and_split "reload_inqi_help"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-        (match_operand:QI 1 "memory_operand" "m"))
-   (clobber (match_operand:SI 2 "register_operand" "=r"))]
-  "! TARGET_BWX && (reload_in_progress || reload_completed)"
+(define_insn_and_split "reload_in<mode>_aligned"
+  [(set (match_operand:I12MODE 0 "register_operand" "=r")
+        (match_operand:I12MODE 1 "memory_operand" "m"))]
+  "!TARGET_BWX && (reload_in_progress || reload_completed)"
   "#"
-  "! TARGET_BWX && reload_completed"
+  "!TARGET_BWX && reload_completed"
   [(const_int 0)]
 {
   rtx aligned_mem, bitnum;
   get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-  operands[0] = gen_lowpart (DImode, operands[0]);
-  emit_insn (gen_aligned_loadqi (operands[0], aligned_mem, bitnum,
-                                operands[2]));
-  DONE;
-})
-
-(define_insn_and_split "reload_inhi_help"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-        (match_operand:HI 1 "memory_operand" "m"))
-   (clobber (match_operand:SI 2 "register_operand" "=r"))]
-  "! TARGET_BWX && (reload_in_progress || reload_completed)"
-  "#"
-  "! TARGET_BWX && reload_completed"
-  [(const_int 0)]
-{
-  rtx aligned_mem, bitnum;
-  get_aligned_mem (operands[1], &aligned_mem, &bitnum);
-  operands[0] = gen_lowpart (DImode, operands[0]);
-  emit_insn (gen_aligned_loadhi (operands[0], aligned_mem, bitnum,
-                                operands[2]));
-  DONE;
-})
-
-(define_insn_and_split "reload_outqi_help"
-  [(set (match_operand:QI 0 "memory_operand" "=m")
-        (match_operand:QI 1 "register_operand" "r"))
-   (clobber (match_operand:SI 2 "register_operand" "=r"))
-   (clobber (match_operand:SI 3 "register_operand" "=r"))]
-  "! TARGET_BWX && (reload_in_progress || reload_completed)"
-  "#"
-  "! TARGET_BWX && reload_completed"
-  [(const_int 0)]
-{
-  rtx aligned_mem, bitnum;
-  get_aligned_mem (operands[0], &aligned_mem, &bitnum);
-  emit_insn (gen_aligned_store (aligned_mem, operands[1], bitnum,
-                               operands[2], operands[3]));
+  emit_insn (gen_aligned_load<reloadmode>
+            (gen_lowpart (DImode, operands[0]), aligned_mem, bitnum,
+             gen_rtx_REG (SImode, REGNO (operands[0]))));
   DONE;
 })
 
-(define_insn_and_split "reload_outhi_help"
-  [(set (match_operand:HI 0 "memory_operand" "=m")
-        (match_operand:HI 1 "register_operand" "r"))
+(define_insn_and_split "reload_out<mode>_aligned"
+  [(set (match_operand:I12MODE 0 "memory_operand" "=m")
+        (match_operand:I12MODE 1 "register_operand" "r"))
    (clobber (match_operand:SI 2 "register_operand" "=r"))
    (clobber (match_operand:SI 3 "register_operand" "=r"))]
-  "! TARGET_BWX && (reload_in_progress || reload_completed)"
+  "!TARGET_BWX && (reload_in_progress || reload_completed)"
   "#"
-  "! TARGET_BWX && reload_completed"
+  "!TARGET_BWX && reload_completed"
   [(const_int 0)]
 {
   rtx aligned_mem, bitnum;