OSDN Git Service

(prepare_scc_operands): Force sh_compare_op1 to a register if
authorwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jan 1995 00:40:27 +0000 (00:40 +0000)
committerwilson <wilson@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 26 Jan 1995 00:40:27 +0000 (00:40 +0000)
it is an invalid constant.
(output_branch): Add cases for 4, 8, and 18.  Correct branch offsets
in comments.
(find_barrier): Correct test for move instructions that need to be
fixed by verifying that the set source is a bad constant.
(arith_reg_or_0_operand): New function.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@8824 138bc75d-0d04-0410-961f-82ee72b054a4

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

index fac1a76..afbbf6c 100644 (file)
@@ -832,6 +832,9 @@ prepare_scc_operands (code)
        }
 
       sh_compare_op0 = force_reg (SImode, sh_compare_op0);
+      if (code != EQ && code != NE && sh_compare_op1 != const0_rtx)
+       sh_compare_op1 = force_reg (SImode, sh_compare_op1);
+
       emit_insn (gen_rtx (SET, VOIDmode,
                          gen_rtx (REG, SImode, T_REG),
                   gen_rtx (code, SImode, sh_compare_op0, sh_compare_op1)));
@@ -1141,11 +1144,15 @@ output_branch (logic, insn)
   switch (get_attr_length (insn))
     {
     case 2:
-      /* Simple branch in range -200..+200 bytes */
+      /* A branch with an unfilled delay slot.  */
+    case 4:
+      /* Simple branch in range -252..+258 bytes */
       return logic ? "bt%.     %l0" : "bf%.    %l0";
 
     case 6:
-      /* Branch in range -4000..+4000 bytes */
+      /* A branch with an unfilled delay slot.  */
+    case 8:
+      /* Branch in range -4092..+4098 bytes */
       {
        rtx oldop = recog_operand[0];
 
@@ -1172,6 +1179,8 @@ output_branch (logic, insn)
       return "";
 
     case 16:
+      /* A branch with an unfilled delay slot.  */
+    case 18:
       /* Branches a long way away */
       {
        rtx oldop = recog_operand[0];
@@ -1859,8 +1868,11 @@ find_barrier (from)
       /* Count the length of this insn - we assume that all moves will
         be 2 bytes long, except the DIs */
 
-      if (GET_CODE (from) == INSN &&
-         GET_CODE (PATTERN (from)) == SET)
+      if (GET_CODE (from) == INSN
+         && GET_CODE (PATTERN (from)) == SET
+         && CONSTANT_P (SET_SRC (PATTERN (from)))
+         && (GET_CODE (SET_SRC (PATTERN (from))) != CONST_INT
+             || ! CONST_OK_FOR_I (INTVAL (SET_SRC (PATTERN (from))))))
        {
          rtx src = SET_SRC (PATTERN (from));
          if (hi_const (src))
@@ -2479,6 +2491,24 @@ arith_operand (op, mode)
   return 0;
 }
 
+/* Returns 1 if OP is a valid source operand for a compare insn.  */
+
+int
+arith_reg_or_0_operand (op, mode)
+     rtx op;
+     enum machine_mode mode;
+{
+  if (arith_reg_operand (op, mode))
+    return 1;
+
+  if (GET_CODE (op) == CONST_INT)
+    {
+      if (CONST_OK_FOR_N (INTVAL (op)))
+       return 1;
+    }
+  return 0;
+}
+
 
 /* Returns 1 if OP is a valid count operand for a shift operation. */
 int 
index d514746..1856907 100644 (file)
 ;; dmpy                double precision integer multiply
 ;; return      rts
 ;; pload       load of pr reg (can't be put into delay slot of rts)
-;; pcloadsi    pc relative load of SI value
-;; pcloadhi    pc relative load of HI value
+;; pcload      pc relative load of constant value
 ;; rte         return from exception
 ;; sfunc       special function call with known used registers
 
 (define_attr "type" 
- "cbranch,jump,arith,other,load,store,move,smpy,dmpy,return,pload,pcloadsi,pcloadhi,rte,sfunc"
+ "cbranch,jump,arith,other,load,store,move,smpy,dmpy,return,pload,pcload,rte,sfunc"
   (const_string "other"))
 
-; If a conditional branch destination is within -120..120 bytes away 
+; If a conditional branch destination is within -252..258 bytes away 
 ; from the instruction it can be 2 bytes long.  Something in the
-; range -4090..4090 bytes can be 6 bytes long, all other conditional
-; branches are 8 bytes long.
+; range -4090..4100 bytes can be 6 bytes long.  All other conditional
+; branches are 16 bytes long.
 
-; An unconditional jump which can reach forward or back 4k can be 
-; 6 bytes long (including the delay slot).  If it is too big, it
-; must be 10 bytes long.
+; An unconditional jump in the range -4092..4098 can be 2 bytes long.
+; Otherwise, it must be 14 bytes long.
 
-; If a pcrel instruction is within 500 bytes of the constant, then the insn is 
-; 2 bytes long, otherwise 12 bytes
 ; All other instructions are two bytes long by default.
 
+; All positive offsets have an adjustment added, which is the number of bytes
+; difference between this instruction length and the next larger instruction
+; length.  This is because shorten_branches starts with the largest
+; instruction size and then tries to reduce them.
+
 (define_attr "length" "" 
   (cond [(eq_attr "type" "cbranch")
-        (if_then_else (and (ge (minus (pc) (match_dup 0))
-                               (const_int -122))
-                           (le (minus (pc) (match_dup 0))
-                               (const_int 122)))
+        (if_then_else (and (ge (minus (match_dup 0) (pc))
+                               (const_int -252))
+                           (le (minus (match_dup 0) (pc))
+                               (const_int 262)))
                       (const_int 2)
-                      (if_then_else (and (ge (minus (pc) (match_dup 0))
+                      (if_then_else (and (ge (minus (match_dup 0) (pc))
                                              (const_int -4090))
-                                         (le (minus (pc) (match_dup 0))
-                                             (const_int 4090)))
+                                         (le (minus (match_dup 0) (pc))
+                                             (const_int 4110)))
                                     (const_int 6)
                                     (const_int 16)))
 
         (eq_attr "type" "jump")
-        (if_then_else (and (ge (minus (pc) (match_dup 0))
-                               (const_int -4090))
-                           (le (minus (pc) (match_dup 0))
-                               (const_int 4090)))
-                      (const_int 4)
-                      (const_int 10))
-        (eq_attr "type" "pcloadsi")
-        (if_then_else (gt (pc) (minus (match_dup 0) (const_int 1000)))
-                      (const_int 2)
-                      (const_int 12))
-        (eq_attr "type" "pcloadhi")
-        (if_then_else (gt (pc) (minus (match_dup 0) (const_int 500)))
+        (if_then_else (and (ge (minus (match_dup 0) (pc))
+                               (const_int -4092))
+                           (le (minus (match_dup 0) (pc))
+                               (const_int 4110)))
                       (const_int 2)
-                      (const_int 12))
-
+                      (const_int 14))
         ] (const_int 2)))
 
 ;; (define_function_unit {name} {num-units} {n-users} {test}
 ;;                       {ready-delay} {issue-delay} [{conflict-list}])
                                      
-(define_function_unit "memory" 1 0 (eq_attr "type" "load,pcloadsi,pcloadhi") 2 2)
+(define_function_unit "memory" 1 0 (eq_attr "type" "load,pcload") 2 2)
 (define_function_unit "mpy"    1 0 (eq_attr "type" "smpy") 7 7)
 (define_function_unit "mpy"    1 0 (eq_attr "type" "dmpy") 9 9)
 
        (eq_attr "cpu" "sh2,sh3"))
   [(eq_attr "in_delay_slot" "yes") (nil) (nil)])
 
-(define_attr "in_delay_slot" "maybe,yes,no" 
+(define_attr "in_delay_slot" "yes,no" 
   (cond [(eq_attr "type" "cbranch") (const_string "no")
         (eq_attr "type" "jump") (const_string "no")
         (eq_attr "type" "pload") (const_string "no")
-        (eq_attr "type" "pcloadsi") (const_string "no")
-        (eq_attr "type" "pcloadhi") (const_string "no")
+        (eq_attr "type" "pcload") (const_string "no")
         (eq_attr "type" "return") (const_string "no")
         (eq_attr "length" "2") (const_string "yes")
-        (eq_attr "length" "4,6,8,10,12") (const_string "no")
-        ] (const_string "yes")))
-
-
+        ] (const_string "no")))
 \f
 ;; -------------------------------------------------------------------------
 ;; SImode signed integer comparisons
   ""
   "movt        %0 !movt1")
 
-(define_insn ""
-  [(set (reg:SI 18) (gt:SI (match_operand:SI 0 "arith_reg_operand" "r")
-                          (const_int 0)))]
-  ""
-  "cmp/pl      %0")
-
-(define_insn ""
-  [(set (reg:SI 18) (ge:SI (match_operand:SI 0 "arith_reg_operand" "r")
-                          (const_int 0)))]
-  ""
-  "cmp/pz      %0")
-
-(define_insn "cmpeq_0"
-  [(set (reg:SI 18) (eq:SI (match_operand:SI 0 "arith_reg_operand" "r")
-                          (const_int 0)))]
-  ""
-  "tst %0,%0 ! t0")
-
 (define_insn "cmpeqsi_t"
-  [(set (reg:SI 18) (eq:SI (match_operand:SI 0 "arith_operand" "r,N,z,r")
-                          (match_operand:SI 1 "arith_operand" "N,r,rI,r")))]
+  [(set (reg:SI 18) (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
+                          (match_operand:SI 1 "arith_operand" "N,rI,r")))]
   ""
   "@
-       tst     %0,%0 !t1
-       tst     %1,%1 !t2
+       tst     %0,%0 ! t0
        cmp/eq  %1,%0
        cmp/eq  %1,%0")
 
 (define_insn "cmpgtsi_t"
   [(set (reg:SI 18) (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
-                          (match_operand:SI 1 "arith_operand" "N,r")))]
+                          (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
   ""
   "@
-       cmp/pl  %0
-       cmp/gt  %1,%0")
+       cmp/gt  %1,%0
+       cmp/pl  %0")
 
 (define_insn "cmpgesi_t"
   [(set (reg:SI 18) (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
-                          (match_operand:SI 1 "arith_operand" "N,r")))]
+                          (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
   ""
   "@
-       cmp/pz  %0
-       cmp/ge  %1,%0")
-
+       cmp/ge  %1,%0
+       cmp/pz  %0")
 \f
 ;; -------------------------------------------------------------------------
 ;; SImode unsigned integer comparisons
 ;; -------------------------------------------------------------------------
 
 (define_insn "cmpgeusi_t"
-  [(set (reg:SI 18) (geu:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
-                           (match_operand:SI 1 "arith_operand" "N,r")))]
+  [(set (reg:SI 18) (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
+                           (match_operand:SI 1 "arith_reg_operand" "r")))]
   ""
-  "@
-       cmp/pz  %1
-       cmp/hs  %1,%0")
+  "cmp/hs      %1,%0")
 
 (define_insn "cmpgtusi_t"
-  [(set (reg:SI 18) (gtu:SI (match_operand:SI 0 "arith_operand" "r,r")
-                           (match_operand:SI 1 "arith_operand" "N,r")))]
+  [(set (reg:SI 18) (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
+                           (match_operand:SI 1 "arith_reg_operand" "r")))]
   ""
-  "@
-       cmp/pl  %1
-       cmp/hi  %1,%0")
+  "cmp/hi      %1,%0")
 
 ;; We save the compare operands in the cmpxx patterns and use them when
 ;; we generate the branch.
                 (match_operand:SI 2 "arith_operand" "rI")))]
   ""
   "add %2,%0"
-  [(set_attr "length" "2")
-   (set_attr "type" "arith")])
+  [(set_attr "type" "arith")])
 
 (define_expand "addsi3"
   [(set (match_operand:SI 0 "arith_reg_operand" "=r")
   ""
   "jsr @%0%#"
   [(set_attr "type" "sfunc")
-   (set_attr "length" "4")
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "udivsi3"
   ""
   "jsr @%0%#"
   [(set_attr "type" "sfunc")
-   (set_attr "length" "4")
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "divsi3"
   ""
   "jsr @%0%#"
   [(set_attr "type" "sfunc")
-   (set_attr "length" "4")
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "mulsi3_call"
   "jsr @%1%#"
   [(set_attr "type" "sfunc")
    (set_attr "in_delay_slot" "no")
-   (set_attr "length" "4")
    (set_attr "needs_delay_slot" "yes")])
 
 (define_expand "ashrsi3"
        (neg:SI (plus:SI (reg:SI 18) (match_operand:SI 1 "arith_reg_operand" "r"))))]
   ""
   "negc        %1,%0"
-  [(set_attr "length" "2")
-   (set_attr "type" "arith")])
+  [(set_attr "type" "arith")])
 
 (define_expand "negdi2"
   [(set (match_operand:DI 0 "arith_reg_operand" "=r")
        lds.l   %1,%0
        tst     %1,%1\;bt       T%*\;bra        F%*\;sett\;T%*:clrt\;F%*:%^
        fake %1,%0"
-  [(set_attr "type" "pcloadsi,move,load,move,store,store,move,load,move,move,move")])
+  [(set_attr "type" "pcload,move,load,move,store,store,move,load,move,move,move")])
                          
 (define_expand "movsi"
   [(set (match_operand:SI 0 "general_movdst_operand" "")
        movt    %0
        sts     %1,%0
        lds     %1,%0"
- [(set_attr "length" "2,2,2,2,2,2")
-  (set_attr "type" "move,load,store,move,move,move")])
+ [(set_attr "type" "move,load,store,move,move,move")])
 
 (define_expand "movqi"
   [(set (match_operand:QI 0 "general_operand" "")
        fake %1,%0
        sts     %1,%0
        lds     %1,%0"
-  [(set_attr "length" "*,2,2,2,2,2,2,2")
-   (set_attr "type" "pcloadhi,move,load,move,store,move,move,move")])
+  [(set_attr "type" "pcload,move,load,move,store,move,move,move")])
 
 (define_expand "movhi"
   [(set (match_operand:HI 0 "general_movdst_operand" "")
   "register_operand (operands[0], DImode)
   || register_operand (operands[1], DImode)"
   "* return output_movedouble (insn, operands, DImode);"
-  [(set_attr "length" "*,4,4,4,4")
-   (set_attr "type" "pcloadsi,move,load,store,move")])
+  [(set_attr "length" "4")
+   (set_attr "type" "pcload,move,load,store,move")])
 
 ;; If the output is a register and the input is memory, we have to be careful
 ;; and see which word needs to be loaded first.
   ""
   "*
 {
-  if (get_attr_length(insn) == 10) 
+  /* The length is 16 if the delay slot is unfilled.  */
+  if (get_attr_length(insn) >= 14) 
     {
       return output_far_jump(insn, operands[0]);
     }
   "TARGET_BSR"
   "bsr %O0%#"
   [(set_attr "needs_delay_slot" "yes")
-   (set_attr "in_delay_slot" "no")
-   (set_attr "length" "4")])
+   (set_attr "in_delay_slot" "no")])
 
 (define_insn "calli"
   [(call (mem:SI (match_operand:SI 0 "arith_reg_operand" "r"))
   ""
   "jsr @%0%#"
   [(set_attr "needs_delay_slot" "yes")
-   (set_attr "in_delay_slot" "no")
-   (set_attr "length" "4")])
+   (set_attr "in_delay_slot" "no")])
 
 (define_insn "bsr_value"
   [(set (match_operand 0 "" "=rf")
   "TARGET_BSR"
   "bsr %O1%#"
   [(set_attr "needs_delay_slot" "yes")
-   (set_attr "in_delay_slot" "no")
-   (set_attr "length" "4")])
+   (set_attr "in_delay_slot" "no")])
 
 (define_insn "call_valuei"
   [(set (match_operand 0 "" "=rf")
   ""
   "jsr @%1%#"
   [(set_attr "needs_delay_slot" "yes")
-   (set_attr "in_delay_slot" "no")
-   (set_attr "length" "4")])
+   (set_attr "in_delay_slot" "no")])
 
 (define_expand "call"
   [(parallel[(call (match_operand 0 "arith_reg_operand" "o")
   ""
   "jmp @%0%#"
   [(set_attr "needs_delay_slot" "yes")
-   (set_attr "in_delay_slot" "no")
-   (set_attr "length" "4")])
+   (set_attr "in_delay_slot" "no")])
 
 \f
 ;; ------------------------------------------------------------------------
                                (match_operand:SI 1 "arith_operand" "")))
    (set (reg:SI 18)
        (gtu:SI (match_dup 5)
-               (match_operand:SI 2 "arith_operand" "")))
+               (match_operand:SI 2 "arith_reg_operand" "")))
    (set (pc)
        (if_then_else (eq (reg:SI 18)
                          (const_int 1))
    (set (match_operand:SI 2 "register_operand" "=r")
        (reg:SI 0))]
    ""
-   "mova       %O0,r0\;mov     r0,%1\;mov      r0,%2"
-   [(set_attr "length" "6")
-    (set_attr "in_delay_slot" "no")])
-
+   "mova       %O0,r0\;mov     r0,%1\;mov      r0,%2")
 
 ;; -------------------------------------------------------------------------
 ;; Combine patterns
              (clobber (reg:SI 0))])]
   ""
   "jsr @%0%#"
-  [(set_attr "length" "4")
-   (set_attr "type" "sfunc")
+  [(set_attr "type" "sfunc")
    (set_attr "needs_delay_slot" "yes")])
 
 (define_insn "block_lump_real"
              (clobber (reg:SI 0))])]
   ""
   "jsr @%0%#"
-  [(set_attr "length" "4")
-   (set_attr "type" "sfunc")
+  [(set_attr "type" "sfunc")
    (set_attr "needs_delay_slot" "yes")])
 
 (define_insn "mac"
               (const_int 0)))]
   "TARGET_SH2"
   "dt  %0")
-  
-       
-       
-       
-       
\ No newline at end of file