predicates.md (input_operand): Do not consider TImode constants as 1-instruction integer constants.
* config/sparc/predicates.md (input_operand): Do not consider TImode constants as 1-instruction integer constants. Use register_or_zero_operand instead of register_operand and tidy up. * config/sparc/sparc.md (movti): New expander. (movti_insn_sp64): New instruction. (movti_insn_sp64_hq): Likewise. (TImode splitters): New splitters. * config/sparc/sparc.c (sparc_expand_move) <TImode>: New case. (sparc_legitimate_address_p): Return 0 for REG+REG in TImode. * config/sparc/sparc-protos.h (arith_double_4096_operand): Delete. (arith_4096_operand): Likewise. (zero_operand): Likewise. (fp_zero_operand): Likewise. (reg_or_0_operand): Likewise. From-SVN: r191283
This commit is contained in:
parent
12308bc61d
commit
03c432bd84
@ -1,3 +1,21 @@
|
||||
2012-09-13 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* config/sparc/predicates.md (input_operand): Do not consider TImode
|
||||
constants as 1-instruction integer constants.
|
||||
Use register_or_zero_operand instead of register_operand and tidy up.
|
||||
* config/sparc/sparc.md (movti): New expander.
|
||||
(movti_insn_sp64): New instruction.
|
||||
(movti_insn_sp64_hq): Likewise.
|
||||
(TImode splitters): New splitters.
|
||||
* config/sparc/sparc.c (sparc_expand_move) <TImode>: New case.
|
||||
(sparc_legitimate_address_p): Return 0 for REG+REG in TImode.
|
||||
|
||||
* config/sparc/sparc-protos.h (arith_double_4096_operand): Delete.
|
||||
(arith_4096_operand): Likewise.
|
||||
(zero_operand): Likewise.
|
||||
(fp_zero_operand): Likewise.
|
||||
(reg_or_0_operand): Likewise.
|
||||
|
||||
2012-09-13 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
* configure.ac (CXXFLAGS): Remove -O2 when not bootstrapping.
|
||||
|
@ -357,7 +357,7 @@
|
||||
(define_predicate "arith_add_operand"
|
||||
(ior (match_operand 0 "arith_operand")
|
||||
(match_operand 0 "const_4096_operand")))
|
||||
|
||||
|
||||
;; Return true if OP is suitable as second double operand for add/sub.
|
||||
(define_predicate "arith_double_add_operand"
|
||||
(match_code "const_int,const_double,reg,subreg")
|
||||
@ -427,6 +427,7 @@
|
||||
|
||||
/* Allow any 1-instruction integer constant. */
|
||||
if (mclass == MODE_INT
|
||||
&& mode != TImode
|
||||
&& (small_int_operand (op, mode) || const_high_operand (op, mode)))
|
||||
return true;
|
||||
|
||||
@ -440,12 +441,10 @@
|
||||
if (mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
|
||||
return true;
|
||||
|
||||
if (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR
|
||||
&& (const_zero_operand (op, mode)
|
||||
|| const_all_ones_operand (op, mode)))
|
||||
if (mclass == MODE_VECTOR_INT && const_all_ones_operand (op, mode))
|
||||
return true;
|
||||
|
||||
if (register_operand (op, mode))
|
||||
if (register_or_zero_operand (op, mode))
|
||||
return true;
|
||||
|
||||
/* If this is a SUBREG, look inside so that we handle paradoxical ones. */
|
||||
|
@ -82,11 +82,6 @@ extern const char *output_probe_stack_range (rtx, rtx);
|
||||
extern bool emit_scc_insn (rtx []);
|
||||
extern void emit_conditional_branch_insn (rtx []);
|
||||
extern int mems_ok_for_ldd_peep (rtx, rtx, rtx);
|
||||
extern int arith_double_4096_operand (rtx, enum machine_mode);
|
||||
extern int arith_4096_operand (rtx, enum machine_mode);
|
||||
extern int zero_operand (rtx, enum machine_mode);
|
||||
extern int fp_zero_operand (rtx, enum machine_mode);
|
||||
extern int reg_or_0_operand (rtx, enum machine_mode);
|
||||
extern int empty_delay_slot (rtx);
|
||||
extern int eligible_for_return_delay (rtx);
|
||||
extern int eligible_for_sibcall_delay (rtx);
|
||||
|
@ -1465,6 +1465,18 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
|
||||
sparc_emit_set_const64 (operands[0], operands[1]);
|
||||
return true;
|
||||
|
||||
case TImode:
|
||||
{
|
||||
rtx high, low;
|
||||
/* TImode isn't available in 32-bit mode. */
|
||||
split_double (operands[1], &high, &low);
|
||||
emit_insn (gen_movdi (operand_subword (operands[0], 0, 0, TImode),
|
||||
high));
|
||||
emit_insn (gen_movdi (operand_subword (operands[0], 1, 0, TImode),
|
||||
low));
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
@ -3492,6 +3504,10 @@ sparc_legitimate_address_p (enum machine_mode mode, rtx addr, bool strict)
|
||||
&& ! (TARGET_ARCH64 && TARGET_HARD_QUAD))
|
||||
return 0;
|
||||
|
||||
/* Likewise for TImode, but in all cases. */
|
||||
if (mode == TImode)
|
||||
return 0;
|
||||
|
||||
/* We prohibit REG + REG on ARCH32 if not optimizing for
|
||||
DFmode/DImode because then mem_min_alignment is likely to be zero
|
||||
after reload and the forced split would lack a matching splitter
|
||||
|
@ -2034,6 +2034,164 @@
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_expand "movti"
|
||||
[(set (match_operand:TI 0 "nonimmediate_operand" "")
|
||||
(match_operand:TI 1 "general_operand" ""))]
|
||||
"TARGET_ARCH64"
|
||||
{
|
||||
if (sparc_expand_move (TImode, operands))
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; We need to prevent reload from splitting TImode moves, because it
|
||||
;; might decide to overwrite a pointer with the value it points to.
|
||||
;; In that case we have to do the loads in the appropriate order so
|
||||
;; that the pointer is not destroyed too early.
|
||||
|
||||
(define_insn "*movti_insn_sp64"
|
||||
[(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?o,b")
|
||||
(match_operand:TI 1 "input_operand" "roJ,rJ, eo, e,J"))]
|
||||
"TARGET_ARCH64
|
||||
&& ! TARGET_HARD_QUAD
|
||||
&& (register_operand (operands[0], TImode)
|
||||
|| register_or_zero_operand (operands[1], TImode))"
|
||||
"#"
|
||||
[(set_attr "length" "2,2,2,2,2")
|
||||
(set_attr "cpu_feature" "*,*,fpu,fpu,vis")])
|
||||
|
||||
(define_insn "*movti_insn_sp64_hq"
|
||||
[(set (match_operand:TI 0 "nonimmediate_operand" "=r , o,?*e,?*e,?m,b")
|
||||
(match_operand:TI 1 "input_operand" "roJ,rJ, e, m, e,J"))]
|
||||
"TARGET_ARCH64
|
||||
&& TARGET_HARD_QUAD
|
||||
&& (register_operand (operands[0], TImode)
|
||||
|| register_or_zero_operand (operands[1], TImode))"
|
||||
"@
|
||||
#
|
||||
#
|
||||
fmovq\t%1, %0
|
||||
ldq\t%1, %0
|
||||
stq\t%1, %0
|
||||
#"
|
||||
[(set_attr "type" "*,*,fpmove,fpload,fpstore,*")
|
||||
(set_attr "length" "2,2,*,*,*,2")])
|
||||
|
||||
;; Now all the splits to handle multi-insn TI mode moves.
|
||||
(define_split
|
||||
[(set (match_operand:TI 0 "register_operand" "")
|
||||
(match_operand:TI 1 "register_operand" ""))]
|
||||
"reload_completed
|
||||
&& ((TARGET_FPU
|
||||
&& ! TARGET_HARD_QUAD)
|
||||
|| (! fp_register_operand (operands[0], TImode)
|
||||
&& ! fp_register_operand (operands[1], TImode)))"
|
||||
[(clobber (const_int 0))]
|
||||
{
|
||||
rtx set_dest = operands[0];
|
||||
rtx set_src = operands[1];
|
||||
rtx dest1, dest2;
|
||||
rtx src1, src2;
|
||||
|
||||
dest1 = gen_highpart (DImode, set_dest);
|
||||
dest2 = gen_lowpart (DImode, set_dest);
|
||||
src1 = gen_highpart (DImode, set_src);
|
||||
src2 = gen_lowpart (DImode, 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_movdi (dest2, src2));
|
||||
emit_insn (gen_movdi (dest1, src1));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_movdi (dest1, src1));
|
||||
emit_insn (gen_movdi (dest2, src2));
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:TI 0 "nonimmediate_operand" "")
|
||||
(match_operand:TI 1 "const_zero_operand" ""))]
|
||||
"reload_completed"
|
||||
[(clobber (const_int 0))]
|
||||
{
|
||||
rtx set_dest = operands[0];
|
||||
rtx dest1, dest2;
|
||||
|
||||
switch (GET_CODE (set_dest))
|
||||
{
|
||||
case REG:
|
||||
dest1 = gen_highpart (DImode, set_dest);
|
||||
dest2 = gen_lowpart (DImode, set_dest);
|
||||
break;
|
||||
case MEM:
|
||||
dest1 = adjust_address (set_dest, DImode, 0);
|
||||
dest2 = adjust_address (set_dest, DImode, 8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
emit_insn (gen_movdi (dest1, const0_rtx));
|
||||
emit_insn (gen_movdi (dest2, const0_rtx));
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:TI 0 "register_operand" "")
|
||||
(match_operand:TI 1 "memory_operand" ""))]
|
||||
"reload_completed
|
||||
&& offsettable_memref_p (operands[1])
|
||||
&& (! TARGET_HARD_QUAD
|
||||
|| ! fp_register_operand (operands[0], TImode))"
|
||||
[(clobber (const_int 0))]
|
||||
{
|
||||
rtx word0 = adjust_address (operands[1], DImode, 0);
|
||||
rtx word1 = adjust_address (operands[1], DImode, 8);
|
||||
rtx set_dest, dest1, dest2;
|
||||
|
||||
set_dest = operands[0];
|
||||
|
||||
dest1 = gen_highpart (DImode, set_dest);
|
||||
dest2 = gen_lowpart (DImode, set_dest);
|
||||
|
||||
/* Now output, ordering such that we don't clobber any registers
|
||||
mentioned in the address. */
|
||||
if (reg_overlap_mentioned_p (dest1, word1))
|
||||
|
||||
{
|
||||
emit_insn (gen_movdi (dest2, word1));
|
||||
emit_insn (gen_movdi (dest1, word0));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_movdi (dest1, word0));
|
||||
emit_insn (gen_movdi (dest2, word1));
|
||||
}
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_split
|
||||
[(set (match_operand:TI 0 "memory_operand" "")
|
||||
(match_operand:TI 1 "register_operand" ""))]
|
||||
"reload_completed
|
||||
&& offsettable_memref_p (operands[0])
|
||||
&& (! TARGET_HARD_QUAD
|
||||
|| ! fp_register_operand (operands[1], TImode))"
|
||||
[(clobber (const_int 0))]
|
||||
{
|
||||
rtx set_src = operands[1];
|
||||
|
||||
emit_insn (gen_movdi (adjust_address (operands[0], DImode, 0),
|
||||
gen_highpart (DImode, set_src)));
|
||||
emit_insn (gen_movdi (adjust_address (operands[0], DImode, 8),
|
||||
gen_lowpart (DImode, set_src)));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
||||
;; Floating point move instructions
|
||||
|
||||
@ -2477,7 +2635,7 @@
|
||||
dest2 = adjust_address (set_dest, DFmode, 8);
|
||||
break;
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
emit_insn (gen_movdf (dest1, CONST0_RTX (DFmode)));
|
||||
|
Loading…
Reference in New Issue
Block a user