From ccd61a806ea13790a6ec3e6c17a04ae48b8e21b8 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 1999 17:20:07 -0800 Subject: [PATCH] sparc.md (movtf reg/reg split): Don't generate SUBREGs by hand, gen the appropriate hard reg directly. * config/sparc/sparc.md (movtf reg/reg split): Don't generate SUBREGs by hand, gen the appropriate hard reg directly. (movtf reg/mem split): Likewise and alter_subreg on destination if necessary. (movtf mem/reg split): Similarly. (movdf_cc_sp64): Rename from hidden pattern. (movtf_cc_hq_sp64): Renamed from movtf_cc_sp64. (movtf_cc_sp64, following split): New pattern and splitter. (movdf_cc_reg_sp64): Rename from hidden pattern. (movtf_cc_reg_hq_sp64): Renamed from movtf_cc_reg_sp64, require TARGET_HARD_QUAD. (movtf_cc_reg_sp64, following split): New pattern and splitter. Co-Authored-By: Jakub Jelinek From-SVN: r30880 --- gcc/ChangeLog | 16 ++++ gcc/config/sparc/sparc.md | 192 +++++++++++++++++++++++++++++++++----- 2 files changed, 185 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 788025dd7f9..10ac35ab122 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +1999-12-12 David S. Miller + Jakub Jelinek + + * config/sparc/sparc.md (movtf reg/reg split): Don't generate + SUBREGs by hand, gen the appropriate hard reg directly. + (movtf reg/mem split): Likewise and alter_subreg on destination + if necessary. + (movtf mem/reg split): Similarly. + (movdf_cc_sp64): Rename from hidden pattern. + (movtf_cc_hq_sp64): Renamed from movtf_cc_sp64. + (movtf_cc_sp64, following split): New pattern and splitter. + (movdf_cc_reg_sp64): Rename from hidden pattern. + (movtf_cc_reg_hq_sp64): Renamed from movtf_cc_reg_sp64, require + TARGET_HARD_QUAD. + (movtf_cc_reg_sp64, following split): New pattern and splitter. + 1999-12-12 Stephen L Moshier * loop.c (load_mems): Don't hoist written floating point mem diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index b7025a860ce..87243ebd6c1 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -3643,11 +3643,14 @@ if (GET_CODE (set_src) == SUBREG) set_src = alter_subreg (set_src); - /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ - dest1 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN == 0); - dest2 = gen_rtx_SUBREG (DFmode, set_dest, WORDS_BIG_ENDIAN != 0); - src1 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN == 0); - src2 = gen_rtx_SUBREG (DFmode, set_src, WORDS_BIG_ENDIAN != 0); + dest1 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2)); + dest2 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0)); + src1 = gen_rtx_REG (DFmode, + REGNO (set_src) + (WORDS_BIG_ENDIAN ? 0 : 2)); + src2 = gen_rtx_REG (DFmode, + REGNO (set_src) + (WORDS_BIG_ENDIAN ? 2 : 0)); /* Now emit using the real source and destination we found, swapping the order if we detect overlap. */ @@ -3675,11 +3678,16 @@ rtx word0 = change_address (operands[1], DFmode, NULL_RTX); rtx word1 = change_address (operands[1], DFmode, plus_constant_for_output (XEXP (word0, 0), 8)); - rtx dest1, dest2; + rtx set_dest, dest1, dest2; + + set_dest = operands[0]; + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); - /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ - dest1 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN == 0); - dest2 = gen_rtx_SUBREG (DFmode, operands[0], WORDS_BIG_ENDIAN != 0); + dest1 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2)); + dest2 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0)); /* Now output, ordering such that we don't clobber any registers mentioned in the address. */ @@ -3705,16 +3713,21 @@ [(clobber (const_int 0))] " { - rtx word0 = change_address (operands[0], DFmode, NULL_RTX); - rtx word1 = change_address (operands[0], DFmode, - plus_constant_for_output (XEXP (word0, 0), 8)); - rtx src1, src2; + rtx word1 = change_address (operands[0], DFmode, NULL_RTX); + rtx word2 = change_address (operands[0], DFmode, + plus_constant_for_output (XEXP (word1, 0), 8)); + rtx set_src, src1, src2; - /* Ugly, but gen_highpart will crap out here for 32-bit targets. */ - src1 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN == 0); - src2 = gen_rtx_SUBREG (DFmode, operands[1], WORDS_BIG_ENDIAN != 0); - emit_insn (gen_movdf (word0, src1)); - emit_insn (gen_movdf (word1, src2)); + set_src = operands[1]; + if (GET_CODE (set_src) == SUBREG) + set_src = alter_subreg (set_src); + + src1 = gen_rtx_REG (DFmode, + REGNO (set_src) + (WORDS_BIG_ENDIAN ? 0 : 2)); + src2 = gen_rtx_REG (DFmode, + REGNO (set_src) + (WORDS_BIG_ENDIAN ? 2 : 0)); + emit_insn (gen_movdf (word1, src1)); + emit_insn (gen_movdf (word2, src2)); DONE; }") @@ -4017,7 +4030,7 @@ [(set_attr "type" "fpcmove") (set_attr "length" "1")]) -(define_insn "*movdf_cc_sp64" +(define_insn "movdf_cc_sp64" [(set (match_operand:DF 0 "register_operand" "=e,e") (if_then_else:DF (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") @@ -4031,7 +4044,7 @@ [(set_attr "type" "fpcmove") (set_attr "length" "1")]) -(define_insn "*movtf_cc_sp64" +(define_insn "*movtf_cc_hq_sp64" [(set (match_operand:TF 0 "register_operand" "=e,e") (if_then_else:TF (match_operator 1 "comparison_operator" [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") @@ -4045,6 +4058,72 @@ [(set_attr "type" "fpcmove") (set_attr "length" "1")]) +(define_insn "*movtf_cc_sp64" + [(set (match_operand:TF 0 "register_operand" "=e,e") + (if_then_else:TF (match_operator 1 "comparison_operator" + [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") + (const_int 0)]) + (match_operand:TF 3 "register_operand" "e,0") + (match_operand:TF 4 "register_operand" "0,e")))] + "TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" + "#" + [(set_attr "type" "fpcmove") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:TF 0 "register_operand" "=e,e") + (if_then_else:TF (match_operator 1 "comparison_operator" + [(match_operand 2 "icc_or_fcc_reg_operand" "X,X") + (const_int 0)]) + (match_operand:TF 3 "register_operand" "e,0") + (match_operand:TF 4 "register_operand" "0,e")))] + "reload_completed && TARGET_V9 && TARGET_FPU && !TARGET_HARD_QUAD" + [(clobber (const_int 0))] + " +{ + rtx set_dest = operands[0]; + rtx set_srca = operands[3]; + rtx set_srcb = operands[4]; + int third = rtx_equal_p (set_dest, set_srca); + rtx dest1, dest2; + rtx srca1, srca2, srcb1, srcb2; + + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); + if (GET_CODE (set_srca) == SUBREG) + set_srca = alter_subreg (set_srca); + if (GET_CODE (set_srcb) == SUBREG) + set_srcb = alter_subreg (set_srcb); + + dest1 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2)); + dest2 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0)); + srca1 = gen_rtx_REG (DFmode, + REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 0 : 2)); + srca2 = gen_rtx_REG (DFmode, + REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 2 : 0)); + srcb1 = gen_rtx_REG (DFmode, + REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 0 : 2)); + srcb2 = gen_rtx_REG (DFmode, + REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 2 : 0)); + + /* Now emit using the real source and destination we found, swapping + the order if we detect overlap. */ + if ((third && reg_overlap_mentioned_p (dest1, srcb2)) + || (!third && reg_overlap_mentioned_p (dest1, srca2))) + { + emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); + emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); + } + else + { + emit_insn (gen_movdf_cc_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); + emit_insn (gen_movdf_cc_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); + } + DONE; +}") + (define_insn "*movqi_cc_reg_sp64" [(set (match_operand:QI 0 "register_operand" "=r,r") (if_then_else:QI (match_operator 1 "v9_regcmp_op" @@ -4130,7 +4209,7 @@ [(set_attr "type" "fpcmove") (set_attr "length" "1")]) -(define_insn "*movdf_cc_reg_sp64" +(define_insn "movdf_cc_reg_sp64" [(set (match_operand:DF 0 "register_operand" "=e,e") (if_then_else:DF (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") @@ -4144,19 +4223,86 @@ [(set_attr "type" "fpcmove") (set_attr "length" "1")]) -(define_insn "*movtf_cc_reg_sp64" +(define_insn "*movtf_cc_reg_hq_sp64" [(set (match_operand:TF 0 "register_operand" "=e,e") (if_then_else:TF (match_operator 1 "v9_regcmp_op" [(match_operand:DI 2 "register_operand" "r,r") (const_int 0)]) (match_operand:TF 3 "register_operand" "e,0") (match_operand:TF 4 "register_operand" "0,e")))] - "TARGET_ARCH64 && TARGET_FPU" + "TARGET_ARCH64 && TARGET_FPU && TARGET_HARD_QUAD" "@ fmovrq%D1\\t%2, %3, %0 fmovrq%d1\\t%2, %4, %0" [(set_attr "type" "fpcmove") (set_attr "length" "1")]) + +(define_insn "*movtf_cc_reg_sp64" + [(set (match_operand:TF 0 "register_operand" "=e,e") + (if_then_else:TF (match_operator 1 "v9_regcmp_op" + [(match_operand:DI 2 "register_operand" "r,r") + (const_int 0)]) + (match_operand:TF 3 "register_operand" "e,0") + (match_operand:TF 4 "register_operand" "0,e")))] + "TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" + "#" + [(set_attr "type" "fpcmove") + (set_attr "length" "2")]) + +(define_split + [(set (match_operand:TF 0 "register_operand" "=e,e") + (if_then_else:TF (match_operator 1 "v9_regcmp_op" + [(match_operand:DI 2 "register_operand" "r,r") + (const_int 0)]) + (match_operand:TF 3 "register_operand" "e,0") + (match_operand:TF 4 "register_operand" "0,e")))] + "reload_completed && TARGET_ARCH64 && TARGET_FPU && ! TARGET_HARD_QUAD" + [(clobber (const_int 0))] + " +{ + rtx set_dest = operands[0]; + rtx set_srca = operands[3]; + rtx set_srcb = operands[4]; + int third = rtx_equal_p (set_dest, set_srca); + rtx dest1, dest2; + rtx srca1, srca2, srcb1, srcb2; + + if (GET_CODE (set_dest) == SUBREG) + set_dest = alter_subreg (set_dest); + if (GET_CODE (set_srca) == SUBREG) + set_srca = alter_subreg (set_srca); + if (GET_CODE (set_srcb) == SUBREG) + set_srcb = alter_subreg (set_srcb); + + dest1 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 0 : 2)); + dest2 = gen_rtx_REG (DFmode, + REGNO (set_dest) + (WORDS_BIG_ENDIAN ? 2 : 0)); + srca1 = gen_rtx_REG (DFmode, + REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 0 : 2)); + srca2 = gen_rtx_REG (DFmode, + REGNO (set_srca) + (WORDS_BIG_ENDIAN ? 2 : 0)); + srcb1 = gen_rtx_REG (DFmode, + REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 0 : 2)); + srcb2 = gen_rtx_REG (DFmode, + REGNO (set_srcb) + (WORDS_BIG_ENDIAN ? 2 : 0)); + + /* Now emit using the real source and destination we found, swapping + the order if we detect overlap. */ + if ((third && reg_overlap_mentioned_p (dest1, srcb2)) + || (!third && reg_overlap_mentioned_p (dest1, srca2))) + { + emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); + emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); + } + else + { + emit_insn (gen_movdf_cc_reg_sp64 (dest1, operands[1], operands[2], srca1, srcb1)); + emit_insn (gen_movdf_cc_reg_sp64 (dest2, operands[1], operands[2], srca2, srcb2)); + } + DONE; +}") + ;;- zero extension instructions -- 2.30.2