aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJim Wilson <wilson@gcc.gnu.org>1995-01-25 16:40:27 -0800
committerJim Wilson <wilson@gcc.gnu.org>1995-01-25 16:40:27 -0800
commit22e1ebf1d7572cef04eea271121cb78f7e0eded5 (patch)
tree89824ef359f92c5da76052fc87e0f1e493a9fc00 /gcc
parent7374f95a9bed221260d498a52cfd3750820f363d (diff)
downloadgcc-22e1ebf1d7572cef04eea271121cb78f7e0eded5.zip
gcc-22e1ebf1d7572cef04eea271121cb78f7e0eded5.tar.gz
gcc-22e1ebf1d7572cef04eea271121cb78f7e0eded5.tar.bz2
(prepare_scc_operands): Force sh_compare_op1 to a register if it is an invalid constant.
(prepare_scc_operands): Force sh_compare_op1 to a register if 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. From-SVN: r8824
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/sh/sh.c38
-rw-r--r--gcc/config/sh/sh.md180
2 files changed, 95 insertions, 123 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index fac1a76..afbbf6c 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -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
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index d514746..1856907 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -71,64 +71,56 @@
;; 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)
@@ -154,18 +146,14 @@
(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")))
;; -------------------------------------------------------------------------
;; SImode signed integer comparisons
@@ -178,70 +166,46 @@
""
"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")
;; -------------------------------------------------------------------------
;; 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.
@@ -280,8 +244,7 @@
(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")
@@ -334,7 +297,6 @@
""
"jsr @%0%#"
[(set_attr "type" "sfunc")
- (set_attr "length" "4")
(set_attr "needs_delay_slot" "yes")])
(define_expand "udivsi3"
@@ -367,7 +329,6 @@
""
"jsr @%0%#"
[(set_attr "type" "sfunc")
- (set_attr "length" "4")
(set_attr "needs_delay_slot" "yes")])
(define_expand "divsi3"
@@ -449,7 +410,6 @@
""
"jsr @%0%#"
[(set_attr "type" "sfunc")
- (set_attr "length" "4")
(set_attr "needs_delay_slot" "yes")])
(define_expand "mulsi3_call"
@@ -720,7 +680,6 @@
"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"
@@ -832,8 +791,7 @@
(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")
@@ -1012,7 +970,7 @@
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" "")
@@ -1034,8 +992,7 @@
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" "")
@@ -1056,8 +1013,7 @@
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" "")
@@ -1079,8 +1035,8 @@
"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.
@@ -1373,7 +1329,8 @@
""
"*
{
- 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]);
}
@@ -1393,8 +1350,7 @@
"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"))
@@ -1403,8 +1359,7 @@
""
"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")
@@ -1414,8 +1369,7 @@
"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")
@@ -1425,8 +1379,7 @@
""
"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")
@@ -1449,8 +1402,7 @@
""
"jmp @%0%#"
[(set_attr "needs_delay_slot" "yes")
- (set_attr "in_delay_slot" "no")
- (set_attr "length" "4")])
+ (set_attr "in_delay_slot" "no")])
;; ------------------------------------------------------------------------
@@ -1507,7 +1459,7 @@
(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))
@@ -1700,10 +1652,7 @@
(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
@@ -1910,8 +1859,7 @@
(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"
@@ -1926,8 +1874,7 @@
(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"
@@ -1952,8 +1899,3 @@
(const_int 0)))]
"TARGET_SH2"
"dt %0")
-
-
-
-
- \ No newline at end of file