Commit dc7342d2 by Eric Botcazou Committed by Eric Botcazou

sparc-protos.h (sparc_splitdi_legitimate): Rename to...

	* config/sparc/sparc-protos.h (sparc_splitdi_legitimate): Rename to...
	(sparc_split_reg_mem_legitimate): ...this.
	(sparc_split_reg_mem): Declare.
	(sparc_split_mem_reg): Likewise.
	(sparc_split_regreg_legitimate): Rename to...
	(sparc_split_reg_reg_legitimate): ...this.
	* config/sparc/sparc.c (sparc_splitdi_legitimate): Rename to...
	(sparc_split_reg_mem_legitimate): ...this.
	(sparc_split_reg_mem): New function.
	(sparc_split_mem_reg): Likewise.
	(sparc_split_regreg_legitimate): Rename to...
	(sparc_split_reg_reg_legitimate): ...this.
	(sparc_split_reg_reg): New function.
	* config/sparc/sparc.md (lra): Remove "none" value.
	(enabled): Adjust to above change.
	(*movdi_insn_sp32): Remove new (r,T) alternative and reorder others.
	(DImode splitters): Adjust to above renamings and use new functions.
	(*movdf_insn_sp32): Remove new (r,T) alternative and reorder others.
	(DFmode splitters): Adjust to above renamings and use new functions.
	(*mov<VM64:mode>_insn_sp64): Replace C with Z constraint and use W
	constraint in conjunction with e.
	(*mov<VM64:mode>_insn_sp32): Remove new (r,T) alternative, add (o,Y)
	alternative and reorder others.
	(VM64:mode splitters): Adjust to above renamings and use new functions.

From-SVN: r243238
parent b2a8d083
2016-12-05 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc-protos.h (sparc_splitdi_legitimate): Rename to...
(sparc_split_reg_mem_legitimate): ...this.
(sparc_split_reg_mem): Declare.
(sparc_split_mem_reg): Likewise.
(sparc_split_regreg_legitimate): Rename to...
(sparc_split_reg_reg_legitimate): ...this.
* config/sparc/sparc.c (sparc_splitdi_legitimate): Rename to...
(sparc_split_reg_mem_legitimate): ...this.
(sparc_split_reg_mem): New function.
(sparc_split_mem_reg): Likewise.
(sparc_split_regreg_legitimate): Rename to...
(sparc_split_reg_reg_legitimate): ...this.
(sparc_split_reg_reg): New function.
* config/sparc/sparc.md (lra): Remove "none" value.
(enabled): Adjust to above change.
(*movdi_insn_sp32): Remove new (r,T) alternative and reorder others.
(DImode splitters): Adjust to above renamings and use new functions.
(*movdf_insn_sp32): Remove new (r,T) alternative and reorder others.
(DFmode splitters): Adjust to above renamings and use new functions.
(*mov<VM64:mode>_insn_sp64): Replace C with Z constraint and use W
constraint in conjunction with e.
(*mov<VM64:mode>_insn_sp32): Remove new (r,T) alternative, add (o,Y)
alternative and reorder others.
(VM64:mode splitters): Adjust to above renamings and use new functions.
2016-12-04 Martin Sebor <msebor@redhat.com> 2016-12-04 Martin Sebor <msebor@redhat.com>
PR c/78668 PR c/78668
...@@ -68,8 +68,11 @@ extern void sparc_emit_call_insn (rtx, rtx); ...@@ -68,8 +68,11 @@ extern void sparc_emit_call_insn (rtx, rtx);
extern void sparc_defer_case_vector (rtx, rtx, int); extern void sparc_defer_case_vector (rtx, rtx, int);
extern bool sparc_expand_move (machine_mode, rtx *); extern bool sparc_expand_move (machine_mode, rtx *);
extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx); extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
extern int sparc_splitdi_legitimate (rtx, rtx); extern int sparc_split_reg_mem_legitimate (rtx, rtx);
extern int sparc_split_regreg_legitimate (rtx, rtx); extern void sparc_split_reg_mem (rtx, rtx, machine_mode);
extern void sparc_split_mem_reg (rtx, rtx, machine_mode);
extern int sparc_split_reg_reg_legitimate (rtx, rtx);
extern void sparc_split_reg_reg (rtx, rtx, machine_mode);
extern const char *output_ubranch (rtx, rtx_insn *); extern const char *output_ubranch (rtx, rtx_insn *);
extern const char *output_cbranch (rtx, rtx, int, int, int, rtx_insn *); extern const char *output_cbranch (rtx, rtx, int, int, int, rtx_insn *);
extern const char *output_return (rtx_insn *); extern const char *output_return (rtx_insn *);
......
...@@ -8484,46 +8484,82 @@ order_regs_for_local_alloc (void) ...@@ -8484,46 +8484,82 @@ order_regs_for_local_alloc (void)
} }
/* Return 1 if REG and MEM are legitimate enough to allow the various /* Return 1 if REG and MEM are legitimate enough to allow the various
mem<-->reg splits to be run. */ MEM<-->REG splits to be run. */
int int
sparc_splitdi_legitimate (rtx reg, rtx mem) sparc_split_reg_mem_legitimate (rtx reg, rtx mem)
{ {
/* Punt if we are here by mistake. */ /* Punt if we are here by mistake. */
gcc_assert (reload_completed); gcc_assert (reload_completed);
/* We must have an offsettable memory reference. */ /* We must have an offsettable memory reference. */
if (! offsettable_memref_p (mem)) if (!offsettable_memref_p (mem))
return 0; return 0;
/* If we have legitimate args for ldd/std, we do not want /* If we have legitimate args for ldd/std, we do not want
the split to happen. */ the split to happen. */
if ((REGNO (reg) % 2) == 0 if ((REGNO (reg) % 2) == 0 && mem_min_alignment (mem, 8))
&& mem_min_alignment (mem, 8))
return 0; return 0;
/* Success. */ /* Success. */
return 1; return 1;
} }
/* Like sparc_splitdi_legitimate but for REG <--> REG moves. */ /* Split a REG <-- MEM move into a pair of moves in MODE. */
void
sparc_split_reg_mem (rtx dest, rtx src, machine_mode mode)
{
rtx high_part = gen_highpart (mode, dest);
rtx low_part = gen_lowpart (mode, dest);
rtx word0 = adjust_address (src, mode, 0);
rtx word1 = adjust_address (src, mode, 4);
if (reg_overlap_mentioned_p (high_part, word1))
{
emit_move_insn_1 (low_part, word1);
emit_move_insn_1 (high_part, word0);
}
else
{
emit_move_insn_1 (high_part, word0);
emit_move_insn_1 (low_part, word1);
}
}
/* Split a MEM <-- REG move into a pair of moves in MODE. */
void
sparc_split_mem_reg (rtx dest, rtx src, machine_mode mode)
{
rtx word0 = adjust_address (dest, mode, 0);
rtx word1 = adjust_address (dest, mode, 4);
rtx high_part = gen_highpart (mode, src);
rtx low_part = gen_lowpart (mode, src);
emit_move_insn_1 (word0, high_part);
emit_move_insn_1 (word1, low_part);
}
/* Like sparc_split_reg_mem_legitimate but for REG <--> REG moves. */
int int
sparc_split_regreg_legitimate (rtx reg1, rtx reg2) sparc_split_reg_reg_legitimate (rtx reg1, rtx reg2)
{ {
int regno1, regno2; /* Punt if we are here by mistake. */
gcc_assert (reload_completed);
if (GET_CODE (reg1) == SUBREG) if (GET_CODE (reg1) == SUBREG)
reg1 = SUBREG_REG (reg1); reg1 = SUBREG_REG (reg1);
if (GET_CODE (reg1) != REG) if (GET_CODE (reg1) != REG)
return 0; return 0;
regno1 = REGNO (reg1); const int regno1 = REGNO (reg1);
if (GET_CODE (reg2) == SUBREG) if (GET_CODE (reg2) == SUBREG)
reg2 = SUBREG_REG (reg2); reg2 = SUBREG_REG (reg2);
if (GET_CODE (reg2) != REG) if (GET_CODE (reg2) != REG)
return 0; return 0;
regno2 = REGNO (reg2); const int regno2 = REGNO (reg2);
if (SPARC_INT_REG_P (regno1) && SPARC_INT_REG_P (regno2)) if (SPARC_INT_REG_P (regno1) && SPARC_INT_REG_P (regno2))
return 1; return 1;
...@@ -8538,6 +8574,30 @@ sparc_split_regreg_legitimate (rtx reg1, rtx reg2) ...@@ -8538,6 +8574,30 @@ sparc_split_regreg_legitimate (rtx reg1, rtx reg2)
return 0; return 0;
} }
/* Split a REG <--> REG move into a pair of moves in MODE. */
void
sparc_split_reg_reg (rtx dest, rtx src, machine_mode mode)
{
rtx dest1 = gen_highpart (mode, dest);
rtx dest2 = gen_lowpart (mode, dest);
rtx src1 = gen_highpart (mode, src);
rtx src2 = gen_lowpart (mode, src);
/* Now emit using the real source and destination we found, swapping
the order if we detect overlap. */
if (reg_overlap_mentioned_p (dest1, src2))
{
emit_move_insn_1 (dest2, src2);
emit_move_insn_1 (dest1, src1);
}
else
{
emit_move_insn_1 (dest1, src1);
emit_move_insn_1 (dest2, src2);
}
}
/* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1. /* Return 1 if REGNO (reg1) is even and REGNO (reg1) == REGNO (reg2) - 1.
This makes them candidates for using ldd and std insns. This makes them candidates for using ldd and std insns.
......
...@@ -254,14 +254,12 @@ ...@@ -254,14 +254,12 @@
(define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4" (define_attr "cpu_feature" "none,fpu,fpunotv9,v9,vis,vis3,vis4"
(const_string "none")) (const_string "none"))
(define_attr "lra" "none,disabled,enabled" (define_attr "lra" "disabled,enabled"
(const_string "none")) (const_string "enabled"))
(define_attr "enabled" "" (define_attr "enabled" ""
(cond [(eq_attr "cpu_feature" "none") (cond [(eq_attr "cpu_feature" "none")
(cond [(eq_attr "lra" "disabled") (symbol_ref "!TARGET_LRA") (cond [(eq_attr "lra" "disabled") (symbol_ref "!TARGET_LRA")] (const_int 1))
(eq_attr "lra" "enabled") (symbol_ref "TARGET_LRA")]
(const_int 1))
(eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU") (eq_attr "cpu_feature" "fpu") (symbol_ref "TARGET_FPU")
(eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && !TARGET_V9") (eq_attr "cpu_feature" "fpunotv9") (symbol_ref "TARGET_FPU && !TARGET_V9")
(eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9") (eq_attr "cpu_feature" "v9") (symbol_ref "TARGET_V9")
...@@ -1707,25 +1705,23 @@ ...@@ -1707,25 +1705,23 @@
(define_insn "*movdi_insn_sp32" (define_insn "*movdi_insn_sp32"
[(set (match_operand:DI 0 "nonimmediate_operand" [(set (match_operand:DI 0 "nonimmediate_operand"
"=T,o,T,T,U,r,o,r,r,r,?T,?*f,?*f,?o,?*e,?*e, r,?*f,?*e,?W,b,b") "=T,o,U,T,r,o,r,r,?*f,?T,?*f,?o,?*e,?*e, r,?*f,?*e,?W,*b,*b")
(match_operand:DI 1 "input_operand" (match_operand:DI 1 "input_operand"
" J,J,U,r,T,T,r,o,i,r,*f, T, o,*f, *e, *e,?*f, r, W,*e,J,P"))] " J,J,T,U,o,r,i,r, T,*f, o,*f, *e, *e,?*f, r, W,*e, J, P"))]
"TARGET_ARCH32 "TARGET_ARCH32
&& (register_operand (operands[0], DImode) && (register_operand (operands[0], DImode)
|| register_or_zero_operand (operands[1], DImode))" || register_or_zero_operand (operands[1], DImode))"
"@ "@
stx\t%%g0, %0 stx\t%r1, %0
# #
std\t%1, %0
std\t%1, %0
ldd\t%1, %0 ldd\t%1, %0
std\t%1, %0
ldd\t%1, %0 ldd\t%1, %0
std\t%1, %0
# #
# #
#
#
std\t%1, %0
ldd\t%1, %0 ldd\t%1, %0
std\t%1, %0
# #
# #
fmovd\t%1, %0 fmovd\t%1, %0
...@@ -1736,12 +1732,12 @@ ...@@ -1736,12 +1732,12 @@
std\t%1, %0 std\t%1, %0
fzero\t%0 fzero\t%0
fone\t%0" fone\t%0"
[(set_attr "type" "store,store,store,store,load,load,*,*,*,*,fpstore,fpload,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl") [(set_attr "type" "store,*,load,store,load,store,*,*,fpload,fpstore,*,*,fpmove,*,*,*,fpload,fpstore,visl,visl")
(set_attr "length" "*,2,*,*,*,*,2,2,2,2,*,*,2,2,*,2,2,2,*,*,*,*") (set_attr "length" "*,2,*,*,*,*,2,2,*,*,2,2,*,2,2,2,*,*,*,*")
(set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double") (set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*,*,*,*,double,double")
(set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis") (set_attr "cpu_feature" "v9,*,*,*,*,*,*,*,fpu,fpu,fpu,fpu,v9,fpunotv9,vis3,vis3,fpu,fpu,vis,vis")
(set_attr "v3pipe" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,true,true") (set_attr "v3pipe" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,true,true")
(set_attr "lra" "*,*,disabled,enabled,disabled,enabled,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")]) (set_attr "lra" "*,*,disabled,disabled,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
(define_insn "*movdi_insn_sp64" (define_insn "*movdi_insn_sp64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b") [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r, m, r,*e,?*e,?*e,?W,b,b")
...@@ -1997,30 +1993,27 @@ ...@@ -1997,30 +1993,27 @@
(define_split (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "const_int_operand" ""))] (match_operand:DI 1 "const_int_operand" ""))]
"TARGET_ARCH32 "reload_completed
&& TARGET_ARCH32
&& ((GET_CODE (operands[0]) == REG && ((GET_CODE (operands[0]) == REG
&& SPARC_INT_REG_P (REGNO (operands[0]))) && SPARC_INT_REG_P (REGNO (operands[0])))
|| (GET_CODE (operands[0]) == SUBREG || (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG && GET_CODE (SUBREG_REG (operands[0])) == REG
&& SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0]))))) && SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
&& reload_completed"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
HOST_WIDE_INT low, high; HOST_WIDE_INT low = trunc_int_for_mode (INTVAL (operands[1]), SImode);
HOST_WIDE_INT high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
rtx high_part = gen_highpart (SImode, operands[0]);
rtx low_part = gen_lowpart (SImode, operands[0]);
low = trunc_int_for_mode (INTVAL (operands[1]), SImode); emit_move_insn_1 (high_part, GEN_INT (high));
high = trunc_int_for_mode (INTVAL (operands[1]) >> 32, SImode);
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), GEN_INT (high)));
/* Slick... but this trick loses if this subreg constant part /* Slick... but this loses if the constant can be done in one insn. */
can be done in one insn. */ if (low == high && !SPARC_SETHI32_P (high) && !SPARC_SIMM13_P (high))
if (low == high emit_move_insn_1 (low_part, high_part);
&& !SPARC_SETHI32_P (high)
&& !SPARC_SIMM13_P (high))
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
gen_highpart (SImode, operands[0])));
else else
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), GEN_INT (low))); emit_move_insn_1 (low_part, GEN_INT (low));
DONE; DONE;
}) })
...@@ -2031,31 +2024,10 @@ ...@@ -2031,31 +2024,10 @@
"reload_completed "reload_completed
&& (!TARGET_V9 && (!TARGET_V9
|| (TARGET_ARCH32 || (TARGET_ARCH32
&& sparc_split_regreg_legitimate (operands[0], operands[1])))" && sparc_split_reg_reg_legitimate (operands[0], operands[1])))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx set_dest = operands[0]; sparc_split_reg_reg (operands[0], operands[1], SImode);
rtx set_src = operands[1];
rtx dest1, dest2;
rtx src1, src2;
dest1 = gen_highpart (SImode, set_dest);
dest2 = gen_lowpart (SImode, set_dest);
src1 = gen_highpart (SImode, set_src);
src2 = gen_lowpart (SImode, set_src);
/* Now emit using the real source and destination we found, swapping
the order if we detect overlap. */
if (reg_overlap_mentioned_p (dest1, src2))
{
emit_insn (gen_movsi (dest2, src2));
emit_insn (gen_movsi (dest1, src1));
}
else
{
emit_insn (gen_movsi (dest1, src1));
emit_insn (gen_movsi (dest2, src2));
}
DONE; DONE;
}) })
...@@ -2064,41 +2036,24 @@ ...@@ -2064,41 +2036,24 @@
(define_split (define_split
[(set (match_operand:DI 0 "register_operand" "") [(set (match_operand:DI 0 "register_operand" "")
(match_operand:DI 1 "memory_operand" ""))] (match_operand:DI 1 "memory_operand" ""))]
"(TARGET_ARCH32 "reload_completed
&& reload_completed && TARGET_ARCH32
&& sparc_splitdi_legitimate (operands[0], operands[1]))" && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx word0 = adjust_address (operands[1], SImode, 0); sparc_split_reg_mem (operands[0], operands[1], SImode);
rtx word1 = adjust_address (operands[1], SImode, 4);
rtx high_part = gen_highpart (SImode, operands[0]);
rtx low_part = gen_lowpart (SImode, operands[0]);
if (reg_overlap_mentioned_p (high_part, word1))
{
emit_insn (gen_movsi (low_part, word1));
emit_insn (gen_movsi (high_part, word0));
}
else
{
emit_insn (gen_movsi (high_part, word0));
emit_insn (gen_movsi (low_part, word1));
}
DONE; DONE;
}) })
(define_split (define_split
[(set (match_operand:DI 0 "memory_operand" "") [(set (match_operand:DI 0 "memory_operand" "")
(match_operand:DI 1 "register_operand" ""))] (match_operand:DI 1 "register_operand" ""))]
"(TARGET_ARCH32 "reload_completed
&& reload_completed && TARGET_ARCH32
&& sparc_splitdi_legitimate (operands[1], operands[0]))" && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), sparc_split_mem_reg (operands[0], operands[1], SImode);
gen_highpart (SImode, operands[1])));
emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4),
gen_lowpart (SImode, operands[1])));
DONE; DONE;
}) })
...@@ -2112,8 +2067,8 @@ ...@@ -2112,8 +2067,8 @@
&& offsettable_memref_p (operands[0])" && offsettable_memref_p (operands[0])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
emit_insn (gen_movsi (adjust_address (operands[0], SImode, 0), const0_rtx)); emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
emit_insn (gen_movsi (adjust_address (operands[0], SImode, 4), const0_rtx)); emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
DONE; DONE;
}) })
...@@ -2381,13 +2336,15 @@ ...@@ -2381,13 +2336,15 @@
(define_insn "*movdf_insn_sp32" (define_insn "*movdf_insn_sp32"
[(set (match_operand:DF 0 "nonimmediate_operand" [(set (match_operand:DF 0 "nonimmediate_operand"
"=b,b,e,e,*r, f, e,T,W,U,r,T,T, f, *r, o,o") "=T,o,b,b,e,e,*r, f, e,W,U,T, f,o, *r,*r, o")
(match_operand:DF 1 "input_operand" (match_operand:DF 1 "input_operand"
" G,C,e,e, f,*r,W#F,G,e,T,T,U,r,o#F,*roF,*rG,f"))] " G,G,G,C,e,e, f,*r,W#F,e,T,U,o#F,f,*rF, o,*r"))]
"TARGET_ARCH32 "TARGET_ARCH32
&& (register_operand (operands[0], DFmode) && (register_operand (operands[0], DFmode)
|| register_or_zero_or_all_ones_operand (operands[1], DFmode))" || register_or_zero_or_all_ones_operand (operands[1], DFmode))"
"@ "@
stx\t%r1, %0
#
fzero\t%0 fzero\t%0
fone\t%0 fone\t%0
fmovd\t%1, %0 fmovd\t%1, %0
...@@ -2395,22 +2352,20 @@ ...@@ -2395,22 +2352,20 @@
# #
# #
ldd\t%1, %0 ldd\t%1, %0
stx\t%r1, %0
std\t%1, %0 std\t%1, %0
ldd\t%1, %0 ldd\t%1, %0
ldd\t%1, %0
std\t%1, %0
std\t%1, %0 std\t%1, %0
# #
# #
# #
#" ldd\t%1, %0
[(set_attr "type" "visl,visl,fpmove,*,*,*,fpload,store,fpstore,load,load,store,store,*,*,*,*") std\t%1, %0"
(set_attr "length" "*,*,*,2,2,2,*,*,*,*,*,*,*,2,2,2,2") [(set_attr "type" "store,*,visl,visl,fpmove,*,*,*,fpload,fpstore,load,store,*,*,*,load,store")
(set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*,*,*,*,*,*,*") (set_attr "length" "*,2,*,*,*,2,2,2,*,*,*,*,2,2,2,*,*")
(set_attr "cpu_feature" "vis,vis,v9,fpunotv9,vis3,vis3,fpu,v9,fpu,*,*,*,*,fpu,*,*,fpu") (set_attr "fptype" "*,*,double,double,double,*,*,*,*,*,*,*,*,*,*,*,*")
(set_attr "v3pipe" "true,true,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*") (set_attr "cpu_feature" "v9,*,vis,vis,v9,fpunotv9,vis3,vis3,fpu,fpu,*,*,fpu,fpu,*,*,*")
(set_attr "lra" "*,*,*,*,*,*,*,*,*,disabled,enabled,disabled,enabled,*,*,*,*")]) (set_attr "v3pipe" "*,*,true,true,*,*,*,*,*,*,*,*,*,*,*,*,*")
(set_attr "lra" "*,*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
(define_insn "*movdf_insn_sp64" (define_insn "*movdf_insn_sp64"
[(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r") [(set (match_operand:DF 0 "nonimmediate_operand" "=b,b,e,*r, e, e,W, *r,*r, m,*r")
...@@ -2440,44 +2395,38 @@ ...@@ -2440,44 +2395,38 @@
(define_split (define_split
[(set (match_operand:DF 0 "register_operand" "") [(set (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "const_double_operand" ""))] (match_operand:DF 1 "const_double_operand" ""))]
"REG_P (operands[0]) "reload_completed
&& REG_P (operands[0])
&& SPARC_INT_REG_P (REGNO (operands[0])) && SPARC_INT_REG_P (REGNO (operands[0]))
&& !const_zero_operand (operands[1], GET_MODE (operands[0])) && !const_zero_operand (operands[1], GET_MODE (operands[0]))"
&& reload_completed"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
operands[0] = gen_raw_REG (DImode, REGNO (operands[0])); operands[0] = gen_raw_REG (DImode, REGNO (operands[0]));
if (TARGET_ARCH64) if (TARGET_ARCH64)
{ {
machine_mode mode = GET_MODE (operands[1]); rtx tem = simplify_subreg (DImode, operands[1], DFmode, 0);
rtx tem = simplify_subreg (DImode, operands[1], mode, 0);
emit_insn (gen_movdi (operands[0], tem)); emit_insn (gen_movdi (operands[0], tem));
} }
else else
{ {
machine_mode mode = GET_MODE (operands[1]); rtx hi = simplify_subreg (SImode, operands[1], DFmode, 0);
rtx hi = simplify_subreg (SImode, operands[1], mode, 0); rtx lo = simplify_subreg (SImode, operands[1], DFmode, 4);
rtx lo = simplify_subreg (SImode, operands[1], mode, 4); rtx high_part = gen_highpart (SImode, operands[0]);
rtx low_part = gen_lowpart (SImode, operands[0]);
gcc_assert (GET_CODE (hi) == CONST_INT); gcc_assert (GET_CODE (hi) == CONST_INT);
gcc_assert (GET_CODE (lo) == CONST_INT); gcc_assert (GET_CODE (lo) == CONST_INT);
emit_insn (gen_movsi (gen_highpart (SImode, operands[0]), hi)); emit_move_insn_1 (high_part, hi);
/* Slick... but this trick loses if this subreg constant part /* Slick... but this loses if the constant can be done in one insn. */
can be done in one insn. */
if (lo == hi if (lo == hi
&& !SPARC_SETHI32_P (INTVAL (hi)) && !SPARC_SETHI32_P (INTVAL (hi))
&& !SPARC_SIMM13_P (INTVAL (hi))) && !SPARC_SIMM13_P (INTVAL (hi)))
{ emit_move_insn_1 (low_part, high_part);
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]),
gen_highpart (SImode, operands[0])));
}
else else
{ emit_move_insn_1 (low_part, lo);
emit_insn (gen_movsi (gen_lowpart (SImode, operands[0]), lo));
}
} }
DONE; DONE;
}) })
...@@ -2489,35 +2438,31 @@ ...@@ -2489,35 +2438,31 @@
;; register DFmode cases must be handled. ;; register DFmode cases must be handled.
(define_split (define_split
[(set (match_operand:DF 0 "register_operand" "") [(set (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "register_operand" ""))] (match_operand:DF 1 "const_zero_operand" ""))]
"(!TARGET_V9 "reload_completed
|| (TARGET_ARCH32 && TARGET_ARCH32
&& sparc_split_regreg_legitimate (operands[0], operands[1]))) && ((GET_CODE (operands[0]) == REG
&& reload_completed" && SPARC_INT_REG_P (REGNO (operands[0])))
|| (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG
&& SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx set_dest = operands[0]; emit_move_insn_1 (gen_highpart (SFmode, operands[0]), CONST0_RTX (SFmode));
rtx set_src = operands[1]; emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), CONST0_RTX (SFmode));
rtx dest1, dest2; DONE;
rtx src1, src2; })
dest1 = gen_highpart (SFmode, set_dest);
dest2 = gen_lowpart (SFmode, set_dest);
src1 = gen_highpart (SFmode, set_src);
src2 = gen_lowpart (SFmode, set_src);
/* Now emit using the real source and destination we found, swapping (define_split
the order if we detect overlap. */ [(set (match_operand:DF 0 "register_operand" "")
if (reg_overlap_mentioned_p (dest1, src2)) (match_operand:DF 1 "register_operand" ""))]
{ "reload_completed
emit_move_insn_1 (dest2, src2); && (!TARGET_V9
emit_move_insn_1 (dest1, src1); || (TARGET_ARCH32
} && sparc_split_reg_reg_legitimate (operands[0], operands[1])))"
else [(clobber (const_int 0))]
{ {
emit_move_insn_1 (dest1, src1); sparc_split_reg_reg (operands[0], operands[1], SFmode);
emit_move_insn_1 (dest2, src2);
}
DONE; DONE;
}) })
...@@ -2526,26 +2471,10 @@ ...@@ -2526,26 +2471,10 @@
(match_operand:DF 1 "memory_operand" ""))] (match_operand:DF 1 "memory_operand" ""))]
"reload_completed "reload_completed
&& TARGET_ARCH32 && TARGET_ARCH32
&& (((REGNO (operands[0]) % 2) != 0) && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
|| !mem_min_alignment (operands[1], 8))
&& offsettable_memref_p (operands[1])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx word0, word1; sparc_split_reg_mem (operands[0], operands[1], SFmode);
word0 = adjust_address (operands[1], SFmode, 0);
word1 = adjust_address (operands[1], SFmode, 4);
if (reg_overlap_mentioned_p (gen_highpart (SFmode, operands[0]), word1))
{
emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
}
else
{
emit_move_insn_1 (gen_highpart (SFmode, operands[0]), word0);
emit_move_insn_1 (gen_lowpart (SFmode, operands[0]), word1);
}
DONE; DONE;
}) })
...@@ -2554,18 +2483,10 @@ ...@@ -2554,18 +2483,10 @@
(match_operand:DF 1 "register_operand" ""))] (match_operand:DF 1 "register_operand" ""))]
"reload_completed "reload_completed
&& TARGET_ARCH32 && TARGET_ARCH32
&& (((REGNO (operands[1]) % 2) != 0) && sparc_split_reg_mem_legitimate (operands[1], operands[0])"
|| !mem_min_alignment (operands[0], 8))
&& offsettable_memref_p (operands[0])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx word0, word1; sparc_split_mem_reg (operands[0], operands[1], SFmode);
word0 = adjust_address (operands[0], SFmode, 0);
word1 = adjust_address (operands[0], SFmode, 4);
emit_move_insn_1 (word0, gen_highpart (SFmode, operands[1]));
emit_move_insn_1 (word1, gen_lowpart (SFmode, operands[1]));
DONE; DONE;
}) })
...@@ -2579,35 +2500,8 @@ ...@@ -2579,35 +2500,8 @@
&& offsettable_memref_p (operands[0])" && offsettable_memref_p (operands[0])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx dest1, dest2; emit_move_insn_1 (adjust_address (operands[0], SFmode, 0), CONST0_RTX (SFmode));
emit_move_insn_1 (adjust_address (operands[0], SFmode, 4), CONST0_RTX (SFmode));
dest1 = adjust_address (operands[0], SFmode, 0);
dest2 = adjust_address (operands[0], SFmode, 4);
emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
DONE;
})
(define_split
[(set (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "const_zero_operand" ""))]
"reload_completed
&& TARGET_ARCH32
&& ((GET_CODE (operands[0]) == REG
&& SPARC_INT_REG_P (REGNO (operands[0])))
|| (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == REG
&& SPARC_INT_REG_P (REGNO (SUBREG_REG (operands[0])))))"
[(clobber (const_int 0))]
{
rtx set_dest = operands[0];
rtx dest1, dest2;
dest1 = gen_highpart (SFmode, set_dest);
dest2 = gen_lowpart (SFmode, set_dest);
emit_move_insn_1 (dest1, CONST0_RTX (SFmode));
emit_move_insn_1 (dest2, CONST0_RTX (SFmode));
DONE; DONE;
}) })
...@@ -8625,8 +8519,8 @@ ...@@ -8625,8 +8519,8 @@
(set_attr "v3pipe" "true,true,true,*,*,*,*,*,*,true,true")]) (set_attr "v3pipe" "true,true,true,*,*,*,*,*,*,true,true")])
(define_insn "*mov<VM64:mode>_insn_sp64" (define_insn "*mov<VM64:mode>_insn_sp64"
[(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,m,m,*r, m,*r, e,*r") [(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,e,W,m,*r, m,*r, e,*r")
(match_operand:VM64 1 "input_operand" "Y,C,e,m,e,Y, m,*r, e,*r,*r"))] (match_operand:VM64 1 "input_operand" "Y,Z,e,W,e,Y, m,*r, e,*r,*r"))]
"TARGET_VIS "TARGET_VIS
&& TARGET_ARCH64 && TARGET_ARCH64
&& (register_operand (operands[0], <VM64:MODE>mode) && (register_operand (operands[0], <VM64:MODE>mode)
...@@ -8648,13 +8542,17 @@ ...@@ -8648,13 +8542,17 @@
(set_attr "v3pipe" "true,true,true,*,*,*,*,*,*,*,*")]) (set_attr "v3pipe" "true,true,true,*,*,*,*,*,*,*,*")])
(define_insn "*mov<VM64:mode>_insn_sp32" (define_insn "*mov<VM64:mode>_insn_sp32"
[(set (match_operand:VM64 0 "nonimmediate_operand" "=e,e,e,*r, f,e,m,m,U,r,T,T, o,*r") [(set (match_operand:VM64 0 "nonimmediate_operand"
(match_operand:VM64 1 "input_operand" "Y,C,e, f,*r,m,e,Y,T,T,U,r,*r,*r"))] "=T,o,e,e,e,*r, f,e,W,U,T,e,o,*r,*r, o")
(match_operand:VM64 1 "input_operand"
" Y,Y,Y,Z,e, f,*r,W,e,T,U,o,e,*r, o,*r"))]
"TARGET_VIS "TARGET_VIS
&& TARGET_ARCH32 && TARGET_ARCH32
&& (register_operand (operands[0], <VM64:MODE>mode) && (register_operand (operands[0], <VM64:MODE>mode)
|| register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))" || register_or_zero_or_all_ones_operand (operands[1], <VM64:MODE>mode))"
"@ "@
stx\t%r1, %0
#
fzero\t%0 fzero\t%0
fone\t%0 fone\t%0
fsrc2\t%1, %0 fsrc2\t%1, %0
...@@ -8662,71 +8560,70 @@ ...@@ -8662,71 +8560,70 @@
# #
ldd\t%1, %0 ldd\t%1, %0
std\t%1, %0 std\t%1, %0
stx\t%r1, %0
ldd\t%1, %0
ldd\t%1, %0 ldd\t%1, %0
std\t%1, %0 std\t%1, %0
std\t%1, %0
# #
#" #
[(set_attr "type" "visl,visl,vismv,*,*,fpload,fpstore,store,load,load,store,store,*,*") #
(set_attr "length" "*,*,*,2,2,*,*,*,*,*,*,*,2,2") ldd\t%1, %0
(set_attr "cpu_feature" "vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*") std\t%1, %0"
(set_attr "v3pipe" "true,true,true,*,*,*,*,*,*,*,*,*,*,*") [(set_attr "type" "store,*,visl,visl,vismv,*,*,fpload,fpstore,load,store,*,*,*,load,store")
(set_attr "lra" "*,*,*,*,*,*,*,*,disabled,enabled,disabled,enabled,*,*")]) (set_attr "length" "*,2,*,*,*,2,2,*,*,*,*,2,2,2,*,*")
(set_attr "cpu_feature" "*,*,vis,vis,vis,vis3,vis3,*,*,*,*,*,*,*,*,*")
(set_attr "v3pipe" "*,*,true,true,true,*,*,*,*,*,*,*,*,*,*,*")
(set_attr "lra" "*,*,*,*,*,*,*,*,*,disabled,disabled,*,*,*,*,*")])
(define_split (define_split
[(set (match_operand:VM64 0 "memory_operand" "") [(set (match_operand:VM64 0 "register_operand" "")
(match_operand:VM64 1 "register_operand" ""))] (match_operand:VM64 1 "register_operand" ""))]
"reload_completed "reload_completed
&& TARGET_VIS && TARGET_VIS
&& TARGET_ARCH32 && TARGET_ARCH32
&& (((REGNO (operands[1]) % 2) != 0) && sparc_split_reg_reg_legitimate (operands[0], operands[1])"
|| !mem_min_alignment (operands[0], 8))
&& offsettable_memref_p (operands[0])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx word0, word1; sparc_split_reg_reg (operands[0], operands[1], SImode);
word0 = adjust_address (operands[0], SImode, 0);
word1 = adjust_address (operands[0], SImode, 4);
emit_move_insn_1 (word0, gen_highpart (SImode, operands[1]));
emit_move_insn_1 (word1, gen_lowpart (SImode, operands[1]));
DONE; DONE;
}) })
(define_split (define_split
[(set (match_operand:VM64 0 "register_operand" "") [(set (match_operand:VM64 0 "register_operand" "")
(match_operand:VM64 1 "register_operand" ""))] (match_operand:VM64 1 "memory_operand" ""))]
"reload_completed "reload_completed
&& TARGET_VIS && TARGET_VIS
&& TARGET_ARCH32 && TARGET_ARCH32
&& sparc_split_regreg_legitimate (operands[0], operands[1])" && sparc_split_reg_mem_legitimate (operands[0], operands[1])"
[(clobber (const_int 0))] [(clobber (const_int 0))]
{ {
rtx set_dest = operands[0]; sparc_split_reg_mem (operands[0], operands[1], SImode);
rtx set_src = operands[1]; DONE;
rtx dest1, dest2; })
rtx src1, src2;
dest1 = gen_highpart (SImode, set_dest); (define_split
dest2 = gen_lowpart (SImode, set_dest); [(set (match_operand:VM64 0 "memory_operand" "")
src1 = gen_highpart (SImode, set_src); (match_operand:VM64 1 "register_operand" ""))]
src2 = gen_lowpart (SImode, set_src); "reload_completed
&& TARGET_VIS
&& TARGET_ARCH32
&& sparc_split_reg_mem_legitimate (operands[1], operands[0])"
[(clobber (const_int 0))]
{
sparc_split_mem_reg (operands[0], operands[1], SImode);
DONE;
})
/* Now emit using the real source and destination we found, swapping (define_split
the order if we detect overlap. */ [(set (match_operand:VM64 0 "memory_operand" "")
if (reg_overlap_mentioned_p (dest1, src2)) (match_operand:VM64 1 "const_zero_operand" ""))]
{ "reload_completed
emit_insn (gen_movsi (dest2, src2)); && TARGET_VIS
emit_insn (gen_movsi (dest1, src1)); && TARGET_ARCH32
} && !mem_min_alignment (operands[0], 8)
else && offsettable_memref_p (operands[0])"
{ [(clobber (const_int 0))]
emit_insn (gen_movsi (dest1, src1)); {
emit_insn (gen_movsi (dest2, src2)); emit_move_insn_1 (adjust_address (operands[0], SImode, 0), const0_rtx);
} emit_move_insn_1 (adjust_address (operands[0], SImode, 4), const0_rtx);
DONE; DONE;
}) })
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment