@@ -209,6 +209,7 @@ static bool pa_can_change_mode_class (machine_mode, machine_mode, reg_class_t);
static HOST_WIDE_INT pa_starting_frame_offset (void);
static section* pa_elf_select_rtx_section(machine_mode, rtx, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED;
static void pa_atomic_assign_expand_fenv (tree *, tree *, tree *);
+static bool pa_use_lra_p (void);
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
@@ -412,7 +413,7 @@ static size_t n_deferred_plabels = 0;
#define TARGET_LEGITIMATE_ADDRESS_P pa_legitimate_address_p
#undef TARGET_LRA_P
-#define TARGET_LRA_P hook_bool_void_false
+#define TARGET_LRA_P pa_use_lra_p
#undef TARGET_HARD_REGNO_NREGS
#define TARGET_HARD_REGNO_NREGS pa_hard_regno_nregs
@@ -973,7 +974,7 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
/* During and after reload, we need to generate a REG_LABEL_OPERAND note
and update LABEL_NUSES because this is not done automatically. */
- if (reload_in_progress || reload_completed)
+ if (lra_in_progress || reload_in_progress || reload_completed)
{
/* Extract LABEL_REF. */
if (GET_CODE (orig) == CONST)
@@ -998,7 +999,7 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
/* Before reload, allocate a temporary register for the intermediate
result. This allows the sequence to be deleted when the final
result is unused and the insns are trivially dead. */
- tmp_reg = ((reload_in_progress || reload_completed)
+ tmp_reg = ((lra_in_progress || reload_in_progress || reload_completed)
? reg : gen_reg_rtx (Pmode));
if (function_label_operand (orig, VOIDmode))
@@ -1959,11 +1960,13 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
copy_to_mode_reg (Pmode, XEXP (operand1, 0)));
if (scratch_reg
- && reload_in_progress && GET_CODE (operand0) == REG
+ && reload_in_progress
+ && GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
operand0 = reg_equiv_mem (REGNO (operand0));
else if (scratch_reg
- && reload_in_progress && GET_CODE (operand0) == SUBREG
+ && reload_in_progress
+ && GET_CODE (operand0) == SUBREG
&& GET_CODE (SUBREG_REG (operand0)) == REG
&& REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)
{
@@ -1976,11 +1979,13 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
}
if (scratch_reg
- && reload_in_progress && GET_CODE (operand1) == REG
+ && reload_in_progress
+ && GET_CODE (operand1) == REG
&& REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
operand1 = reg_equiv_mem (REGNO (operand1));
else if (scratch_reg
- && reload_in_progress && GET_CODE (operand1) == SUBREG
+ && reload_in_progress
+ && GET_CODE (operand1) == SUBREG
&& GET_CODE (SUBREG_REG (operand1)) == REG
&& REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
{
@@ -1992,12 +1997,16 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
operand1 = alter_subreg (&temp, true);
}
- if (scratch_reg && reload_in_progress && GET_CODE (operand0) == MEM
+ if (scratch_reg
+ && (lra_in_progress || reload_in_progress)
+ && GET_CODE (operand0) == MEM
&& ((tem = find_replacement (&XEXP (operand0, 0)))
!= XEXP (operand0, 0)))
operand0 = replace_equiv_address (operand0, tem);
- if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
+ if (scratch_reg
+ && (lra_in_progress || reload_in_progress)
+ && GET_CODE (operand1) == MEM
&& ((tem = find_replacement (&XEXP (operand1, 0)))
!= XEXP (operand1, 0)))
operand1 = replace_equiv_address (operand1, tem);
@@ -2255,7 +2264,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
else if (GET_CODE (operand0) == MEM)
{
if (mode == DFmode && operand1 == CONST0_RTX (mode)
- && !(reload_in_progress || reload_completed))
+ && !(lra_in_progress || reload_in_progress || reload_completed))
{
rtx temp = gen_reg_rtx (DFmode);
@@ -2269,7 +2278,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
emit_insn (gen_rtx_SET (operand0, operand1));
return 1;
}
- if (! (reload_in_progress || reload_completed))
+ if (! (lra_in_progress || reload_in_progress || reload_completed))
{
operands[0] = validize_mem (operand0);
operands[1] = operand1 = force_reg (mode, operand1);
@@ -2309,7 +2318,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
rtx temp, const_part;
/* Figure out what (if any) scratch register to use. */
- if (reload_in_progress || reload_completed)
+ if (lra_in_progress || reload_in_progress || reload_completed)
{
scratch_reg = scratch_reg ? scratch_reg : operand0;
/* SCRATCH_REG will hold an address and maybe the actual
@@ -2367,7 +2376,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
rtx_insn *insn;
rtx temp;
- if (reload_in_progress || reload_completed)
+ if (lra_in_progress || reload_in_progress || reload_completed)
{
temp = scratch_reg ? scratch_reg : operand0;
/* TEMP will hold an address and maybe the actual
@@ -2411,7 +2420,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
{
rtx temp, set;
- if (reload_in_progress || reload_completed)
+ if (lra_in_progress || reload_in_progress || reload_completed)
{
temp = scratch_reg ? scratch_reg : operand0;
/* TEMP will hold an address and maybe the actual
@@ -2502,7 +2511,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
}
}
- if (reload_in_progress || reload_completed)
+ if (lra_in_progress || reload_in_progress || reload_completed)
temp = scratch_reg ? scratch_reg : operand0;
else
temp = gen_reg_rtx (mode);
@@ -6408,24 +6417,21 @@ pa_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
regno = true_regnum (x);
- /* Handle reloads for floating point loads and stores. */
- if ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
- && FP_REG_CLASS_P (rclass))
+ /* Handle reloads for floating-point loads and stores. */
+ if (regno < 0 && FP_REG_CLASS_P (rclass))
{
- if (MEM_P (x))
- {
- x = XEXP (x, 0);
+ if (REG_P (x) || GET_CODE (x) == SUBREG)
+ return NO_REGS;
- /* We don't need a secondary reload for indexed memory addresses.
+ /* We don't need a secondary reload for indexed memory addresses.
- When INT14_OK_STRICT is true, it might appear that we could
- directly allow register indirect memory addresses. However,
- this doesn't work because we don't support SUBREGs in
- floating-point register copies and reload doesn't tell us
- when it's going to use a SUBREG. */
- if (IS_INDEX_ADDR_P (x))
- return NO_REGS;
- }
+ When INT14_OK_STRICT is true, it might appear that we could
+ directly allow register indirect memory addresses. However,
+ this doesn't work because we don't support SUBREGs in
+ floating-point register copies and reload doesn't tell us
+ when it's going to use a SUBREG. */
+ if (MEM_P (x) && IS_INDEX_ADDR_P (XEXP (x, 0)))
+ return NO_REGS;
/* Request a secondary reload with a general scratch register
for everything else. ??? Could symbolic operands be handled
@@ -6442,8 +6448,14 @@ pa_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
if (rclass == SHIFT_REGS)
{
/* Handle spill. */
- if (regno >= FIRST_PSEUDO_REGISTER || regno < 0)
+ if (regno < 0)
{
+ if (REG_P (x) || GET_CODE (x) == SUBREG)
+ return GENERAL_REGS;
+
+ if (TARGET_64BIT && GET_CODE (x) == CONST_INT)
+ return GENERAL_REGS;
+
sri->icode = (in_p
? direct_optab_handler (reload_in_optab, mode)
: direct_optab_handler (reload_out_optab, mode));
@@ -10875,6 +10887,7 @@ pa_legitimate_constant_p (machine_mode mode, rtx x)
if (TARGET_64BIT
&& HOST_BITS_PER_WIDE_INT > 32
&& GET_CODE (x) == CONST_INT
+ && !lra_in_progress
&& !reload_in_progress
&& !reload_completed
&& !LEGITIMATE_64BIT_CONST_INT_P (INTVAL (x))
@@ -11026,7 +11039,8 @@ pa_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
reload on targets with non-equivalent space registers. */
&& (TARGET_NO_SPACE_REGS
|| reload_completed
- || (reload_in_progress && HARD_REGISTER_P (base))
+ || ((lra_in_progress || reload_in_progress)
+ && HARD_REGISTER_P (base))
|| REG_POINTER (base))
&& GET_CODE (index) == MULT
&& REG_P (XEXP (index, 0))
@@ -11334,4 +11348,12 @@ pa_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
reload_fenv, restore_fnenv), update_call);
}
+/* Implement TARGET_LRA_P. */
+
+static bool
+pa_use_lra_p ()
+{
+ return pa_lra_p;
+}
+
#include "gt-pa.h"
@@ -86,6 +86,10 @@ mlong-calls
Target Mask(LONG_CALLS)
Always generate long calls.
+mlra
+Target Var(pa_lra_p) Init(0)
+Use LRA instead of reload (transitional).
+
mlong-load-store
Target Mask(LONG_LOAD_STORE)
Emit long load/store sequences.
@@ -300,7 +300,7 @@
(define_predicate "integer_store_memory_operand"
(match_code "reg,mem")
{
- if (reload_in_progress
+ if ((lra_in_progress || reload_in_progress)
&& REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_renumber [REGNO (op)] < 0)
@@ -312,7 +312,7 @@
REG+D instructions in pa_emit_move_sequence. Further, the Q
constraint is used in more than simple move instructions. So,
we must return true and let reload handle the reload. */
- if (reload_in_progress)
+ if (lra_in_progress || reload_in_progress)
return true;
/* Extract CONST_INT operand. */
@@ -326,7 +326,8 @@
if (!MEM_P (op))
return false;
- return ((reload_in_progress || memory_address_p (mode, XEXP (op, 0)))
+ return ((lra_in_progress || reload_in_progress
+ || memory_address_p (mode, XEXP (op, 0)))
&& !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
&& !IS_INDEX_ADDR_P (XEXP (op, 0)));
})
@@ -346,7 +347,7 @@
(define_predicate "floating_point_store_memory_operand"
(match_code "reg,mem")
{
- if (reload_in_progress
+ if ((lra_in_progress || reload_in_progress)
&& REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_renumber [REGNO (op)] < 0)
@@ -366,7 +367,8 @@
if (!MEM_P (op))
return false;
- return ((reload_in_progress || memory_address_p (mode, XEXP (op, 0)))
+ return ((lra_in_progress || reload_in_progress
+ || memory_address_p (mode, XEXP (op, 0)))
&& (INT14_OK_STRICT || !symbolic_memory_operand (op, VOIDmode))
&& !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
&& !IS_INDEX_ADDR_P (XEXP (op, 0)));
@@ -555,7 +557,7 @@
if (register_operand (op, mode))
return true;
- if (!reload_in_progress && !reload_completed)
+ if (!lra_in_progress && !reload_in_progress && !reload_completed)
return false;
if (! MEM_P (op))