aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@redhat.com>1999-12-12 17:20:07 -0800
committerDavid S. Miller <davem@gcc.gnu.org>1999-12-12 17:20:07 -0800
commitccd61a806ea13790a6ec3e6c17a04ae48b8e21b8 (patch)
treee4ba53e1087812c1f19fb9ffb7b71e21d1b44ffd /gcc
parent38b58895a4a73c3584de9606206be02c564e54b6 (diff)
downloadgcc-ccd61a806ea13790a6ec3e6c17a04ae48b8e21b8.zip
gcc-ccd61a806ea13790a6ec3e6c17a04ae48b8e21b8.tar.gz
gcc-ccd61a806ea13790a6ec3e6c17a04ae48b8e21b8.tar.bz2
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 <jakub@redhat.com> From-SVN: r30880
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/sparc/sparc.md192
2 files changed, 185 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 788025d..10ac35a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+1999-12-12 David S. Miller <davem@redhat.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * 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 <moshier@mediaone.net>
* 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 b7025a8..87243eb 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