(movdf+1): Use new 'T' and 'U' constraints to determine when an ldd or std will have...
authorJeff Law <law@gcc.gnu.org>
Wed, 22 Jul 1992 20:04:55 +0000 (14:04 -0600)
committerJeff Law <law@gcc.gnu.org>
Wed, 22 Jul 1992 20:04:55 +0000 (14:04 -0600)
(movdf+1): Use new 'T' and 'U' constraints to
determine when an ldd or std will have a length of 1, and
therefore is eligible for use in some delay slots.
(uncond_branch): New attribute used for unconditional branches.
All unconditional branch patterns changed to use this attribute.
(define_delays and delay slot attributes): Do not allow
uncond_branch instructions in delay slots.  Do not allow fpload or
fpstore operations in a conditional branch delay slot.  Allow
fpload and fpstore in call, unconditional branch, and annuled
conditional branch delay slots.

From-SVN: r1663

gcc/config/sparc/sparc.md

index b918acd..9a34c35 100644 (file)
@@ -29,7 +29,7 @@
 ;; type "call_no_delay_slot" is a call followed by an unimp instruction.
 
 (define_attr "type"
-  "move,unary,binary,compare,load,store,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc"
+  "move,unary,binary,compare,load,store,uncond_branch,branch,call,call_no_delay_slot,address,fpload,fpstore,fp,fpcmp,fpmul,fpdiv,fpsqrt,multi,misc"
   (const_string "binary"))
 
 ;; Set true if insn uses call-clobbered intermediate register.
@@ -72,7 +72,7 @@
 ;; Attributes for instruction and branch scheduling
 
 (define_attr "in_call_delay" "false,true"
-  (cond [(eq_attr "type" "branch,call,call_no_delay_slot,multi")
+  (cond [(eq_attr "type" "uncond_branch,branch,call,call_no_delay_slot,multi")
                (const_string "false")
         (eq_attr "type" "load,fpload,store,fpstore")
                (if_then_else (eq_attr "length" "1")
 ;; branches.  This would allow us to remove the nop always inserted before
 ;; a floating point branch.
 
+
 (define_attr "in_branch_delay" "false,true"
-  (if_then_else (and (eq_attr "type" "!branch,call,call_no_delay_slot,multi")
+  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi,fpload,fpstore")
+                    (eq_attr "length" "1"))
+               (const_string "true")
+               (const_string "false")))
+
+(define_attr "in_uncond_branch_delay" "false,true"
+  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
+                    (eq_attr "length" "1"))
+               (const_string "true")
+               (const_string "false")))
+
+(define_attr "in_annul_branch_delay" "false,true"
+  (if_then_else (and (eq_attr "type" "!uncond_branch,branch,call,call_no_delay_slot,multi")
                     (eq_attr "length" "1"))
                (const_string "true")
                (const_string "false")))
 
 (define_delay (eq_attr "type" "branch")
   [(eq_attr "in_branch_delay" "true")
-   (nil) (eq_attr "in_branch_delay" "true")])
+   (nil) (eq_attr "in_annul_branch_delay" "true")])
 
+(define_delay (eq_attr "type" "uncond_branch")
+  [(eq_attr "in_uncond_branch_delay" "true")
+   (nil) (nil)])
+   
 ;; Function units of the SPARC
 
 ;; (define_function_unit {name} {num-units} {n-users} {test}
 }")
 
 (define_insn ""
-  [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand" "=f,r,Q,Q,f,&r,?f,?r")
-       (match_operand:DF 1 "reg_or_nonsymb_mem_operand" "f,r,f,r,Q,Q,r,f"))]
+  [(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)"
   "*
     return output_fp_move_double (operands);
   return output_move_double (operands);
 }"
-  [(set_attr "type" "fp,move,fpstore,store,fpload,load,multi,multi")
-   (set_attr "length" "2,2,3,3,3,3,3,3")])
+  [(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")])
 
 (define_insn ""
   [(set (mem:DF (match_operand:SI 0 "symbolic_operand" "i,i"))
   [(set (pc) (label_ref (match_operand 0 "" "")))]
   ""
   "b%* %l0%("
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "uncond_branch")])
 
 (define_expand "tablejump"
   [(parallel [(set (pc) (match_operand:SI 0 "register_operand" "r"))
    (use (reg:SI 15))]
   ""
   "jmp %%o7+%0%#"
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "uncond_branch")])
 
 (define_insn ""
   [(set (pc) (match_operand:SI 0 "address_operand" "p"))
    (use (label_ref (match_operand 1 "" "")))]
   ""
   "jmp %a0%#"
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "uncond_branch")])
 
 (define_insn ""
   [(set (pc) (label_ref (match_operand 0 "" "")))
    (set (reg:SI 15) (label_ref (match_dup 0)))]
   ""
   "call %l0%#"
-  [(set_attr "type" "branch")])
+  [(set_attr "type" "uncond_branch")])
 
 ;; This pattern recognizes the "instruction" that appears in 
 ;; a function call that wants a structure value, 
   [(set (pc) (match_operand:SI 0 "address_operand" "p"))]
   ""
  "jmp %a0%#"
- [(set_attr "type" "branch")])
+ [(set_attr "type" "uncond_branch")])
  
 (define_expand "nonlocal_goto"
   [(match_operand:SI 0 "general_operand" "")
         (match_operand:SI 1 "memory_operand" ""))
    (set (match_operand:SI 2 "register_operand" "r")
         (match_operand:SI 3 "memory_operand" ""))]
-  "registers_ok_for_ldd (operands[0], operands[2]) 
+  "registers_ok_for_ldd_peep (operands[0], operands[2]) 
    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
-   && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
+   && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))" 
   "ldd %1,%0")
 
 (define_peephole
         (match_operand:SI 1 "register_operand" "r"))
    (set (match_operand:SI 2 "memory_operand" "")
         (match_operand:SI 3 "register_operand" "r"))]
-  "registers_ok_for_ldd (operands[1], operands[3]) 
+  "registers_ok_for_ldd_peep (operands[1], operands[3]) 
    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
-   && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
+   && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
   "std %1,%0")
  
 (define_peephole
         (match_operand:SF 1 "memory_operand" ""))
    (set (match_operand:SF 2 "register_operand" "fr")
         (match_operand:SF 3 "memory_operand" ""))]
-  "registers_ok_for_ldd (operands[0], operands[2]) 
+  "registers_ok_for_ldd_peep (operands[0], operands[2]) 
    && ! MEM_VOLATILE_P (operands[1]) && ! MEM_VOLATILE_P (operands[3])
-   && memory_ok_for_ldd (XEXP (operands[1], 0), XEXP (operands[3], 0))"
+   && addrs_ok_for_ldd_peep (XEXP (operands[1], 0), XEXP (operands[3], 0))"
   "ldd %1,%0")
 
 (define_peephole
         (match_operand:SF 1 "register_operand" "fr"))
    (set (match_operand:SF 2 "memory_operand" "")
         (match_operand:SF 3 "register_operand" "fr"))]
-  "registers_ok_for_ldd (operands[1], operands[3]) 
+  "registers_ok_for_ldd_peep (operands[1], operands[3]) 
    && ! MEM_VOLATILE_P (operands[0]) && ! MEM_VOLATILE_P (operands[2])
-   && memory_ok_for_ldd (XEXP (operands[0], 0), XEXP (operands[2], 0))"
+   && addrs_ok_for_ldd_peep (XEXP (operands[0], 0), XEXP (operands[2], 0))"
   "std %1,%0")
 
 (define_peephole
         (match_operand:SI 1 "memory_operand" ""))
    (set (match_operand:SI 2 "register_operand" "r")
         (match_operand:SI 3 "memory_operand" ""))]
-  "registers_ok_for_ldd (operands[2], operands[0]) 
+  "registers_ok_for_ldd_peep (operands[2], operands[0]) 
    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
-   && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
+   && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
   "ldd %3,%2")
 
 (define_peephole
         (match_operand:SI 1 "register_operand" "r"))
    (set (match_operand:SI 2 "memory_operand" "")
         (match_operand:SI 3 "register_operand" "r"))]
-  "registers_ok_for_ldd (operands[3], operands[1]) 
+  "registers_ok_for_ldd_peep (operands[3], operands[1]) 
    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
-   && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
+   && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))" 
   "std %3,%2")
  
 (define_peephole
         (match_operand:SF 1 "memory_operand" ""))
    (set (match_operand:SF 2 "register_operand" "fr")
         (match_operand:SF 3 "memory_operand" ""))]
-  "registers_ok_for_ldd (operands[2], operands[0]) 
+  "registers_ok_for_ldd_peep (operands[2], operands[0]) 
    && ! MEM_VOLATILE_P (operands[3]) && ! MEM_VOLATILE_P (operands[1])
-   && memory_ok_for_ldd (XEXP (operands[3], 0), XEXP (operands[1], 0))"
+   && addrs_ok_for_ldd_peep (XEXP (operands[3], 0), XEXP (operands[1], 0))"
   "ldd %3,%2")
 
 (define_peephole
         (match_operand:SF 1 "register_operand" "fr"))
    (set (match_operand:SF 2 "memory_operand" "")
         (match_operand:SF 3 "register_operand" "fr"))]
-  "registers_ok_for_ldd (operands[3], operands[1]) 
+  "registers_ok_for_ldd_peep (operands[3], operands[1]) 
    && ! MEM_VOLATILE_P (operands[2]) && ! MEM_VOLATILE_P (operands[0])
-   && memory_ok_for_ldd (XEXP (operands[2], 0), XEXP (operands[0], 0))"
+   && addrs_ok_for_ldd_peep (XEXP (operands[2], 0), XEXP (operands[0], 0))"
   "std %3,%2")
  
 ;; Optimize the case of following a reg-reg move with a test