diff options
Diffstat (limited to 'gcc/config')
-rw-r--r-- | gcc/config/sparc/predicates.md | 5 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.c | 23 | ||||
-rw-r--r-- | gcc/config/sparc/sparc.md | 137 |
3 files changed, 69 insertions, 96 deletions
diff --git a/gcc/config/sparc/predicates.md b/gcc/config/sparc/predicates.md index b8524e5..073bce2 100644 --- a/gcc/config/sparc/predicates.md +++ b/gcc/config/sparc/predicates.md @@ -265,6 +265,11 @@ (ior (match_test "register_operand (op, SImode)") (match_test "TARGET_ARCH64 && register_operand (op, DImode)"))) +;; Return true if OP is an integer register of the appropriate mode +;; for a cstore result. +(define_special_predicate "cstore_result_operand" + (match_test "register_operand (op, TARGET_ARCH64 ? DImode : SImode)")) + ;; Return true if OP is a floating point condition code register. (define_predicate "fcc_register_operand" (match_code "reg") diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 3e98325..4a73c73 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -597,6 +597,7 @@ static void sparc_print_operand_address (FILE *, rtx); static reg_class_t sparc_secondary_reload (bool, rtx, reg_class_t, enum machine_mode, secondary_reload_info *); +static enum machine_mode sparc_cstore_mode (enum insn_code icode); #ifdef SUBTARGET_ATTRIBUTE_TABLE /* Table of valid machine attributes. */ @@ -802,6 +803,9 @@ char sparc_hard_reg_printed[8]; #undef TARGET_ATOMIC_TEST_AND_SET_TRUEVAL #define TARGET_ATOMIC_TEST_AND_SET_TRUEVAL 0xff +#undef TARGET_CSTORE_MODE +#define TARGET_CSTORE_MODE sparc_cstore_mode + struct gcc_target targetm = TARGET_INITIALIZER; static void @@ -2572,7 +2576,11 @@ emit_scc_insn (rtx operands[]) { if (GET_MODE (x) == SImode) { - rtx pat = gen_seqsi_special (operands[0], x, y); + rtx pat; + if (TARGET_ARCH64) + pat = gen_seqsidi_special (operands[0], x, y); + else + pat = gen_seqsisi_special (operands[0], x, y); emit_insn (pat); return true; } @@ -2588,7 +2596,11 @@ emit_scc_insn (rtx operands[]) { if (GET_MODE (x) == SImode) { - rtx pat = gen_snesi_special (operands[0], x, y); + rtx pat; + if (TARGET_ARCH64) + pat = gen_snesidi_special (operands[0], x, y); + else + pat = gen_snesisi_special (operands[0], x, y); emit_insn (pat); return true; } @@ -2631,7 +2643,7 @@ emit_scc_insn (rtx operands[]) || (!TARGET_VIS3 && code == GEU)) { emit_insn (gen_rtx_SET (VOIDmode, operands[0], - gen_rtx_fmt_ee (code, SImode, + gen_rtx_fmt_ee (code, GET_MODE (operands[0]), gen_compare_reg_1 (code, x, y), const0_rtx))); return true; @@ -12104,4 +12116,9 @@ sparc_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2) return true; } +static enum machine_mode sparc_cstore_mode (enum insn_code icode ATTRIBUTE_UNUSED) +{ + return (TARGET_ARCH64 ? DImode : SImode); +} + #include "gt-sparc.h" diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 832032b..292cb20 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -615,11 +615,14 @@ ;; Next come the scc insns. +;; Note that the boolean result (operand 0) takes on DImode +;; (not SImode) when TARGET_ARCH64. + (define_expand "cstoresi4" [(use (match_operator 1 "comparison_operator" [(match_operand:SI 2 "compare_operand" "") (match_operand:SI 3 "arith_operand" "")])) - (clobber (match_operand:SI 0 "register_operand"))] + (clobber (match_operand:SI 0 "cstore_result_operand"))] "" { if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) @@ -631,7 +634,7 @@ [(use (match_operator 1 "comparison_operator" [(match_operand:DI 2 "compare_operand" "") (match_operand:DI 3 "arith_operand" "")])) - (clobber (match_operand:SI 0 "register_operand"))] + (clobber (match_operand:SI 0 "cstore_result_operand"))] "TARGET_ARCH64" { if (GET_CODE (operands[2]) == ZERO_EXTRACT && operands[3] != const0_rtx) @@ -643,7 +646,7 @@ [(use (match_operator 1 "comparison_operator" [(match_operand:F 2 "register_operand" "") (match_operand:F 3 "register_operand" "")])) - (clobber (match_operand:SI 0 "register_operand"))] + (clobber (match_operand:SI 0 "cstore_result_operand"))] "TARGET_FPU" { if (emit_scc_insn (operands)) DONE; else FAIL; }) @@ -652,12 +655,12 @@ ;; Seq_special[_xxx] and sne_special[_xxx] clobber the CC reg, because they ;; generate addcc/subcc instructions. -(define_expand "seqsi_special" +(define_expand "seqsi<P:mode>_special" [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" ""))) - (parallel [(set (match_operand:SI 0 "register_operand" "") - (eq:SI (match_dup 3) (const_int 0))) + (parallel [(set (match_operand:P 0 "register_operand" "") + (eq:P (match_dup 3) (const_int 0))) (clobber (reg:CC CC_REG))])] "" { operands[3] = gen_reg_rtx (SImode); }) @@ -666,17 +669,17 @@ [(set (match_dup 3) (xor:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) - (set (match_operand:SI 0 "register_operand" "") - (eq:SI (match_dup 3) (const_int 0)))] + (set (match_operand:DI 0 "register_operand" "") + (eq:DI (match_dup 3) (const_int 0)))] "TARGET_ARCH64" { operands[3] = gen_reg_rtx (DImode); }) -(define_expand "snesi_special" +(define_expand "snesi<P:mode>_special" [(set (match_dup 3) (xor:SI (match_operand:SI 1 "register_operand" "") (match_operand:SI 2 "register_operand" ""))) - (parallel [(set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_dup 3) (const_int 0))) + (parallel [(set (match_operand:P 0 "register_operand" "") + (ne:P (match_dup 3) (const_int 0))) (clobber (reg:CC CC_REG))])] "" { operands[3] = gen_reg_rtx (SImode); }) @@ -685,8 +688,8 @@ [(set (match_dup 3) (xor:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) - (set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_dup 3) (const_int 0)))] + (set (match_operand:DI 0 "register_operand" "") + (ne:DI (match_dup 3) (const_int 0)))] "TARGET_ARCH64 && ! TARGET_VIS3" { operands[3] = gen_reg_rtx (DImode); }) @@ -694,8 +697,8 @@ [(set (match_dup 3) (xor:DI (match_operand:DI 1 "register_operand" "") (match_operand:DI 2 "register_operand" ""))) - (parallel [(set (match_operand:SI 0 "register_operand" "") - (ne:SI (match_dup 3) (const_int 0))) + (parallel [(set (match_operand:DI 0 "register_operand" "") + (ne:DI (match_dup 3) (const_int 0))) (clobber (reg:CCX CC_REG))])] "TARGET_ARCH64 && TARGET_VIS3" { operands[3] = gen_reg_rtx (DImode); }) @@ -708,9 +711,9 @@ ;; them to always use the splits below so the results can be ;; scheduled. -(define_insn_and_split "*snesi_zero" - [(set (match_operand:SI 0 "register_operand" "=r") - (ne:SI (match_operand:SI 1 "register_operand" "r") +(define_insn_and_split "*snesi<P:mode>_zero" + [(set (match_operand:P 0 "register_operand" "=r") + (ne:P (match_operand:SI 1 "register_operand" "r") (const_int 0))) (clobber (reg:CC CC_REG))] "" @@ -718,11 +721,11 @@ "" [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (ltu:SI (reg:CC CC_REG) (const_int 0)))] + (set (match_dup 0) (ltu:P (reg:CC CC_REG) (const_int 0)))] "" [(set_attr "length" "2")]) -(define_insn_and_split "*neg_snesi_zero" +(define_insn_and_split "*neg_snesisi_zero" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (ne:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) @@ -736,35 +739,16 @@ "" [(set_attr "length" "2")]) -(define_insn_and_split "*snesi_zero_extend" +(define_insn_and_split "*neg_snesidi_zero" [(set (match_operand:DI 0 "register_operand" "=r") - (ne:DI (match_operand:SI 1 "register_operand" "r") - (const_int 0))) + (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r") + (const_int 0)))) (clobber (reg:CC CC_REG))] "TARGET_ARCH64" "#" - "&& 1" - [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) - (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (zero_extend:DI (plus:SI (plus:SI (const_int 0) - (const_int 0)) - (ltu:SI (reg:CC_NOOV CC_REG) - (const_int 0)))))] "" - [(set_attr "length" "2")]) - -(define_insn_and_split "*neg_snesi_sign_extend" - [(set (match_operand:DI 0 "register_operand" "=r") - (neg:DI (ne:DI (match_operand:SI 1 "register_operand" "r") - (const_int 0)))) - (clobber (reg:CC CC_REG))] - "TARGET_ARCH64" - "#" - "&& 1" - [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) - (match_dup 1)) - (const_int 0))) + [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) + (const_int 0))) (set (match_dup 0) (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))] "" @@ -843,9 +827,9 @@ "" [(set_attr "length" "2")]) -(define_insn_and_split "*seqsi_zero" - [(set (match_operand:SI 0 "register_operand" "=r") - (eq:SI (match_operand:SI 1 "register_operand" "r") +(define_insn_and_split "*seqsi<P:mode>_zero" + [(set (match_operand:P 0 "register_operand" "=r") + (eq:P (match_operand:SI 1 "register_operand" "r") (const_int 0))) (clobber (reg:CC CC_REG))] "" @@ -853,11 +837,11 @@ "" [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (neg:SI (match_dup 1)) (const_int 0))) - (set (match_dup 0) (geu:SI (reg:CC CC_REG) (const_int 0)))] + (set (match_dup 0) (geu:P (reg:CC CC_REG) (const_int 0)))] "" [(set_attr "length" "2")]) -(define_insn_and_split "*neg_seqsi_zero" +(define_insn_and_split "*neg_seqsisi_zero" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (eq:SI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) @@ -871,25 +855,7 @@ "" [(set_attr "length" "2")]) -(define_insn_and_split "*seqsi_zero_extend" - [(set (match_operand:DI 0 "register_operand" "=r") - (eq:DI (match_operand:SI 1 "register_operand" "r") - (const_int 0))) - (clobber (reg:CC CC_REG))] - "TARGET_ARCH64" - "#" - "&& 1" - [(set (reg:CC_NOOV CC_REG) (compare:CC_NOOV (minus:SI (const_int 0) - (match_dup 1)) - (const_int 0))) - (set (match_dup 0) (zero_extend:DI (minus:SI (minus:SI (const_int 0) - (const_int -1)) - (ltu:SI (reg:CC_NOOV CC_REG) - (const_int 0)))))] - "" - [(set_attr "length" "2")]) - -(define_insn_and_split "*neg_seqsi_sign_extend" +(define_insn_and_split "*neg_seqsidi_zero" [(set (match_operand:DI 0 "register_operand" "=r") (neg:DI (eq:DI (match_operand:SI 1 "register_operand" "r") (const_int 0)))) @@ -1021,9 +987,9 @@ ;; ??? The addx/subx insns use the 32 bit carry flag so there are no DImode ;; versions for v9. -(define_insn "*sltu_insn" - [(set (match_operand:SI 0 "register_operand" "=r") - (ltu:SI (reg:CC CC_REG) (const_int 0)))] +(define_insn "*sltu<P:mode>_insn" + [(set (match_operand:P 0 "register_operand" "=r") + (ltu:P (reg:CC CC_REG) (const_int 0)))] "" "addx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) @@ -1042,28 +1008,20 @@ "addxc\t%%g0, %%g0, %0" [(set_attr "type" "ialuX")]) -(define_insn "*sltu_extend_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (ltu:DI (reg:CC CC_REG) (const_int 0)))] - "TARGET_ARCH64" - "addx\t%%g0, 0, %0" - [(set_attr "type" "ialuX")]) - -(define_insn "*neg_sltu_insn" +(define_insn "*neg_sltusi_insn" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))))] "" "subx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) -(define_insn "*neg_sltu_extend_sp64" +(define_insn "*neg_sltudi_insn" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0)))))] "TARGET_ARCH64" "subx\t%%g0, 0, %0" [(set_attr "type" "ialuX")]) -;; ??? Combine should canonicalize these next two to the same pattern. (define_insn "*neg_sltu_minus_x" [(set (match_operand:SI 0 "register_operand" "=r") (minus:SI (neg:SI (ltu:SI (reg:CC CC_REG) (const_int 0))) @@ -1080,28 +1038,21 @@ "subx\t%%g0, %1, %0" [(set_attr "type" "ialuX")]) -(define_insn "*sgeu_insn" - [(set (match_operand:SI 0 "register_operand" "=r") - (geu:SI (reg:CC CC_REG) (const_int 0)))] +(define_insn "*sgeu<P:mode>_insn" + [(set (match_operand:P 0 "register_operand" "=r") + (geu:P (reg:CC CC_REG) (const_int 0)))] "" "subx\t%%g0, -1, %0" [(set_attr "type" "ialuX")]) -(define_insn "*sgeu_extend_sp64" - [(set (match_operand:DI 0 "register_operand" "=r") - (geu:DI (reg:CC CC_REG) (const_int 0)))] - "TARGET_ARCH64" - "subx\t%%g0, -1, %0" - [(set_attr "type" "ialuX")]) - -(define_insn "*neg_sgeu_insn" +(define_insn "*neg_sgeusi_insn" [(set (match_operand:SI 0 "register_operand" "=r") (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0))))] "" "addx\t%%g0, -1, %0" [(set_attr "type" "ialuX")]) -(define_insn "*neg_sgeu_extend_sp64" +(define_insn "*neg_sgeudi_insn" [(set (match_operand:DI 0 "register_operand" "=r") (sign_extend:DI (neg:SI (geu:SI (reg:CC CC_REG) (const_int 0)))))] "TARGET_ARCH64" |