(*): Make all fp patterns conditional on TARGET_FPU.
authorJim Wilson <wilson@gcc.gnu.org>
Mon, 11 Jan 1993 22:25:36 +0000 (14:25 -0800)
committerJim Wilson <wilson@gcc.gnu.org>
Mon, 11 Jan 1993 22:25:36 +0000 (14:25 -0800)
(movtf, movdf, movsf): Add !TARGET_FPU versions.
(sfmode return): Add pattern for when !TARGET_FPU.
(movsi+2, movsf+1): Use %@ instead of %%fp.
(mulsidi3, umulsidi3): Rewrite, to avoid extending constants.

From-SVN: r3195

gcc/config/sparc/sparc.md

index 33b50f9e2af2c5a5ae3090a791652a6d9113ef14..bef48086a2894ba15655d5e5bc7a00ebd445f373 100644 (file)
   [(set (reg:CCFP 0)
        (compare:CCFP (match_operand:SF 0 "register_operand" "")
                      (match_operand:SF 1 "register_operand" "")))]
-  ""
+  "TARGET_FPU"
   "
 {
   sparc_compare_op0 = operands[0];
   [(set (reg:CCFP 0)
        (compare:CCFP (match_operand:DF 0 "register_operand" "")
                      (match_operand:DF 1 "register_operand" "")))]
-  ""
+  "TARGET_FPU"
   "
 {
   sparc_compare_op0 = operands[0];
   [(set (reg:CCFP 0)
        (compare:CCFP (match_operand:TF 0 "register_operand" "")
                      (match_operand:TF 1 "register_operand" "")))]
-  ""
+  "TARGET_FPU"
   "
 {
   sparc_compare_op0 = operands[0];
   [(set (reg:CCFPE 0)
        (compare:CCFPE (match_operand:DF 0 "register_operand" "f")
                       (match_operand:DF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fcmped %0,%1"
   [(set_attr "type" "fpcmp")])
 
   [(set (reg:CCFPE 0)
        (compare:CCFPE (match_operand:SF 0 "register_operand" "f")
                       (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fcmpes %0,%1"
   [(set_attr "type" "fpcmp")])
 
   [(set (reg:CCFPE 0)
        (compare:CCFPE (match_operand:TF 0 "register_operand" "f")
                       (match_operand:TF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fcmpeq %0,%1"
   [(set_attr "type" "fpcmp")])
 
   [(set (reg:CCFP 0)
        (compare:CCFP (match_operand:DF 0 "register_operand" "f")
                      (match_operand:DF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fcmpd %0,%1"
   [(set_attr "type" "fpcmp")])
 
   [(set (reg:CCFP 0)
        (compare:CCFP (match_operand:SF 0 "register_operand" "f")
                      (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fcmps %0,%1"
   [(set_attr "type" "fpcmp")])
 
   [(set (reg:CCFP 0)
        (compare:CCFP (match_operand:TF 0 "register_operand" "f")
                      (match_operand:TF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fcmpq %0,%1"
   [(set_attr "type" "fpcmp")])
 
    ld %1,%0
    st %r1,%0
    st %r1,%0
-   st %r1,[%%fp-4]\;ld [%%fp-4],%0"
+   st %r1,[%@-4]\;ld [%@-4],%0"
   [(set_attr "type" "move,move,load,load,store,store,multi")
    (set_attr "length" "*,1,*,*,*,*,*")])
 
 (define_insn ""
   [(set (match_operand:TF 0 "general_operand" "=?r,f,o")
        (match_operand:TF 1 "" "?E,m,G"))]
-  "GET_CODE (operands[1]) == CONST_DOUBLE"
+  "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
   "*
 {
   switch (which_alternative)
 (define_insn ""
   [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
        (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
-  "register_operand (operands[0], TFmode)
-   || register_operand (operands[1], TFmode)"
+  "TARGET_FPU
+   && (register_operand (operands[0], TFmode)
+       || register_operand (operands[1], TFmode))"
   "*
 {
   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
   [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
    (set_attr "length" "4,4,5,5,5,5,5,5")])
 
+;; Exactly the same as above, except that all `f' cases are deleted.
+;; This is necessary to prevent reload from ever trying to use a `f' reg
+;; when -mno-fpu.
+
+(define_insn ""
+  [(set (match_operand:TF 0 "reg_or_nonsymb_mem_operand" "=r,Q,&r")
+       (match_operand:TF 1 "reg_or_nonsymb_mem_operand" "r,r,Q"))]
+  "! TARGET_FPU
+   && (register_operand (operands[0], TFmode)
+       || register_operand (operands[1], TFmode))"
+  "*
+{
+  if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
+    return output_fp_move_quad (operands);
+  return output_move_quad (operands);
+}"
+  [(set_attr "type" "move,store,load")
+   (set_attr "length" "4,5,5")])
+
 (define_insn ""
   [(set (mem:TF (match_operand:SI 0 "symbolic_operand" "i,i"))
        (match_operand:TF 1 "reg_or_0_operand" "rf,G"))
 ;; This pattern forces (set (reg:DF ...) (const_double ...))
 ;; to be reloaded by putting the constant into memory.
 ;; It must come before the more general movdf pattern.
+
 (define_insn ""
   [(set (match_operand:DF 0 "general_operand" "=?r,f,o")
        (match_operand:DF 1 "" "?E,m,G"))]
-  "GET_CODE (operands[1]) == CONST_DOUBLE"
+  "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
   "*
 {
   switch (which_alternative)
 (define_insn ""
   [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,f,r,Q,Q,f,&r,?f,?r")
        (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,f,r,f,r,Q,Q,r,f"))]
-  "register_operand (operands[0], DFmode)
-   || register_operand (operands[1], DFmode)"
+  "TARGET_FPU
+   && (register_operand (operands[0], DFmode)
+       || register_operand (operands[1], DFmode))"
   "*
 {
   if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
   [(set_attr "type" "fpstore,fpload,fp,move,fpstore,store,fpload,load,multi,multi")
    (set_attr "length" "1,1,2,2,3,3,3,3,3,3")])
 
+;; Exactly the same as above, except that all `f' cases are deleted.
+;; This is necessary to prevent reload from ever trying to use a `f' reg
+;; when -mno-fpu.
+
+(define_insn ""
+  [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=T,U,r,Q,&r")
+       (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "U,T,r,r,Q"))]
+  "! TARGET_FPU
+   && (register_operand (operands[0], DFmode)
+       || register_operand (operands[1], DFmode))"
+  "*
+{
+  if (FP_REG_P (operands[0]) || FP_REG_P (operands[1]))
+    return output_fp_move_double (operands);
+  return output_move_double (operands);
+}"
+  [(set_attr "type" "fpstore,fpload,move,store,load")
+   (set_attr "length" "1,1,2,3,3")])
+
 (define_insn ""
   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
        (match_operand:DF 1 "reg_or_0_operand" "rf,G"))
 (define_insn ""
   [(set (match_operand:SF 0 "general_operand" "=?r,f,m")
        (match_operand:SF 1 "" "?E,m,G"))]
-  "GET_CODE (operands[1]) == CONST_DOUBLE"
+  "TARGET_FPU && GET_CODE (operands[1]) == CONST_DOUBLE"
   "*
 {
   switch (which_alternative)
 (define_insn ""
   [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=f,r,rf,f,r,Q,Q")
        (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "f,r,!rf,Q,Q,f,r"))]
-  "register_operand (operands[0], SFmode)
-   || register_operand (operands[1], SFmode)"
+  "TARGET_FPU
+   && (register_operand (operands[0], SFmode)
+       || register_operand (operands[1], SFmode))"
   "@
    fmovs %1,%0
    mov %1,%0
-   st %r1,[%%fp-4]\;ld [%%fp-4],%0
+   st %r1,[%@-4]\;ld [%@-4],%0
    ld %1,%0
    ld %1,%0
    st %r1,%0
    st %r1,%0"
   [(set_attr "type" "fp,move,multi,fpload,load,fpstore,store")])
 
+;; Exactly the same as above, except that all `f' cases are deleted.
+;; This is necessary to prevent reload from ever trying to use a `f' reg
+;; when -mno-fpu.
+
+(define_insn ""
+  [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand" "=r,r,Q")
+       (match_operand:SF 1 "reg_or_nonsymb_mem_operand" "r,Q,r"))]
+  "! TARGET_FPU
+   && (register_operand (operands[0], SFmode)
+       || register_operand (operands[1], SFmode))"
+  "@
+   mov %1,%0
+   ld %1,%0
+   st %r1,%0"
+  [(set_attr "type" "move,load,store")])
+
 (define_insn ""
   [(set (mem:SF (match_operand:SI 0 "symbolic_operand" "i"))
        (match_operand:SF 1 "reg_or_0_operand" "rfG"))
   [(set (match_operand:DF 0 "register_operand" "=f")
        (float_extend:DF
         (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fstod %1,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:TF 0 "register_operand" "=f")
        (float_extend:TF
         (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fstoq %1,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:TF 0 "register_operand" "=f")
        (float_extend:TF
         (match_operand:DF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fdtoq %1,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "register_operand" "=f")
        (float_truncate:SF
         (match_operand:DF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fdtos %1,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "register_operand" "=f")
        (float_truncate:SF
         (match_operand:TF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fqtos %1,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:DF 0 "register_operand" "=f")
        (float_truncate:DF
         (match_operand:TF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fqtod %1,%0"
   [(set_attr "type" "fp")])
 \f
 (define_insn "floatsisf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (float:SF (match_operand:SI 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fitos %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "floatsidf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (float:DF (match_operand:SI 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fitod %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "floatsitf2"
   [(set (match_operand:TF 0 "register_operand" "=f")
        (float:TF (match_operand:SI 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fitox %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncsfsi2"
   [(set (match_operand:SI 0 "register_operand" "=f")
        (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
-  ""
+  "TARGET_FPU"
   "fstoi %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_truncdfsi2"
   [(set (match_operand:SI 0 "register_operand" "=f")
        (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
-  ""
+  "TARGET_FPU"
   "fdtoi %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "fix_trunctfsi2"
   [(set (match_operand:SI 0 "register_operand" "=f")
        (fix:SI (fix:TF (match_operand:TF 1 "register_operand" "f"))))]
-  ""
+  "TARGET_FPU"
   "fqtoi %1,%0"
   [(set_attr "type" "fp")])
 \f
   "TARGET_V8 || TARGET_SPARCLITE"
   "smulcc %1,%2,%0")
 
-(define_insn "mulsidi3"
+(define_expand "mulsidi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" ""))
+                (sign_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
+  "TARGET_V8 || TARGET_SPARCLITE"
+  "
+{
+  if (CONSTANT_P (operands[2]))
+    {
+      emit_insn (gen_const_mulsidi3 (operands[0], operands[1], operands[2]));
+      DONE;
+    }
+}")
+
+(define_insn ""
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
+                (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
+  "TARGET_V8 || TARGET_SPARCLITE"
+  "smul %1,%2,%R0\;rd %%y,%0"
+  [(set_attr "length" "2")])
+
+;; Extra pattern, because sign_extend of a constant isn't legal.
+
+(define_insn "const_mulsidi3"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+       (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
+                (match_operand:SI 2 "small_int" "I")))]
+  "TARGET_V8 || TARGET_SPARCLITE"
+  "smul %1,%2,%R0\;rd %%y,%0"
+  [(set_attr "length" "2")])
+
+(define_expand "umulsidi3"
+  [(set (match_operand:DI 0 "register_operand" "")
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" ""))
+                (zero_extend:DI (match_operand:SI 2 "arith_operand" ""))))]
+  "TARGET_V8 || TARGET_SPARCLITE"
+  "
+{
+  if (CONSTANT_P (operands[2]))
+    {
+      emit_insn (gen_const_umulsidi3 (operands[0], operands[1], operands[2]));
+      DONE;
+    }
+}")
+
+(define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_operand" "%r"))
-                (sign_extend:DI (match_operand:SI 2 "arith_operand" "rI"))))]
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+                (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
   "TARGET_V8 || TARGET_SPARCLITE"
-  "smul %1,%2,%R0\;rd %y,%0"
+  "umul %1,%2,%R0\;rd %%y,%0"
   [(set_attr "length" "2")])
 
-(define_insn "umulsidi3"
+;; Extra pattern, because sign_extend of a constant isn't legal.
+
+(define_insn "const_umulsidi3"
   [(set (match_operand:DI 0 "register_operand" "=r")
-       (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_operand" "%r"))
-                (zero_extend:DI (match_operand:SI 2 "arith_operand" "rI"))))]
+       (mult:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "r"))
+                (match_operand:SI 2 "small_int" "I")))]
   "TARGET_V8 || TARGET_SPARCLITE"
-  "umul %1,%2,%R0\;rd %y,%0"
+  "umul %1,%2,%R0\;rd %%y,%0"
   [(set_attr "length" "2")])
 
 ;; The architecture specifies that there must be 3 instructions between
   [(set (match_operand:TF 0 "register_operand" "=f")
        (plus:TF (match_operand:TF 1 "register_operand" "f")
                 (match_operand:TF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "faddq %1,%2,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:DF 0 "register_operand" "=f")
        (plus:DF (match_operand:DF 1 "register_operand" "f")
                 (match_operand:DF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "faddd %1,%2,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "register_operand" "=f")
        (plus:SF (match_operand:SF 1 "register_operand" "f")
                 (match_operand:SF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fadds %1,%2,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:TF 0 "register_operand" "=f")
        (minus:TF (match_operand:TF 1 "register_operand" "f")
                  (match_operand:TF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fsubq %1,%2,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:DF 0 "register_operand" "=f")
        (minus:DF (match_operand:DF 1 "register_operand" "f")
                  (match_operand:DF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fsubd %1,%2,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:SF 0 "register_operand" "=f")
        (minus:SF (match_operand:SF 1 "register_operand" "f")
                  (match_operand:SF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fsubs %1,%2,%0"
   [(set_attr "type" "fp")])
 
   [(set (match_operand:TF 0 "register_operand" "=f")
        (mult:TF (match_operand:TF 1 "register_operand" "f")
                 (match_operand:TF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fmulq %1,%2,%0"
   [(set_attr "type" "fpmul")])
 
   [(set (match_operand:DF 0 "register_operand" "=f")
        (mult:DF (match_operand:DF 1 "register_operand" "f")
                 (match_operand:DF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fmuld %1,%2,%0"
   [(set_attr "type" "fpmul")])
 
   [(set (match_operand:SF 0 "register_operand" "=f")
        (mult:SF (match_operand:SF 1 "register_operand" "f")
                 (match_operand:SF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fmuls %1,%2,%0"
   [(set_attr "type" "fpmul")])
 
   [(set (match_operand:TF 0 "register_operand" "=f")
        (div:TF (match_operand:TF 1 "register_operand" "f")
                (match_operand:TF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fdivq %1,%2,%0"
   [(set_attr "type" "fpdiv")])
 
   [(set (match_operand:DF 0 "register_operand" "=f")
        (div:DF (match_operand:DF 1 "register_operand" "f")
                (match_operand:DF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fdivd %1,%2,%0"
   [(set_attr "type" "fpdiv")])
 
   [(set (match_operand:SF 0 "register_operand" "=f")
        (div:SF (match_operand:SF 1 "register_operand" "f")
                (match_operand:SF 2 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fdivs %1,%2,%0"
   [(set_attr "type" "fpdiv")])
 
 (define_insn "negtf2"
   [(set (match_operand:TF 0 "register_operand" "=f,f")
        (neg:TF (match_operand:TF 1 "register_operand" "0,f")))]
-  ""
+  "TARGET_FPU"
   "@
    fnegs %0,%0
    fnegs %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
 (define_insn "negdf2"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
        (neg:DF (match_operand:DF 1 "register_operand" "0,f")))]
-  ""
+  "TARGET_FPU"
   "@
    fnegs %0,%0
    fnegs %1,%0\;fmovs %R1,%R0"
 (define_insn "negsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (neg:SF (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fnegs %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "abstf2"
   [(set (match_operand:TF 0 "register_operand" "=f,f")
        (abs:TF (match_operand:TF 1 "register_operand" "0,f")))]
-  ""
+  "TARGET_FPU"
   "@
    fabss %0,%0
    fabss %1,%0\;fmovs %R1,%R0\;fmovs %S1,%S0\;fmovs %T1,%T0"
 (define_insn "absdf2"
   [(set (match_operand:DF 0 "register_operand" "=f,f")
        (abs:DF (match_operand:DF 1 "register_operand" "0,f")))]
-  ""
+  "TARGET_FPU"
   "@
    fabss %0,%0
    fabss %1,%0\;fmovs %R1,%R0"
 (define_insn "abssf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (abs:SF (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fabss %1,%0"
   [(set_attr "type" "fp")])
 
 (define_insn "sqrttf2"
   [(set (match_operand:TF 0 "register_operand" "=f")
        (sqrt:TF (match_operand:TF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fsqrtq %1,%0"
   [(set_attr "type" "fpsqrt")])
 
 (define_insn "sqrtdf2"
   [(set (match_operand:DF 0 "register_operand" "=f")
        (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fsqrtd %1,%0"
   [(set_attr "type" "fpsqrt")])
 
 (define_insn "sqrtsf2"
   [(set (match_operand:SF 0 "register_operand" "=f")
        (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
-  ""
+  "TARGET_FPU"
   "fsqrts %1,%0"
   [(set_attr "type" "fpsqrt")])
 \f
 }"
   [(set_attr "type" "multi")])
 
+;; The following pattern is only generated by delayed-branch scheduling,
+;; when the insn winds up in the epilogue.  This can only happen when
+;; ! TARGET_FPU because otherwise fp return values are in %f0.
+(define_insn ""
+  [(set (match_operand:SF 0 "restore_operand" "r")
+       (match_operand:SF 1 "register_operand" "r"))
+   (return)]
+  "! TARGET_FPU && ! TARGET_EPILOGUE"
+  "*
+{
+  if (current_function_returns_struct)
+    return \"jmp %%i7+12\;restore %%g0,%1,%Y0\";
+  else
+    return \"ret\;restore %%g0,%1,%Y0\";
+}"
+  [(set_attr "type" "multi")])
+
 (define_insn ""
   [(set (match_operand:SI 0 "restore_operand" "")
        (plus:SI (match_operand:SI 1 "arith_operand" "%r")