From f1149235142d434a76ceec242944c85c9749d3d4 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Thu, 20 Aug 2009 09:19:53 +0000 Subject: [PATCH] s390.md ("*brx_stage1_", [...]): New patterns. 2009-08-20 Andreas Krebbel * config/s390/s390.md ("*brx_stage1_", "*brxg_64bit", "*brx_64bit", "*brx_31bit"): New patterns. * config/s390/s390.c ('E'): New output modifier. From-SVN: r150954 --- gcc/ChangeLog | 6 ++ gcc/config/s390/predicates.md | 3 + gcc/config/s390/s390.c | 10 ++ gcc/config/s390/s390.md | 174 ++++++++++++++++++++++++++++++++++ 4 files changed, 193 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 51f783e16e0f..f35ed54663d5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2009-08-20 Andreas Krebbel + + * config/s390/s390.md ("*brx_stage1_", "*brxg_64bit", + "*brx_64bit", "*brx_31bit"): New patterns. + * config/s390/s390.c ('E'): New output modifier. + 2009-08-20 Ramana Radhakrishnan Richard Earnshaw diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index d09c9b3e161c..9d619fbc0990 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -197,6 +197,9 @@ (define_predicate "s390_scond_operator" (match_code "ltu, gtu, leu, geu")) +(define_predicate "s390_brx_operator" + (match_code "le, gt")) + ;; Return nonzero if OP is a valid comparison operator ;; for an ALC condition. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 25203ab52b6c..1431bfde7017 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -4957,6 +4957,7 @@ print_operand_address (FILE *file, rtx addr) 'C': print opcode suffix for 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 'G': print the size of the operand in bytes. '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)); 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': if (GET_CODE (x) == SYMBOL_REF) { diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index b6a54469498d..7898dc569a3a 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -7561,6 +7561,180 @@ ;; This is all complicated by the fact that since this is a jump insn ;; 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_" + [(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 (mode, + gen_highpart (word_mode, dreg)); + operands[8] = gen_lowpart (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" [(use (match_operand 0 "" "")) ; loop pseudo (use (match_operand 1 "" "")) ; iterations; zero if unknown -- 2.43.5