diff options
Diffstat (limited to 'gcc/config/s390/s390.md')
-rw-r--r-- | gcc/config/s390/s390.md | 158 |
1 files changed, 120 insertions, 38 deletions
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 7d9d1ad7ecd..3b74e450c2f 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1,5 +1,5 @@ ;;- Machine description for GNU compiler -- S/390 / zSeries version. -;; Copyright (C) 1999-2014 Free Software Foundation, Inc. +;; Copyright (C) 1999-2015 Free Software Foundation, Inc. ;; Contributed by Hartmut Penner (hpenner@de.ibm.com) and ;; Ulrich Weigand (uweigand@de.ibm.com) and ;; Andreas Krebbel (Andreas.Krebbel@de.ibm.com) @@ -2389,7 +2389,7 @@ (use (match_operand 2 "" ""))])] "reload_completed" { - enum machine_mode mode; + machine_mode mode; int regno; int count; rtx from; @@ -2479,7 +2479,7 @@ (use (match_operand 2 "" ""))])] "reload_completed" { - enum machine_mode mode; + machine_mode mode; int regno; int count; rtx to; @@ -2825,8 +2825,8 @@ (clobber (reg:CC CC_REGNUM))])] "" { - enum machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode; - enum machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode; + machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode; + machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode; rtx reg0 = gen_reg_rtx (dreg_mode); rtx reg1 = gen_reg_rtx (dreg_mode); rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0)); @@ -3042,8 +3042,8 @@ (clobber (reg:CC CC_REGNUM))])] "" { - enum machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode; - enum machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode; + machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode; + machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode; rtx reg0 = gen_reg_rtx (dreg_mode); rtx reg1 = gen_reg_rtx (dreg_mode); rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0)); @@ -3215,8 +3215,8 @@ (use (match_dup 3))])] "" { - enum machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode; - enum machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode; + machine_mode sreg_mode = TARGET_ZARCH ? DImode : SImode; + machine_mode dreg_mode = TARGET_ZARCH ? TImode : DImode; rtx reg0 = gen_reg_rtx (dreg_mode); rtx reg1 = gen_reg_rtx (dreg_mode); rtx addr0 = gen_lowpart (Pmode, gen_highpart (sreg_mode, reg0)); @@ -4124,8 +4124,8 @@ { if (!TARGET_Z196) { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); + rtx_code_label *label2 = gen_label_rtx (); rtx temp = gen_reg_rtx (TDmode); REAL_VALUE_TYPE cmp, sub; @@ -4163,8 +4163,8 @@ { if (!TARGET_Z196) { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); + rtx_code_label *label2 = gen_label_rtx (); rtx temp = gen_reg_rtx (TDmode); REAL_VALUE_TYPE cmp, sub; @@ -4202,8 +4202,8 @@ { if (!TARGET_Z196) { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); + rtx_code_label *label2 = gen_label_rtx (); rtx temp = gen_reg_rtx (<BFP:MODE>mode); REAL_VALUE_TYPE cmp, sub; @@ -4406,6 +4406,18 @@ [(set_attr "op_type" "RRF") (set_attr "type" "ftruncsd")]) +(define_expand "trunctdsd2" + [(parallel + [(set (match_dup 3) + (float_truncate:DD (match_operand:TD 1 "register_operand" ""))) + (clobber (match_scratch:TD 2 ""))]) + (set (match_operand:SD 0 "register_operand" "") + (float_truncate:SD (match_dup 3)))] + "TARGET_HARD_DFP" +{ + operands[3] = gen_reg_rtx (DDmode); +}) + ; ; extend(sf|df)(df|tf)2 instruction pattern(s). ; @@ -4442,6 +4454,16 @@ [(set_attr "op_type" "RRF") (set_attr "type" "fsimptf")]) +(define_expand "extendsdtd2" + [(set (match_dup 2) + (float_extend:DD (match_operand:SD 1 "register_operand" ""))) + (set (match_operand:TD 0 "register_operand" "") + (float_extend:TD (match_dup 2)))] + "TARGET_HARD_DFP" +{ + operands[2] = gen_reg_rtx (DDmode); +}) + ; Binary Floating Point - load fp integer ; Expanders for: floor, btrunc, round, ceil, and nearbyint @@ -5045,10 +5067,10 @@ (match_operand:DI 2 "nonmemory_operand" "")))] "TARGET_64BIT" { - HOST_WIDE_INT c = INTVAL (operands[2]); - if (GET_CODE (operands[2]) == CONST_INT) { + HOST_WIDE_INT c = INTVAL (operands[2]); + if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K") && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os")) { @@ -5071,10 +5093,10 @@ (use (const_int 0))])] "!TARGET_64BIT" { - HOST_WIDE_INT c = INTVAL (operands[2]); - if (GET_CODE (operands[2]) == CONST_INT) { + HOST_WIDE_INT c = INTVAL (operands[2]); + if (!CONST_OK_FOR_CONSTRAINT_P (c, 'K', "K") && !CONST_OK_FOR_CONSTRAINT_P (c, 'O', "Os")) { @@ -6115,7 +6137,7 @@ { if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) { - rtx label1 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); operands[1] = make_safe_from (operands[1], operands[0]); emit_move_insn (operands[0], const0_rtx); @@ -6141,9 +6163,9 @@ } else { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx label3 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); + rtx_code_label *label2 = gen_label_rtx (); + rtx_code_label *label3 = gen_label_rtx (); operands[1] = force_reg (SImode, operands[1]); operands[1] = make_safe_from (operands[1], operands[0]); @@ -6201,7 +6223,7 @@ { if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) <= 0) { - rtx label1 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); operands[1] = make_safe_from (operands[1], operands[0]); emit_move_insn (operands[0], operands[1]); @@ -6228,9 +6250,9 @@ } else { - rtx label1 = gen_label_rtx (); - rtx label2 = gen_label_rtx (); - rtx label3 = gen_label_rtx (); + rtx_code_label *label1 = gen_label_rtx (); + rtx_code_label *label2 = gen_label_rtx (); + rtx_code_label *label3 = gen_label_rtx (); operands[1] = force_reg (SImode, operands[1]); operands[1] = make_safe_from (operands[1], operands[0]); @@ -7001,6 +7023,21 @@ "" "s390_expand_logical_operator (XOR, <MODE>mode, operands); DONE;") +; Combine replaces (xor (x) (const_int -1)) with (not (x)) when doing +; simplifications. So its better to have something matching. +(define_split + [(set (match_operand:INT 0 "nonimmediate_operand" "") + (not:INT (match_operand:INT 1 "nonimmediate_operand" "")))] + "" + [(parallel + [(set (match_dup 0) (xor:INT (match_dup 1) (match_dup 2))) + (clobber (reg:CC CC_REGNUM))])] +{ + operands[2] = constm1_rtx; + if (!s390_logical_operator_ok_p (operands)) + FAIL; +}) + ; ; xordi3 instruction pattern(s). ; @@ -7351,13 +7388,27 @@ [(set_attr "op_type" "RR<E>") (set_attr "z10prop" "z10_super_c_E1")]) -(define_insn_and_split "*negdi2_31" +(define_insn "*negdi2_31" [(set (match_operand:DI 0 "register_operand" "=d") (neg:DI (match_operand:DI 1 "register_operand" "d"))) (clobber (reg:CC CC_REGNUM))] "!TARGET_ZARCH" - "#" - "&& reload_completed" + "#") + +; Split a DImode NEG on 31bit into 2 SImode NEGs + +; Doing the twos complement separately on the SImode parts does an +; unwanted +1 on the high part which needs to be subtracted afterwards +; ... unless the +1 on the low part created an overflow. + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (neg:DI (match_operand:DI 1 "register_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH + && (REGNO (operands[0]) == REGNO (operands[1]) + || s390_split_ok_p (operands[0], operands[1], DImode, 0)) + && reload_completed" [(parallel [(set (match_dup 2) (neg:SI (match_dup 3))) (clobber (reg:CC CC_REGNUM))]) @@ -7379,6 +7430,40 @@ operands[5] = operand_subword (operands[1], 1, 0, DImode); operands[6] = gen_label_rtx ();") +; Like above but first make a copy of the low part of the src operand +; since it might overlap with the high part of the destination. + +(define_split + [(set (match_operand:DI 0 "register_operand" "") + (neg:DI (match_operand:DI 1 "register_operand" ""))) + (clobber (reg:CC CC_REGNUM))] + "!TARGET_ZARCH + && s390_split_ok_p (operands[0], operands[1], DImode, 1) + && reload_completed" + [; Make a backup of op5 first + (set (match_dup 4) (match_dup 5)) + ; Setting op2 here might clobber op5 + (parallel + [(set (match_dup 2) (neg:SI (match_dup 3))) + (clobber (reg:CC CC_REGNUM))]) + (parallel + [(set (reg:CCAP CC_REGNUM) + (compare:CCAP (neg:SI (match_dup 4)) (const_int 0))) + (set (match_dup 4) (neg:SI (match_dup 4)))]) + (set (pc) + (if_then_else (ne (reg:CCAP CC_REGNUM) (const_int 0)) + (pc) + (label_ref (match_dup 6)))) + (parallel + [(set (match_dup 2) (plus:SI (match_dup 2) (const_int -1))) + (clobber (reg:CC CC_REGNUM))]) + (match_dup 6)] + "operands[2] = operand_subword (operands[0], 0, 0, DImode); + operands[3] = operand_subword (operands[1], 0, 0, DImode); + operands[4] = operand_subword (operands[0], 1, 0, DImode); + operands[5] = operand_subword (operands[1], 1, 0, DImode); + operands[6] = gen_label_rtx ();") + ; ; neg(df|sf)2 instruction pattern(s). ; @@ -8057,16 +8142,13 @@ (define_expand "cbranchcc4" [(set (pc) - (if_then_else (match_operator 0 "s390_eqne_operator" + (if_then_else (match_operator 0 "s390_comparison" [(match_operand 1 "cc_reg_operand" "") - (match_operand 2 "const0_operand" "")]) + (match_operand 2 "const_int_operand" "")]) (label_ref (match_operand 3 "" "")) (pc)))] - "TARGET_HARD_FLOAT" - "s390_emit_jump (operands[3], - s390_emit_compare (GET_CODE (operands[0]), operands[1], operands[2])); - DONE;") - + "" + "") ;; @@ -9629,7 +9711,7 @@ UNSPECV_POOL_ENTRY)] "" { - enum machine_mode mode = GET_MODE (PATTERN (insn)); + machine_mode mode = GET_MODE (PATTERN (insn)); unsigned int align = GET_MODE_BITSIZE (mode); s390_output_pool_entry (operands[0], mode, align); return ""; |