sh.c (calc_live_regs): Save fpscr only if target has FPU.
authorDhananjay R. Deshpande <dhananjayd@kpit.com>
Fri, 6 Dec 2002 20:10:50 +0000 (20:10 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Fri, 6 Dec 2002 20:10:50 +0000 (20:10 +0000)
2002-12-06 Dhananjay Deshpande <dhananjayd@kpit.com>

* gcc/config/sh/sh.c (calc_live_regs): Save fpscr only if target has
FPU.
(push): Generate push_fpscr.
(pop): Generate pop_fpscr.
* gcc/config/sh/sh.md : Add define_expand "push_fpscr", "pop_fpscr".
(fpu_switch): Add alternative to push fpscr.  Enable for TARGET_SH3E.

From-SVN: r59893

gcc/ChangeLog
gcc/config/sh/sh.c
gcc/config/sh/sh.md

index 8eaad55..612294c 100644 (file)
@@ -1,3 +1,12 @@
+2002-12-06 Dhananjay Deshpande <dhananjayd@kpit.com>
+
+       * gcc/config/sh/sh.c (calc_live_regs): Save fpscr only if target has
+       FPU.
+       (push): Generate push_fpscr.
+       (pop): Generate pop_fpscr.
+       * gcc/config/sh/sh.md : Add define_expand "push_fpscr", "pop_fpscr".
+       (fpu_switch): Add alternative to push fpscr.  Enable for TARGET_SH3E.
+
 Fri Dec  6 19:36:24 2002  J"orn Rennecke <joern.rennecke@superh.com>
 
        * sh.c (dump_table): DImode pool constants need only 32 bit alignment.
index 5a31c84..c33b57e 100644 (file)
@@ -4305,6 +4305,8 @@ push (rn)
   rtx x;
   if (rn == FPUL_REG)
     x = gen_push_fpul ();
+  else if (rn == FPSCR_REG)
+    x = gen_push_fpscr ();
   else if (TARGET_SH4 && TARGET_FMOVD && ! TARGET_FPU_SINGLE
           && FP_OR_XD_REGISTER_P (rn))
     {
@@ -4333,6 +4335,8 @@ pop (rn)
   rtx x;
   if (rn == FPUL_REG)
     x = gen_pop_fpul ();
+  else if (rn == FPSCR_REG)
+    x = gen_pop_fpscr ();
   else if (TARGET_SH4 && TARGET_FMOVD && ! TARGET_FPU_SINGLE
           && FP_OR_XD_REGISTER_P (rn))
     {
@@ -4431,7 +4435,9 @@ calc_live_regs (count_ptr, live_regs_mask)
                  && pr_live))
             && reg != STACK_POINTER_REGNUM && reg != ARG_POINTER_REGNUM
             && reg != RETURN_ADDRESS_POINTER_REGNUM
-            && reg != T_REG && reg != GBR_REG)
+            && reg != T_REG && reg != GBR_REG
+            /* Push fpscr only on targets which have FPU */
+            && (reg != FPSCR_REG || TARGET_FPU_ANY))
          : (/* Only push those regs which are used and need to be saved.  */
             (TARGET_SHCOMPACT
              && flag_pic
index 835b411..e545b0a 100644 (file)
   "TARGET_SH1 && ! TARGET_SH5"
   "")
 
+(define_expand "push_fpscr"
+  [(const_int 0)]
+  "TARGET_SH3E"
+  "
+{
+  rtx insn = emit_insn (gen_fpu_switch (gen_rtx (MEM, PSImode,
+                                                gen_rtx (PRE_DEC, Pmode,
+                                                         stack_pointer_rtx)),
+                                       get_fpscr_rtx ()));
+  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
+  DONE;
+}")
+
+(define_expand "pop_fpscr"
+  [(const_int 0)]
+  "TARGET_SH3E"
+  "
+{
+  rtx insn = emit_insn (gen_fpu_switch (get_fpscr_rtx (),
+                                       gen_rtx (MEM, PSImode,
+                                                gen_rtx (POST_INC, Pmode,
+                                                         stack_pointer_rtx))));
+  REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_INC, stack_pointer_rtx, NULL_RTX);
+  DONE;
+}")
+
 ;; These two patterns can happen as the result of optimization, when
 ;; comparisons get simplified to a move of zero or 1 into the T reg.
 ;; They don't disappear completely, because the T reg is a fixed hard reg.
 ;; The mac_gp type for r/!c might look a bit odd, but it actually schedules
 ;; like a mac -> gpr move.
 (define_insn "fpu_switch"
-  [(set (match_operand:PSI 0 "register_operand" "=c,c,r,c,c,r,m,r")
-       (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c"))]
-  "TARGET_SH4
+  [(set (match_operand:PSI 0 "general_movdst_operand" "=c,c,r,c,c,r,m,r,<")
+       (match_operand:PSI 1 "general_movsrc_operand" "c,>,m,m,r,r,r,!c,c"))]
+  "TARGET_SH3E
    && (! reload_completed
        || true_regnum (operands[0]) != FPSCR_REG
        || GET_CODE (operands[1]) != MEM
        lds     %1,fpscr
        mov     %1,%0
        mov.l   %1,%0
-       sts     fpscr,%0"
-  [(set_attr "length" "0,2,2,4,2,2,2,2")
-   (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp")])
+       sts     fpscr,%0
+       sts.l   fpscr,%0"
+  [(set_attr "length" "0,2,2,4,2,2,2,2,2")
+   (set_attr "type" "nil,mem_fpscr,load,mem_fpscr,gp_fpscr,move,store,mac_gp,store")])
 
 (define_split
   [(set (reg:PSI FPSCR_REG)