sparc-protos.h (sparc_expand_move): New prototype.
* config/sparc/sparc-protos.h (sparc_expand_move): New prototype. * config/sparc/sparc.c (sparc_expand_move): New function. (sparc_emit_set_const64): Rewrite assert condition on entry. (legitimate_constant_p) <CONST_VECTOR>: New case. (legitimize_pic_address): Use TARGET_ARCH64 to select the mode. * config/sparc/sparc.md (movqi, movhi, movsi, movdi, movV32, movV64, movtf): Use nonimmediate_operand for the first operand. Rewrite. Only invoke sparc_expand_move. * config/sparc/predicates.md (input_operand): Reorder tests. From-SVN: r100077
This commit is contained in:
parent
7c68fabb78
commit
bea5071fd0
5 changed files with 182 additions and 436 deletions
|
@ -1,3 +1,15 @@
|
|||
2005-05-23 Eric Botcazou <ebotcazou@libertysurf.fr>
|
||||
|
||||
* config/sparc/sparc-protos.h (sparc_expand_move): New prototype.
|
||||
* config/sparc/sparc.c (sparc_expand_move): New function.
|
||||
(sparc_emit_set_const64): Rewrite assert condition on entry.
|
||||
(legitimate_constant_p) <CONST_VECTOR>: New case.
|
||||
(legitimize_pic_address): Use TARGET_ARCH64 to select the mode.
|
||||
* config/sparc/sparc.md (movqi, movhi, movsi, movdi, movV32,
|
||||
movV64, movtf): Use nonimmediate_operand for the first operand.
|
||||
Rewrite. Only invoke sparc_expand_move.
|
||||
* config/sparc/predicates.md (input_operand): Reorder tests.
|
||||
|
||||
2005-05-23 Jan Beulich <jbeulich@novell.com>
|
||||
|
||||
* gthr-posix.h (__gthread_recursive_mutex_init_function): Add
|
||||
|
|
|
@ -380,8 +380,10 @@
|
|||
if (mode != VOIDmode && GET_MODE (op) != VOIDmode && mode != GET_MODE (op))
|
||||
return false;
|
||||
|
||||
mclass = GET_MODE_CLASS (mode);
|
||||
|
||||
/* Allow any 1-instruction integer constant. */
|
||||
if (GET_MODE_CLASS (mode) == MODE_INT
|
||||
if (mclass == MODE_INT
|
||||
&& (small_int_operand (op, mode) || const_high_operand (op, mode)))
|
||||
return true;
|
||||
|
||||
|
@ -392,16 +394,14 @@
|
|||
&& (GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT))
|
||||
return true;
|
||||
|
||||
if (register_operand (op, mode))
|
||||
return true;
|
||||
|
||||
mclass = GET_MODE_CLASS (mode);
|
||||
if ((mclass == MODE_FLOAT && GET_CODE (op) == CONST_DOUBLE)
|
||||
|| (mclass == MODE_VECTOR_INT && GET_CODE (op) == CONST_VECTOR))
|
||||
return true;
|
||||
|
||||
/* If this is a SUBREG, look inside so that we handle
|
||||
paradoxical ones. */
|
||||
if (register_operand (op, mode))
|
||||
return true;
|
||||
|
||||
/* If this is a SUBREG, look inside so that we handle paradoxical ones. */
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
|
|||
extern rtx legitimize_tls_address (rtx);
|
||||
extern rtx legitimize_address (rtx, rtx, enum machine_mode);
|
||||
extern void sparc_defer_case_vector (rtx, rtx, int);
|
||||
extern bool sparc_expand_move (enum machine_mode, rtx *);
|
||||
extern void sparc_emit_set_const32 (rtx, rtx);
|
||||
extern void sparc_emit_set_const64 (rtx, rtx);
|
||||
extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
|
||||
|
|
|
@ -801,9 +801,6 @@ v9_regcmp_p (enum rtx_code code)
|
|||
|| code == LE || code == GT);
|
||||
}
|
||||
|
||||
|
||||
/* Operand constraints. */
|
||||
|
||||
/* Nonzero if OP is a floating point constant which can
|
||||
be loaded into an integer register using a single
|
||||
sethi instruction. */
|
||||
|
@ -877,9 +874,127 @@ tls_symbolic_operand (rtx op)
|
|||
return 0;
|
||||
return SYMBOL_REF_TLS_MODEL (op);
|
||||
}
|
||||
|
||||
/* We know it can't be done in one insn when we get here,
|
||||
the movsi expander guarantees this. */
|
||||
|
||||
/* Expand a move instruction. Return true if all work is done. */
|
||||
|
||||
bool
|
||||
sparc_expand_move (enum machine_mode mode, rtx *operands)
|
||||
{
|
||||
/* Handle sets of MEM first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
/* 0 is a register (or a pair of registers) on SPARC. */
|
||||
if (register_or_zero_operand (operands[1], mode))
|
||||
return false;
|
||||
|
||||
if (!reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (mode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup TLS cases. */
|
||||
if (tls_symbolic_operand (operands [1]))
|
||||
operands[1] = legitimize_tls_address (operands[1]);
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic && CONSTANT_P (operands[1]))
|
||||
{
|
||||
if (pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], mode, 0);
|
||||
|
||||
if (GET_CODE (operands[1]) == LABEL_REF && mode == SImode)
|
||||
{
|
||||
emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (GET_CODE (operands[1]) == LABEL_REF && mode == DImode)
|
||||
{
|
||||
gcc_assert (TARGET_ARCH64);
|
||||
emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (symbolic_operand (operands[1], mode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
mode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are trying to toss an integer constant into FP registers,
|
||||
or loading a FP or vector constant, force it into memory. */
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& REG_P (operands[0])
|
||||
&& (SPARC_FP_REG_P (REGNO (operands[0]))
|
||||
|| SCALAR_FLOAT_MODE_P (mode)
|
||||
|| VECTOR_MODE_P (mode)))
|
||||
{
|
||||
/* emit_group_store will send such bogosity to us when it is
|
||||
not storing directly into memory. So fix this up to avoid
|
||||
crashes in output_constant_pool. */
|
||||
if (operands [1] == const0_rtx)
|
||||
operands[1] = CONST0_RTX (mode);
|
||||
|
||||
/* We can clear FP registers if TARGET_VIS, and always other regs. */
|
||||
if ((TARGET_VIS || REGNO (operands[0]) < SPARC_FIRST_FP_REG)
|
||||
&& const_zero_operand (operands[1], mode))
|
||||
return false;
|
||||
|
||||
if (REGNO (operands[0]) < SPARC_FIRST_FP_REG
|
||||
/* We are able to build any SF constant in integer registers
|
||||
with at most 2 instructions. */
|
||||
&& (mode == SFmode
|
||||
/* And any DF constant in integer registers. */
|
||||
|| (mode == DFmode
|
||||
&& (reload_completed || reload_in_progress))))
|
||||
return false;
|
||||
|
||||
operands[1] = force_const_mem (mode, operands[1]);
|
||||
if (!reload_in_progress)
|
||||
operands[1] = validize_mem (operands[1]);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Accept non-constants and valid constants unmodified. */
|
||||
if (!CONSTANT_P (operands[1])
|
||||
|| GET_CODE (operands[1]) == HIGH
|
||||
|| input_operand (operands[1], mode))
|
||||
return false;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case QImode:
|
||||
/* All QImode constants require only one insn, so proceed. */
|
||||
break;
|
||||
|
||||
case HImode:
|
||||
case SImode:
|
||||
sparc_emit_set_const32 (operands[0], operands[1]);
|
||||
return true;
|
||||
|
||||
case DImode:
|
||||
/* input_operand should have filtered out 32-bit mode. */
|
||||
sparc_emit_set_const64 (operands[0], operands[1]);
|
||||
return true;
|
||||
|
||||
default:
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Load OP1, a 32-bit constant, into OP0, a register.
|
||||
We know it can't be done in one insn when we get
|
||||
here, the move expander guarantees this. */
|
||||
|
||||
void
|
||||
sparc_emit_set_const32 (rtx op0, rtx op1)
|
||||
{
|
||||
|
@ -918,13 +1033,13 @@ sparc_emit_set_const32 (rtx op0, rtx op1)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Load OP1, a symbolic 64-bit constant, into OP0, a DImode register.
|
||||
If TEMP is nonzero, we are forbidden to use any other scratch
|
||||
registers. Otherwise, we are allowed to generate them as needed.
|
||||
|
||||
Note that TEMP may have TImode if the code model is TARGET_CM_MEDANY
|
||||
or TARGET_CM_EMBMEDANY (see the reload_indi and reload_outdi patterns). */
|
||||
|
||||
void
|
||||
sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp)
|
||||
{
|
||||
|
@ -1488,14 +1603,9 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
|
|||
rtx temp = 0;
|
||||
|
||||
/* Sanity check that we know what we are working with. */
|
||||
gcc_assert (TARGET_ARCH64);
|
||||
|
||||
if (GET_CODE (op0) != SUBREG)
|
||||
{
|
||||
gcc_assert (GET_CODE (op0) == REG
|
||||
&& (REGNO (op0) < SPARC_FIRST_FP_REG
|
||||
|| REGNO (op0) > SPARC_LAST_V9_FP_REG));
|
||||
}
|
||||
gcc_assert (TARGET_ARCH64
|
||||
&& (GET_CODE (op0) == SUBREG
|
||||
|| (REG_P (op0) && ! SPARC_FP_REG_P (REGNO (op0)))));
|
||||
|
||||
if (reload_in_progress || reload_completed)
|
||||
temp = op0;
|
||||
|
@ -2626,9 +2736,16 @@ legitimate_constant_p (rtx x)
|
|||
/* Floating point constants are generally not ok.
|
||||
The only exception is 0.0 in VIS. */
|
||||
if (TARGET_VIS
|
||||
&& (GET_MODE (x) == SFmode
|
||||
|| GET_MODE (x) == DFmode
|
||||
|| GET_MODE (x) == TFmode)
|
||||
&& SCALAR_FLOAT_MODE_P (GET_MODE (x))
|
||||
&& const_zero_operand (x, GET_MODE (x)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
case CONST_VECTOR:
|
||||
/* Vector constants are generally not ok.
|
||||
The only exception is 0 in VIS. */
|
||||
if (TARGET_VIS
|
||||
&& const_zero_operand (x, GET_MODE (x)))
|
||||
return true;
|
||||
|
||||
|
@ -3007,16 +3124,16 @@ legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
|
|||
won't get confused into thinking that these two instructions
|
||||
are loading in the true address of the symbol. If in the
|
||||
future a PIC rtx exists, that should be used instead. */
|
||||
if (Pmode == SImode)
|
||||
{
|
||||
emit_insn (gen_movsi_high_pic (temp_reg, orig));
|
||||
emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
|
||||
}
|
||||
else
|
||||
if (TARGET_ARCH64)
|
||||
{
|
||||
emit_insn (gen_movdi_high_pic (temp_reg, orig));
|
||||
emit_insn (gen_movdi_lo_sum_pic (temp_reg, temp_reg, orig));
|
||||
}
|
||||
else
|
||||
{
|
||||
emit_insn (gen_movsi_high_pic (temp_reg, orig));
|
||||
emit_insn (gen_movsi_lo_sum_pic (temp_reg, temp_reg, orig));
|
||||
}
|
||||
address = temp_reg;
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1723,54 +1723,12 @@
|
|||
;; Integer move instructions
|
||||
|
||||
(define_expand "movqi"
|
||||
[(set (match_operand:QI 0 "general_operand" "")
|
||||
[(set (match_operand:QI 0 "nonimmediate_operand" "")
|
||||
(match_operand:QI 1 "general_operand" ""))]
|
||||
""
|
||||
{
|
||||
/* Working with CONST_INTs is easier, so convert
|
||||
a double if needed. */
|
||||
if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), QImode);
|
||||
|
||||
/* Handle sets of MEM first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], QImode))
|
||||
goto movqi_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (QImode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup TLS cases. */
|
||||
if (tls_symbolic_operand (operands [1]))
|
||||
operands[1] = legitimize_tls_address (operands[1]);
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], QImode, 0);
|
||||
|
||||
if (symbolic_operand (operands[1], QImode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
QImode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
goto movqi_is_ok;
|
||||
}
|
||||
}
|
||||
|
||||
/* All QI constants require only one insn, so proceed. */
|
||||
|
||||
movqi_is_ok:
|
||||
;
|
||||
if (sparc_expand_move (QImode, operands))
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "*movqi_insn"
|
||||
|
@ -1786,62 +1744,12 @@
|
|||
(set_attr "us3load_type" "*,3cycle,*")])
|
||||
|
||||
(define_expand "movhi"
|
||||
[(set (match_operand:HI 0 "general_operand" "")
|
||||
[(set (match_operand:HI 0 "nonimmediate_operand" "")
|
||||
(match_operand:HI 1 "general_operand" ""))]
|
||||
""
|
||||
{
|
||||
/* Working with CONST_INTs is easier, so convert
|
||||
a double if needed. */
|
||||
if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), HImode);
|
||||
|
||||
/* Handle sets of MEM first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], HImode))
|
||||
goto movhi_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (HImode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup TLS cases. */
|
||||
if (tls_symbolic_operand (operands [1]))
|
||||
operands[1] = legitimize_tls_address (operands[1]);
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], HImode, 0);
|
||||
|
||||
if (symbolic_operand (operands[1], HImode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
HImode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
goto movhi_is_ok;
|
||||
}
|
||||
}
|
||||
|
||||
/* This makes sure we will not get rematched due to splittage. */
|
||||
if (! CONSTANT_P (operands[1]) || input_operand (operands[1], HImode))
|
||||
;
|
||||
else if (GET_CODE (operands[1]) != HIGH
|
||||
&& GET_CODE (operands[1]) != LO_SUM)
|
||||
{
|
||||
sparc_emit_set_const32 (operands[0], operands[1]);
|
||||
if (sparc_expand_move (HImode, operands))
|
||||
DONE;
|
||||
}
|
||||
|
||||
movhi_is_ok:
|
||||
;
|
||||
})
|
||||
|
||||
(define_insn "*movhi_insn"
|
||||
|
@ -1866,77 +1774,12 @@
|
|||
"or\t%1, %2, %0")
|
||||
|
||||
(define_expand "movsi"
|
||||
[(set (match_operand:SI 0 "general_operand" "")
|
||||
[(set (match_operand:SI 0 "nonimmediate_operand" "")
|
||||
(match_operand:SI 1 "general_operand" ""))]
|
||||
""
|
||||
{
|
||||
/* Working with CONST_INTs is easier, so convert
|
||||
a double if needed. */
|
||||
if (GET_CODE (operands[1]) == CONST_DOUBLE)
|
||||
operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), SImode);
|
||||
|
||||
/* Handle sets of MEM first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], SImode))
|
||||
goto movsi_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (SImode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup TLS cases. */
|
||||
if (tls_symbolic_operand (operands [1]))
|
||||
operands[1] = legitimize_tls_address (operands[1]);
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], SImode, 0);
|
||||
|
||||
if (GET_CODE (operands[1]) == LABEL_REF)
|
||||
{
|
||||
emit_insn (gen_movsi_pic_label_ref (operands[0], operands[1]));
|
||||
if (sparc_expand_move (SImode, operands))
|
||||
DONE;
|
||||
}
|
||||
|
||||
if (symbolic_operand (operands[1], SImode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
SImode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
goto movsi_is_ok;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are trying to toss an integer constant into the
|
||||
FPU registers, force it into memory. */
|
||||
if (GET_CODE (operands[0]) == REG
|
||||
&& REGNO (operands[0]) >= SPARC_FIRST_FP_REG
|
||||
&& REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
|
||||
&& CONSTANT_P (operands[1]))
|
||||
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
|
||||
operands[1]));
|
||||
|
||||
/* This makes sure we will not get rematched due to splittage. */
|
||||
if (! CONSTANT_P (operands[1]) || input_operand (operands[1], SImode))
|
||||
;
|
||||
else if (GET_CODE (operands[1]) != HIGH
|
||||
&& GET_CODE (operands[1]) != LO_SUM)
|
||||
{
|
||||
sparc_emit_set_const32 (operands[0], operands[1]);
|
||||
DONE;
|
||||
}
|
||||
|
||||
movsi_is_ok:
|
||||
;
|
||||
})
|
||||
|
||||
(define_insn "*movsi_insn"
|
||||
|
@ -2025,85 +1868,12 @@
|
|||
"or\t%1, %%lo(%a3-(%a2-.)), %0")
|
||||
|
||||
(define_expand "movdi"
|
||||
[(set (match_operand:DI 0 "general_operand" "")
|
||||
[(set (match_operand:DI 0 "nonimmediate_operand" "")
|
||||
(match_operand:DI 1 "general_operand" ""))]
|
||||
""
|
||||
{
|
||||
/* Working with CONST_INTs is easier, so convert
|
||||
a double if needed. */
|
||||
if (GET_CODE (operands[1]) == CONST_DOUBLE
|
||||
#if HOST_BITS_PER_WIDE_INT == 32
|
||||
&& ((CONST_DOUBLE_HIGH (operands[1]) == 0
|
||||
&& (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) == 0)
|
||||
|| (CONST_DOUBLE_HIGH (operands[1]) == (HOST_WIDE_INT) 0xffffffff
|
||||
&& (CONST_DOUBLE_LOW (operands[1]) & 0x80000000) != 0))
|
||||
#endif
|
||||
)
|
||||
operands[1] = gen_int_mode (CONST_DOUBLE_LOW (operands[1]), DImode);
|
||||
|
||||
/* Handle MEM cases first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], DImode))
|
||||
goto movdi_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (DImode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup TLS cases. */
|
||||
if (tls_symbolic_operand (operands [1]))
|
||||
operands[1] = legitimize_tls_address (operands[1]);
|
||||
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], DImode, 0);
|
||||
|
||||
if (GET_CODE (operands[1]) == LABEL_REF)
|
||||
{
|
||||
gcc_assert (TARGET_ARCH64);
|
||||
emit_insn (gen_movdi_pic_label_ref (operands[0], operands[1]));
|
||||
if (sparc_expand_move (DImode, operands))
|
||||
DONE;
|
||||
}
|
||||
|
||||
if (symbolic_operand (operands[1], DImode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
DImode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
goto movdi_is_ok;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are trying to toss an integer constant into the
|
||||
FPU registers, force it into memory. */
|
||||
if (GET_CODE (operands[0]) == REG
|
||||
&& REGNO (operands[0]) >= SPARC_FIRST_FP_REG
|
||||
&& REGNO (operands[0]) <= SPARC_LAST_V9_FP_REG
|
||||
&& CONSTANT_P (operands[1]))
|
||||
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
|
||||
operands[1]));
|
||||
|
||||
/* This makes sure we will not get rematched due to splittage. */
|
||||
if (! CONSTANT_P (operands[1]) || input_operand (operands[1], DImode))
|
||||
;
|
||||
else if (TARGET_ARCH64
|
||||
&& GET_CODE (operands[1]) != HIGH
|
||||
&& GET_CODE (operands[1]) != LO_SUM)
|
||||
{
|
||||
sparc_emit_set_const64 (operands[0], operands[1]);
|
||||
DONE;
|
||||
}
|
||||
|
||||
movdi_is_ok:
|
||||
;
|
||||
})
|
||||
|
||||
;; Be careful, fmovd does not exist when !v9.
|
||||
|
@ -2552,65 +2322,12 @@
|
|||
|
||||
;; Yes, you guessed it right, the former movsf expander.
|
||||
(define_expand "mov<V32:mode>"
|
||||
[(set (match_operand:V32 0 "general_operand" "")
|
||||
[(set (match_operand:V32 0 "nonimmediate_operand" "")
|
||||
(match_operand:V32 1 "general_operand" ""))]
|
||||
"<V32:MODE>mode == SFmode || TARGET_VIS"
|
||||
{
|
||||
/* Force constants into memory. */
|
||||
if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
|
||||
{
|
||||
/* emit_group_store will send such bogosity to us when it is
|
||||
not storing directly into memory. So fix this up to avoid
|
||||
crashes in output_constant_pool. */
|
||||
if (operands [1] == const0_rtx)
|
||||
operands[1] = CONST0_RTX (<V32:MODE>mode);
|
||||
|
||||
if ((TARGET_VIS || REGNO (operands[0]) < 32)
|
||||
&& const_zero_operand (operands[1], <V32:MODE>mode))
|
||||
goto movsf_is_ok;
|
||||
|
||||
/* We are able to build any SF constant in integer registers
|
||||
with at most 2 instructions. */
|
||||
if (REGNO (operands[0]) < 32
|
||||
&& <V32:MODE>mode == SFmode)
|
||||
goto movsf_is_ok;
|
||||
|
||||
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
|
||||
operands[1]));
|
||||
}
|
||||
|
||||
/* Handle sets of MEM first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], <V32:MODE>mode))
|
||||
goto movsf_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (<V32:MODE>mode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], <V32:MODE>mode, 0);
|
||||
|
||||
if (symbolic_operand (operands[1], <V32:MODE>mode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
<V32:MODE>mode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
}
|
||||
}
|
||||
|
||||
movsf_is_ok:
|
||||
;
|
||||
if (sparc_expand_move (<V32:MODE>mode, operands))
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "*movsf_insn"
|
||||
|
@ -2741,65 +2458,12 @@
|
|||
|
||||
;; Yes, you again guessed it right, the former movdf expander.
|
||||
(define_expand "mov<V64:mode>"
|
||||
[(set (match_operand:V64 0 "general_operand" "")
|
||||
[(set (match_operand:V64 0 "nonimmediate_operand" "")
|
||||
(match_operand:V64 1 "general_operand" ""))]
|
||||
"<V64:MODE>mode == DFmode || TARGET_VIS"
|
||||
{
|
||||
/* Force constants into memory. */
|
||||
if (GET_CODE (operands[0]) == REG && CONSTANT_P (operands[1]))
|
||||
{
|
||||
/* emit_group_store will send such bogosity to us when it is
|
||||
not storing directly into memory. So fix this up to avoid
|
||||
crashes in output_constant_pool. */
|
||||
if (operands [1] == const0_rtx)
|
||||
operands[1] = CONST0_RTX (<V64:MODE>mode);
|
||||
|
||||
if ((TARGET_VIS || REGNO (operands[0]) < 32)
|
||||
&& const_zero_operand (operands[1], <V64:MODE>mode))
|
||||
goto movdf_is_ok;
|
||||
|
||||
/* We are able to build any DF constant in integer registers. */
|
||||
if (REGNO (operands[0]) < 32
|
||||
&& <V64:MODE>mode == DFmode
|
||||
&& (reload_completed || reload_in_progress))
|
||||
goto movdf_is_ok;
|
||||
|
||||
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
|
||||
operands[1]));
|
||||
}
|
||||
|
||||
/* Handle MEM cases first. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], <V64:MODE>mode))
|
||||
goto movdf_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (<V64:MODE>mode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], <V64:MODE>mode, 0);
|
||||
|
||||
if (symbolic_operand (operands[1], <V64:MODE>mode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
<V64:MODE>mode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
}
|
||||
}
|
||||
|
||||
movdf_is_ok:
|
||||
;
|
||||
if (sparc_expand_move (<V64:MODE>mode, operands))
|
||||
DONE;
|
||||
})
|
||||
|
||||
;; Be careful, fmovd does not exist when !v9.
|
||||
|
@ -3137,60 +2801,12 @@
|
|||
})
|
||||
|
||||
(define_expand "movtf"
|
||||
[(set (match_operand:TF 0 "general_operand" "")
|
||||
[(set (match_operand:TF 0 "nonimmediate_operand" "")
|
||||
(match_operand:TF 1 "general_operand" ""))]
|
||||
""
|
||||
{
|
||||
/* Force TFmode constants into memory. */
|
||||
if (GET_CODE (operands[0]) == REG
|
||||
&& CONSTANT_P (operands[1]))
|
||||
{
|
||||
/* emit_group_store will send such bogosity to us when it is
|
||||
not storing directly into memory. So fix this up to avoid
|
||||
crashes in output_constant_pool. */
|
||||
if (operands [1] == const0_rtx)
|
||||
operands[1] = CONST0_RTX (TFmode);
|
||||
|
||||
if (TARGET_VIS && const_zero_operand (operands[1], TFmode))
|
||||
goto movtf_is_ok;
|
||||
|
||||
operands[1] = validize_mem (force_const_mem (GET_MODE (operands[0]),
|
||||
operands[1]));
|
||||
}
|
||||
|
||||
/* Handle MEM cases first, note that only v9 guarantees
|
||||
full 16-byte alignment for quads. */
|
||||
if (GET_CODE (operands[0]) == MEM)
|
||||
{
|
||||
if (register_or_zero_operand (operands[1], TFmode))
|
||||
goto movtf_is_ok;
|
||||
|
||||
if (! reload_in_progress)
|
||||
{
|
||||
operands[0] = validize_mem (operands[0]);
|
||||
operands[1] = force_reg (TFmode, operands[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fixup PIC cases. */
|
||||
if (flag_pic)
|
||||
{
|
||||
if (CONSTANT_P (operands[1])
|
||||
&& pic_address_needs_scratch (operands[1]))
|
||||
operands[1] = legitimize_pic_address (operands[1], TFmode, 0);
|
||||
|
||||
if (symbolic_operand (operands[1], TFmode))
|
||||
{
|
||||
operands[1] = legitimize_pic_address (operands[1],
|
||||
TFmode,
|
||||
(reload_in_progress ?
|
||||
operands[0] :
|
||||
NULL_RTX));
|
||||
}
|
||||
}
|
||||
|
||||
movtf_is_ok:
|
||||
;
|
||||
if (sparc_expand_move (TFmode, operands))
|
||||
DONE;
|
||||
})
|
||||
|
||||
(define_insn "*movtf_insn_sp32"
|
||||
|
|
Loading…
Add table
Reference in a new issue