diff options
author | Ulrich Weigand <uweigand@de.ibm.com> | 2004-10-01 21:48:13 +0000 |
---|---|---|
committer | Ulrich Weigand <uweigand@gcc.gnu.org> | 2004-10-01 21:48:13 +0000 |
commit | 5b022de53cab42a3f5a4637c595cddc155175a13 (patch) | |
tree | 979c2e664ba91ff465eec4d87e6f8ac3ecd5d58c /gcc | |
parent | abccc4f66c34723d4f91654a3a52cc1b50effebc (diff) | |
download | gcc-5b022de53cab42a3f5a4637c595cddc155175a13.zip gcc-5b022de53cab42a3f5a4637c595cddc155175a13.tar.gz gcc-5b022de53cab42a3f5a4637c595cddc155175a13.tar.bz2 |
s390-protos.h (s390_comparison): Add prototype.
* config/s390/s390-protos.h (s390_comparison): Add prototype.
* config/s390/s390.c (s390_comparison): New function.
(s390_branch_condition_mask): Return -1 for invalid comparisons.
(s390_branch_condition_mnemonic): Assert valid comparison.
* config/s390/s390.h (PREDICATE_CODES): Add s390_comparison.
* config/s390/s390.md ("*cjump_64", "*cjump_31", "*cjump_long",
"*icjump_64", "*icjump_31", "*icjump_long", "*trap"): Use
s390_comparison instead of comparison_operator.
* config/s390/s390.md (UNSPEC_CMPINT): New constant.
("cmpmemdi"): Remove.
("cmpmem_short", "*cmpmem_short"): Use CCUmode instead of CCSmode.
("cmpmem_long", "*cmpmem_long_64", "*cmpmem_long_31"): Likewise.
("cmpint_si"): Rename to ...
("*cmpint_si"): ... this. Use UNSPEC_CMPINT.
("cmpint_di", "*cmpint_di"): Likewise.
* config/s390/s390.c (s390_canonicalize_comparison): Remove
redundant UNSPEC_CMPINT conversions.
(s390_expand_cmpmem): Adapt to cmpint pattern changes.
From-SVN: r88410
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 22 | ||||
-rw-r--r-- | gcc/config/s390/s390-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/s390/s390.c | 109 | ||||
-rw-r--r-- | gcc/config/s390/s390.h | 3 | ||||
-rw-r--r-- | gcc/config/s390/s390.md | 53 |
5 files changed, 120 insertions, 68 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4abd51e..9e3acb9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,25 @@ +2004-10-01 Ulrich Weigand <uweigand@de.ibm.com> + + * config/s390/s390-protos.h (s390_comparison): Add prototype. + * config/s390/s390.c (s390_comparison): New function. + (s390_branch_condition_mask): Return -1 for invalid comparisons. + (s390_branch_condition_mnemonic): Assert valid comparison. + * config/s390/s390.h (PREDICATE_CODES): Add s390_comparison. + * config/s390/s390.md ("*cjump_64", "*cjump_31", "*cjump_long", + "*icjump_64", "*icjump_31", "*icjump_long", "*trap"): Use + s390_comparison instead of comparison_operator. + + * config/s390/s390.md (UNSPEC_CMPINT): New constant. + ("cmpmemdi"): Remove. + ("cmpmem_short", "*cmpmem_short"): Use CCUmode instead of CCSmode. + ("cmpmem_long", "*cmpmem_long_64", "*cmpmem_long_31"): Likewise. + ("cmpint_si"): Rename to ... + ("*cmpint_si"): ... this. Use UNSPEC_CMPINT. + ("cmpint_di", "*cmpint_di"): Likewise. + * config/s390/s390.c (s390_canonicalize_comparison): Remove + redundant UNSPEC_CMPINT conversions. + (s390_expand_cmpmem): Adapt to cmpint pattern changes. + 2004-10-01 Kazu Hirata <kazu@cs.umass.edu> * collect2.c (COLLECT_PARSE_FLAG): Remove. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index 8846f25..78b90a8 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -51,6 +51,7 @@ extern int s390_match_ccmode (rtx, enum machine_mode); extern enum machine_mode s390_tm_ccmode (rtx, rtx, int); extern enum machine_mode s390_select_ccmode (enum rtx_code, rtx, rtx); extern void s390_canonicalize_comparison (enum rtx_code *, rtx *, rtx *); +extern int s390_comparison (rtx op, enum machine_mode mode); extern int s390_alc_comparison (rtx op, enum machine_mode mode); extern int s390_slb_comparison (rtx op, enum machine_mode mode); extern rtx s390_emit_compare (enum rtx_code, rtx, rtx); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 411b06f..21679c3 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -592,7 +592,6 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1) } /* Narrow comparisons against 0xffff to HImode if possible. */ - if ((*code == EQ || *code == NE) && GET_CODE (*op1) == CONST_INT && INTVAL (*op1) == 0xffff @@ -603,6 +602,35 @@ s390_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1) *op0 = gen_lowpart (HImode, *op0); *op1 = constm1_rtx; } + + + /* Remove redundant UNSPEC_CMPINT conversions if possible. */ + if (GET_CODE (*op0) == UNSPEC + && XINT (*op0, 1) == UNSPEC_CMPINT + && XVECLEN (*op0, 0) == 1 + && GET_MODE (XVECEXP (*op0, 0, 0)) == CCUmode + && GET_CODE (XVECEXP (*op0, 0, 0)) == REG + && REGNO (XVECEXP (*op0, 0, 0)) == CC_REGNUM + && *op1 == const0_rtx) + { + enum rtx_code new_code = UNKNOWN; + switch (*code) + { + case EQ: new_code = EQ; break; + case NE: new_code = NE; break; + case LT: new_code = LTU; break; + case GT: new_code = GTU; break; + case LE: new_code = LEU; break; + case GE: new_code = GEU; break; + default: break; + } + + if (new_code != UNKNOWN) + { + *op0 = XVECEXP (*op0, 0, 0); + *code = new_code; + } + } } /* Emit a compare instruction suitable to implement the comparison @@ -636,6 +664,26 @@ s390_emit_jump (rtx target, rtx cond) } /* Return nonzero if OP is a valid comparison operator + for a branch condition in mode MODE. */ + +int +s390_comparison (rtx op, enum machine_mode mode) +{ + if (mode != VOIDmode && mode != GET_MODE (op)) + return 0; + + if (!COMPARISON_P (op)) + return 0; + + if (GET_CODE (XEXP (op, 0)) != REG + || REGNO (XEXP (op, 0)) != CC_REGNUM + || XEXP (op, 1) != const0_rtx) + return 0; + + return s390_branch_condition_mask (op) >= 0; +} + +/* Return nonzero if OP is a valid comparison operator for an ALC condition in mode MODE. */ int @@ -732,7 +780,7 @@ s390_slb_comparison (rtx op, enum machine_mode mode) } /* Return branch condition mask to implement a branch - specified by CODE. */ + specified by CODE. Return -1 for invalid comparisons. */ static int s390_branch_condition_mask (rtx code) @@ -754,8 +802,7 @@ s390_branch_condition_mask (rtx code) { case EQ: return CC0; case NE: return CC1 | CC2 | CC3; - default: - abort (); + default: return -1; } break; @@ -764,8 +811,7 @@ s390_branch_condition_mask (rtx code) { case EQ: return CC1; case NE: return CC0 | CC2 | CC3; - default: - abort (); + default: return -1; } break; @@ -774,8 +820,7 @@ s390_branch_condition_mask (rtx code) { case EQ: return CC2; case NE: return CC0 | CC1 | CC3; - default: - abort (); + default: return -1; } break; @@ -784,8 +829,7 @@ s390_branch_condition_mask (rtx code) { case EQ: return CC3; case NE: return CC0 | CC1 | CC2; - default: - abort (); + default: return -1; } break; @@ -794,8 +838,7 @@ s390_branch_condition_mask (rtx code) { case EQ: return CC0 | CC2; case NE: return CC1 | CC3; - default: - abort (); + default: return -1; } break; @@ -804,8 +847,7 @@ s390_branch_condition_mask (rtx code) { case LTU: return CC2 | CC3; /* carry */ case GEU: return CC0 | CC1; /* no carry */ - default: - abort (); + default: return -1; } break; @@ -814,8 +856,7 @@ s390_branch_condition_mask (rtx code) { case GTU: return CC0 | CC1; /* borrow */ case LEU: return CC2 | CC3; /* no borrow */ - default: - abort (); + default: return -1; } break; @@ -828,8 +869,7 @@ s390_branch_condition_mask (rtx code) case GTU: return CC3; case LEU: return CC1 | CC2; case GEU: return CC2 | CC3; - default: - abort (); + default: return -1; } case CCUmode: @@ -841,8 +881,7 @@ s390_branch_condition_mask (rtx code) case GTU: return CC2; case LEU: return CC0 | CC1; case GEU: return CC0 | CC2; - default: - abort (); + default: return -1; } break; @@ -855,8 +894,7 @@ s390_branch_condition_mask (rtx code) case GTU: return CC1; case LEU: return CC0 | CC2; case GEU: return CC0 | CC1; - default: - abort (); + default: return -1; } break; @@ -869,8 +907,7 @@ s390_branch_condition_mask (rtx code) case GT: return CC2; case LE: return CC0 | CC1 | CC3; case GE: return CC0 | CC2; - default: - abort (); + default: return -1; } break; @@ -883,8 +920,7 @@ s390_branch_condition_mask (rtx code) case GT: return CC2 | CC3; case LE: return CC0 | CC1; case GE: return CC0 | CC2 | CC3; - default: - abort (); + default: return -1; } break; @@ -905,8 +941,7 @@ s390_branch_condition_mask (rtx code) case UNLE: return CC0 | CC1 | CC3; case UNGE: return CC0 | CC2 | CC3; case LTGT: return CC1 | CC2; - default: - abort (); + default: return -1; } break; @@ -927,13 +962,12 @@ s390_branch_condition_mask (rtx code) case UNLE: return CC0 | CC2 | CC3; case UNGE: return CC0 | CC1 | CC3; case LTGT: return CC2 | CC1; - default: - abort (); + default: return -1; } break; default: - abort (); + return -1; } } @@ -953,6 +987,7 @@ s390_branch_condition_mnemonic (rtx code, int inv) }; int mask = s390_branch_condition_mask (code); + gcc_assert (mask >= 0); if (inv) mask ^= 15; @@ -3486,15 +3521,15 @@ s390_expand_clrmem (rtx dst, rtx len) void s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) { - rtx (*gen_result) (rtx) = - GET_MODE (target) == DImode ? gen_cmpint_di : gen_cmpint_si; + rtx ccreg = gen_rtx_REG (CCUmode, CC_REGNUM); + rtx result = gen_rtx_UNSPEC (SImode, gen_rtvec (1, ccreg), UNSPEC_CMPINT); if (GET_CODE (len) == CONST_INT && INTVAL (len) >= 0 && INTVAL (len) <= 256) { if (INTVAL (len) > 0) { emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (INTVAL (len) - 1))); - emit_insn (gen_result (target)); + emit_move_insn (target, result); } else emit_move_insn (target, const0_rtx); @@ -3503,7 +3538,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) else /* if (TARGET_MVCLE) */ { emit_insn (gen_cmpmem_long (op0, op1, convert_to_mode (Pmode, len, 1))); - emit_insn (gen_result (target)); + emit_move_insn (target, result); } #if 0 @@ -3549,7 +3584,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) emit_label (loop_start_label); emit_insn (gen_cmpmem_short (op0, op1, GEN_INT (255))); - temp = gen_rtx_NE (VOIDmode, gen_rtx_REG (CCSmode, 33), const0_rtx); + temp = gen_rtx_NE (VOIDmode, ccreg, const0_rtx); temp = gen_rtx_IF_THEN_ELSE (VOIDmode, temp, gen_rtx_LABEL_REF (VOIDmode, end_label), pc_rtx); temp = gen_rtx_SET (VOIDmode, pc_rtx, temp); @@ -3574,7 +3609,7 @@ s390_expand_cmpmem (rtx target, rtx op0, rtx op1, rtx len) convert_to_mode (Pmode, count, 1))); emit_label (end_label); - emit_insn (gen_result (target)); + emit_move_insn (target, result); } #endif } diff --git a/gcc/config/s390/s390.h b/gcc/config/s390/s390.h index 9814561..4d50395 100644 --- a/gcc/config/s390/s390.h +++ b/gcc/config/s390/s390.h @@ -1025,6 +1025,9 @@ do { \ {"consttable_operand", { SYMBOL_REF, LABEL_REF, CONST, \ CONST_INT, CONST_DOUBLE }}, \ {"s390_plus_operand", { PLUS }}, \ + {"s390_comparison", { EQ, NE, LT, GT, LE, GE, LTU, GTU, LEU, GEU, \ + UNEQ, UNLT, UNGT, UNLE, UNGE, LTGT, \ + UNORDERED, ORDERED }}, \ {"s390_alc_comparison", { ZERO_EXTEND, SIGN_EXTEND, \ LTU, GTU, LEU, GEU }}, \ {"s390_slb_comparison", { ZERO_EXTEND, SIGN_EXTEND, \ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 86d13b8..a2408d7 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -78,6 +78,7 @@ (define_constants [; Miscellaneous (UNSPEC_ROUND 1) + (UNSPEC_CMPINT 2) (UNSPEC_SETHIGH 10) ; GOT/PLT and lt-relative accesses @@ -1911,16 +1912,6 @@ ; cmpmemM instruction pattern(s). ; -(define_expand "cmpmemdi" - [(set (match_operand:DI 0 "register_operand" "") - (compare:DI (match_operand:BLK 1 "memory_operand" "") - (match_operand:BLK 2 "memory_operand" "") ) ) - (use (match_operand:DI 3 "general_operand" "")) - (use (match_operand:DI 4 "" ""))] - "TARGET_64BIT" - "s390_expand_cmpmem (operands[0], operands[1], - operands[2], operands[3]); DONE;") - (define_expand "cmpmemsi" [(set (match_operand:SI 0 "register_operand" "") (compare:SI (match_operand:BLK 1 "memory_operand" "") @@ -1936,8 +1927,8 @@ (define_expand "cmpmem_short" [(parallel - [(set (reg:CCS 33) - (compare:CCS (match_operand:BLK 0 "memory_operand" "") + [(set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" ""))) (use (match_operand 2 "nonmemory_operand" "")) (clobber (match_dup 3))])] @@ -1945,8 +1936,8 @@ "operands[3] = gen_rtx_SCRATCH (Pmode);") (define_insn "*cmpmem_short" - [(set (reg:CCS 33) - (compare:CCS (match_operand:BLK 0 "memory_operand" "=Q,Q") + [(set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "=Q,Q") (match_operand:BLK 1 "memory_operand" "Q,Q"))) (use (match_operand 2 "nonmemory_operand" "n,a")) (clobber (match_scratch 3 "=X,&a"))] @@ -1978,8 +1969,8 @@ [(parallel [(clobber (match_dup 2)) (clobber (match_dup 3)) - (set (reg:CCS 33) - (compare:CCS (match_operand:BLK 0 "memory_operand" "") + (set (reg:CCU 33) + (compare:CCU (match_operand:BLK 0 "memory_operand" "") (match_operand:BLK 1 "memory_operand" ""))) (use (match_operand 2 "general_operand" "")) (use (match_dup 3))])] @@ -2010,8 +2001,8 @@ (define_insn "*cmpmem_long_64" [(clobber (match_operand:TI 0 "register_operand" "=d")) (clobber (match_operand:TI 1 "register_operand" "=d")) - (set (reg:CCS 33) - (compare:CCS (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0)) + (set (reg:CCU 33) + (compare:CCU (mem:BLK (subreg:DI (match_operand:TI 2 "register_operand" "0") 0)) (mem:BLK (subreg:DI (match_operand:TI 3 "register_operand" "1") 0)))) (use (match_dup 2)) (use (match_dup 3))] @@ -2024,8 +2015,8 @@ (define_insn "*cmpmem_long_31" [(clobber (match_operand:DI 0 "register_operand" "=d")) (clobber (match_operand:DI 1 "register_operand" "=d")) - (set (reg:CCS 33) - (compare:CCS (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0)) + (set (reg:CCU 33) + (compare:CCU (mem:BLK (subreg:SI (match_operand:DI 2 "register_operand" "0") 0)) (mem:BLK (subreg:SI (match_operand:DI 3 "register_operand" "1") 0)))) (use (match_dup 2)) (use (match_dup 3))] @@ -2037,9 +2028,9 @@ ; Convert condition code to integer in range (-1, 0, 1) -(define_insn "cmpint_si" +(define_insn "*cmpint_si" [(set (match_operand:SI 0 "register_operand" "=d") - (compare:SI (reg:CCS 33) (const_int 0)))] + (unspec:SI [(reg:CCU 33)] UNSPEC_CMPINT))] "" { output_asm_insn ("lhi\t%0,1", operands); @@ -2052,9 +2043,9 @@ (set_attr "length" "16") (set_attr "type" "other")]) -(define_insn "cmpint_di" +(define_insn "*cmpint_di" [(set (match_operand:DI 0 "register_operand" "=d") - (compare:DI (reg:CCS 33) (const_int 0)))] + (sign_extend:DI (unspec:SI [(reg:CCU 33)] UNSPEC_CMPINT)))] "TARGET_64BIT" { output_asm_insn ("lghi\t%0,1", operands); @@ -6232,7 +6223,7 @@ (define_insn "*cjump_64" [(set (pc) (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] "TARGET_CPU_ZARCH" @@ -6251,7 +6242,7 @@ (define_insn "*cjump_31" [(set (pc) (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)]) (label_ref (match_operand 0 "" "")) (pc)))] "!TARGET_CPU_ZARCH" @@ -6273,7 +6264,7 @@ (define_insn "*cjump_long" [(set (pc) (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)]) (match_operand 0 "address_operand" "U") (pc)))] "" @@ -6297,7 +6288,7 @@ (define_insn "*icjump_64" [(set (pc) (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] "TARGET_CPU_ZARCH" @@ -6316,7 +6307,7 @@ (define_insn "*icjump_31" [(set (pc) (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)]) (pc) (label_ref (match_operand 0 "" ""))))] "!TARGET_CPU_ZARCH" @@ -6338,7 +6329,7 @@ (define_insn "*icjump_long" [(set (pc) (if_then_else - (match_operator 1 "comparison_operator" [(reg 33) (const_int 0)]) + (match_operator 1 "s390_comparison" [(reg 33) (const_int 0)]) (pc) (match_operand 0 "address_operand" "U")))] "" @@ -6376,7 +6367,7 @@ }) (define_insn "*trap" - [(trap_if (match_operator 0 "comparison_operator" [(reg 33) (const_int 0)]) + [(trap_if (match_operator 0 "s390_comparison" [(reg 33) (const_int 0)]) (const_int 0))] "" "j%C0\t.+2"; |