(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
This commit is contained in:
parent
7374f95a9b
commit
22e1ebf1d7
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
(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))
|
||||
(eq_attr "type" "pcloadhi")
|
||||
(if_then_else (gt (pc) (minus (match_dup 0) (const_int 500)))
|
||||
(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")
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue