mirror of git://gcc.gnu.org/git/gcc.git
s390.md ("*brx_stage1_<GPR:mode>", [...]): New patterns.
2009-08-20 Andreas Krebbel <krebbel1@de.ibm.com> * config/s390/s390.md ("*brx_stage1_<GPR:mode>", "*brxg_64bit", "*brx_64bit", "*brx_31bit"): New patterns. * config/s390/s390.c ('E'): New output modifier. From-SVN: r150954
This commit is contained in:
parent
a552b644fb
commit
f114923514
|
@ -1,3 +1,9 @@
|
||||||
|
2009-08-20 Andreas Krebbel <krebbel1@de.ibm.com>
|
||||||
|
|
||||||
|
* config/s390/s390.md ("*brx_stage1_<GPR:mode>", "*brxg_64bit",
|
||||||
|
"*brx_64bit", "*brx_31bit"): New patterns.
|
||||||
|
* config/s390/s390.c ('E'): New output modifier.
|
||||||
|
|
||||||
2009-08-20 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
2009-08-20 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
|
||||||
Richard Earnshaw <richard.earnshaw@arm.com>
|
Richard Earnshaw <richard.earnshaw@arm.com>
|
||||||
|
|
||||||
|
|
|
@ -197,6 +197,9 @@
|
||||||
(define_predicate "s390_scond_operator"
|
(define_predicate "s390_scond_operator"
|
||||||
(match_code "ltu, gtu, leu, geu"))
|
(match_code "ltu, gtu, leu, geu"))
|
||||||
|
|
||||||
|
(define_predicate "s390_brx_operator"
|
||||||
|
(match_code "le, gt"))
|
||||||
|
|
||||||
;; Return nonzero if OP is a valid comparison operator
|
;; Return nonzero if OP is a valid comparison operator
|
||||||
;; for an ALC condition.
|
;; for an ALC condition.
|
||||||
|
|
||||||
|
|
|
@ -4957,6 +4957,7 @@ print_operand_address (FILE *file, rtx addr)
|
||||||
|
|
||||||
'C': print opcode suffix for branch condition.
|
'C': print opcode suffix for branch condition.
|
||||||
'D': print opcode suffix for inverse branch condition.
|
'D': print opcode suffix for inverse branch condition.
|
||||||
|
'E': print opcode suffix for branch on index instruction.
|
||||||
'J': print tls_load/tls_gdcall/tls_ldcall suffix
|
'J': print tls_load/tls_gdcall/tls_ldcall suffix
|
||||||
'G': print the size of the operand in bytes.
|
'G': print the size of the operand in bytes.
|
||||||
'O': print only the displacement of a memory reference.
|
'O': print only the displacement of a memory reference.
|
||||||
|
@ -4989,6 +4990,15 @@ print_operand (FILE *file, rtx x, int code)
|
||||||
fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
|
fprintf (file, s390_branch_condition_mnemonic (x, TRUE));
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 'E':
|
||||||
|
if (GET_CODE (x) == LE)
|
||||||
|
fprintf (file, "l");
|
||||||
|
else if (GET_CODE (x) == GT)
|
||||||
|
fprintf (file, "h");
|
||||||
|
else
|
||||||
|
gcc_unreachable ();
|
||||||
|
return;
|
||||||
|
|
||||||
case 'J':
|
case 'J':
|
||||||
if (GET_CODE (x) == SYMBOL_REF)
|
if (GET_CODE (x) == SYMBOL_REF)
|
||||||
{
|
{
|
||||||
|
|
|
@ -7561,6 +7561,180 @@
|
||||||
;; This is all complicated by the fact that since this is a jump insn
|
;; This is all complicated by the fact that since this is a jump insn
|
||||||
;; we must handle our own output reloads.
|
;; we must handle our own output reloads.
|
||||||
|
|
||||||
|
;; branch on index
|
||||||
|
|
||||||
|
; This splitter will be matched by combine and has to add the 2 moves
|
||||||
|
; necessary to load the compare and the increment values into a
|
||||||
|
; register pair as needed by brxle.
|
||||||
|
|
||||||
|
(define_insn_and_split "*brx_stage1_<GPR:mode>"
|
||||||
|
[(set (pc)
|
||||||
|
(if_then_else
|
||||||
|
(match_operator 6 "s390_brx_operator"
|
||||||
|
[(plus:GPR (match_operand:GPR 1 "register_operand" "")
|
||||||
|
(match_operand:GPR 2 "general_operand" ""))
|
||||||
|
(match_operand:GPR 3 "register_operand" "")])
|
||||||
|
(label_ref (match_operand 0 "" ""))
|
||||||
|
(pc)))
|
||||||
|
(set (match_operand:GPR 4 "nonimmediate_operand" "")
|
||||||
|
(plus:GPR (match_dup 1) (match_dup 2)))
|
||||||
|
(clobber (match_scratch:GPR 5 ""))]
|
||||||
|
"TARGET_CPU_ZARCH"
|
||||||
|
"#"
|
||||||
|
"!reload_completed && !reload_in_progress"
|
||||||
|
[(set (match_dup 7) (match_dup 2)) ; the increment
|
||||||
|
(set (match_dup 8) (match_dup 3)) ; the comparison value
|
||||||
|
(parallel [(set (pc)
|
||||||
|
(if_then_else
|
||||||
|
(match_op_dup 6
|
||||||
|
[(plus:GPR (match_dup 1) (match_dup 7))
|
||||||
|
(match_dup 8)])
|
||||||
|
(label_ref (match_dup 0))
|
||||||
|
(pc)))
|
||||||
|
(set (match_dup 4)
|
||||||
|
(plus:GPR (match_dup 1) (match_dup 7)))
|
||||||
|
(clobber (match_dup 5))
|
||||||
|
(clobber (reg:CC CC_REGNUM))])]
|
||||||
|
{
|
||||||
|
rtx dreg = gen_reg_rtx (word_mode == DImode ? TImode : DImode);
|
||||||
|
operands[7] = gen_lowpart (<GPR:MODE>mode,
|
||||||
|
gen_highpart (word_mode, dreg));
|
||||||
|
operands[8] = gen_lowpart (<GPR:MODE>mode,
|
||||||
|
gen_lowpart (word_mode, dreg));
|
||||||
|
})
|
||||||
|
|
||||||
|
; brxlg, brxhg
|
||||||
|
|
||||||
|
(define_insn_and_split "*brxg_64bit"
|
||||||
|
[(set (pc)
|
||||||
|
(if_then_else
|
||||||
|
(match_operator 5 "s390_brx_operator"
|
||||||
|
[(plus:DI (match_operand:DI 1 "register_operand" "d,d,d")
|
||||||
|
(subreg:DI (match_operand:TI 2 "register_operand" "d,d,d") 0))
|
||||||
|
(subreg:DI (match_dup 2) 8)])
|
||||||
|
(label_ref (match_operand 0 "" ""))
|
||||||
|
(pc)))
|
||||||
|
(set (match_operand:DI 3 "nonimmediate_operand" "=1,?X,?X")
|
||||||
|
(plus:DI (match_dup 1)
|
||||||
|
(subreg:DI (match_dup 2) 0)))
|
||||||
|
(clobber (match_scratch:DI 4 "=X,&1,&?d"))
|
||||||
|
(clobber (reg:CC CC_REGNUM))]
|
||||||
|
"TARGET_64BIT"
|
||||||
|
{
|
||||||
|
if (which_alternative != 0)
|
||||||
|
return "#";
|
||||||
|
else if (get_attr_length (insn) == 6)
|
||||||
|
return "brx%E5g\t%1,%2,%l0";
|
||||||
|
else
|
||||||
|
return "agr\t%1,%2\;cgr\t%1,%M2\;jg%C5\t%l0";
|
||||||
|
}
|
||||||
|
"&& reload_completed
|
||||||
|
&& (!REG_P (operands[3])
|
||||||
|
|| !rtx_equal_p (operands[1], operands[3]))"
|
||||||
|
[(set (match_dup 4) (match_dup 1))
|
||||||
|
(parallel [(set (match_dup 4) (plus:DI (match_dup 4) (subreg:DI (match_dup 2) 0)))
|
||||||
|
(clobber (reg:CC CC_REGNUM))])
|
||||||
|
(set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:DI (match_dup 2) 8)))
|
||||||
|
(set (match_dup 3) (match_dup 4))
|
||||||
|
(set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
|
||||||
|
(label_ref (match_dup 0))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
[(set_attr "op_type" "RIE")
|
||||||
|
(set_attr "type" "branch")
|
||||||
|
(set (attr "length")
|
||||||
|
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
||||||
|
(const_int 6) (const_int 16)))])
|
||||||
|
|
||||||
|
; brxle, brxh
|
||||||
|
|
||||||
|
(define_insn_and_split "*brx_64bit"
|
||||||
|
[(set (pc)
|
||||||
|
(if_then_else
|
||||||
|
(match_operator 5 "s390_brx_operator"
|
||||||
|
[(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
|
||||||
|
(subreg:SI (match_operand:TI 2 "register_operand" "d,d,d") 4))
|
||||||
|
(subreg:SI (match_dup 2) 12)])
|
||||||
|
(label_ref (match_operand 0 "" ""))
|
||||||
|
(pc)))
|
||||||
|
(set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
|
||||||
|
(plus:SI (match_dup 1)
|
||||||
|
(subreg:SI (match_dup 2) 4)))
|
||||||
|
(clobber (match_scratch:SI 4 "=X,&1,&?d"))
|
||||||
|
(clobber (reg:CC CC_REGNUM))]
|
||||||
|
"TARGET_64BIT"
|
||||||
|
{
|
||||||
|
if (which_alternative != 0)
|
||||||
|
return "#";
|
||||||
|
else if (get_attr_length (insn) == 6)
|
||||||
|
return "brx%C5\t%1,%2,%l0";
|
||||||
|
else
|
||||||
|
return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
|
||||||
|
}
|
||||||
|
"&& reload_completed
|
||||||
|
&& (!REG_P (operands[3])
|
||||||
|
|| !rtx_equal_p (operands[1], operands[3]))"
|
||||||
|
[(set (match_dup 4) (match_dup 1))
|
||||||
|
(parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 4)))
|
||||||
|
(clobber (reg:CC CC_REGNUM))])
|
||||||
|
(set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 12)))
|
||||||
|
(set (match_dup 3) (match_dup 4))
|
||||||
|
(set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
|
||||||
|
(label_ref (match_dup 0))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
[(set_attr "op_type" "RSI")
|
||||||
|
(set_attr "type" "branch")
|
||||||
|
(set (attr "length")
|
||||||
|
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
||||||
|
(const_int 6) (const_int 14)))])
|
||||||
|
|
||||||
|
; brxle, brxh
|
||||||
|
|
||||||
|
(define_insn_and_split "*brx_31bit"
|
||||||
|
[(set (pc)
|
||||||
|
(if_then_else
|
||||||
|
(match_operator 5 "s390_brx_operator"
|
||||||
|
[(plus:SI (match_operand:SI 1 "register_operand" "d,d,d")
|
||||||
|
(subreg:SI (match_operand:DI 2 "register_operand" "d,d,d") 0))
|
||||||
|
(subreg:SI (match_dup 2) 4)])
|
||||||
|
(label_ref (match_operand 0 "" ""))
|
||||||
|
(pc)))
|
||||||
|
(set (match_operand:SI 3 "nonimmediate_operand" "=1,?X,?X")
|
||||||
|
(plus:SI (match_dup 1)
|
||||||
|
(subreg:SI (match_dup 2) 0)))
|
||||||
|
(clobber (match_scratch:SI 4 "=X,&1,&?d"))
|
||||||
|
(clobber (reg:CC CC_REGNUM))]
|
||||||
|
"!TARGET_64BIT && TARGET_CPU_ZARCH"
|
||||||
|
{
|
||||||
|
if (which_alternative != 0)
|
||||||
|
return "#";
|
||||||
|
else if (get_attr_length (insn) == 6)
|
||||||
|
return "brx%C5\t%1,%2,%l0";
|
||||||
|
else
|
||||||
|
return "ar\t%1,%2\;cr\t%1,%M2\;jg%C5\t%l0";
|
||||||
|
}
|
||||||
|
"&& reload_completed
|
||||||
|
&& (!REG_P (operands[3])
|
||||||
|
|| !rtx_equal_p (operands[1], operands[3]))"
|
||||||
|
[(set (match_dup 4) (match_dup 1))
|
||||||
|
(parallel [(set (match_dup 4) (plus:SI (match_dup 4) (subreg:SI (match_dup 2) 0)))
|
||||||
|
(clobber (reg:CC CC_REGNUM))])
|
||||||
|
(set (reg:CCS CC_REGNUM) (compare:CCS (match_dup 4) (subreg:SI (match_dup 2) 4)))
|
||||||
|
(set (match_dup 3) (match_dup 4))
|
||||||
|
(set (pc) (if_then_else (match_op_dup 5 [(reg:CCS CC_REGNUM) (const_int 0)])
|
||||||
|
(label_ref (match_dup 0))
|
||||||
|
(pc)))]
|
||||||
|
""
|
||||||
|
[(set_attr "op_type" "RSI")
|
||||||
|
(set_attr "type" "branch")
|
||||||
|
(set (attr "length")
|
||||||
|
(if_then_else (lt (abs (minus (pc) (match_dup 0))) (const_int 60000))
|
||||||
|
(const_int 6) (const_int 14)))])
|
||||||
|
|
||||||
|
|
||||||
|
;; branch on count
|
||||||
|
|
||||||
(define_expand "doloop_end"
|
(define_expand "doloop_end"
|
||||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||||
|
|
Loading…
Reference in New Issue