mirror of git://gcc.gnu.org/git/gcc.git
[ARM] length pop* pattern in epilogue correctly
PR target/71061 * config/arm/arm-protos.h (arm_attr_length_pop_multi): New declaration. * config/arm/arm.c (arm_attr_length_pop_multi): New function to return length for pop patterns. (arm_attr_length_push_multi): Update comments. * config/arm/arm.md (*load_multiple_with_writeback): Set "length" attribute. (*pop_multiple_with_writeback_and_return): Likewise. (*pop_multiple_with_return): Likewise. From-SVN: r237331
This commit is contained in:
parent
a0d6600253
commit
5775d58c06
|
|
@ -1,3 +1,15 @@
|
|||
2016-06-11 Jiong Wang <jiong.wang@arm.com>
|
||||
|
||||
PR target/71061
|
||||
* config/arm/arm-protos.h (arm_attr_length_pop_multi): New declaration.
|
||||
* config/arm/arm.c (arm_attr_length_pop_multi): New function to return
|
||||
length for pop patterns.
|
||||
(arm_attr_length_push_multi): Update comments.
|
||||
* config/arm/arm.md (*load_multiple_with_writeback): Set "length"
|
||||
attribute.
|
||||
(*pop_multiple_with_writeback_and_return): Likewise.
|
||||
(*pop_multiple_with_return): Likewise.
|
||||
|
||||
2016-06-11 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR middle-end/71310
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ extern const char *arm_output_iwmmxt_shift_immediate (const char *, rtx *, bool)
|
|||
extern const char *arm_output_iwmmxt_tinsr (rtx *);
|
||||
extern unsigned int arm_sync_loop_insns (rtx , rtx *);
|
||||
extern int arm_attr_length_push_multi(rtx, rtx);
|
||||
extern int arm_attr_length_pop_multi(rtx *, bool, bool);
|
||||
extern void arm_expand_compare_and_swap (rtx op[]);
|
||||
extern void arm_split_compare_and_swap (rtx op[]);
|
||||
extern void arm_split_atomic_op (enum rtx_code, rtx, rtx, rtx, rtx, rtx, rtx);
|
||||
|
|
|
|||
|
|
@ -27793,7 +27793,7 @@ arm_preferred_rename_class (reg_class_t rclass)
|
|||
return NO_REGS;
|
||||
}
|
||||
|
||||
/* Compute the atrribute "length" of insn "*push_multi".
|
||||
/* Compute the attribute "length" of insn "*push_multi".
|
||||
So this function MUST be kept in sync with that insn pattern. */
|
||||
int
|
||||
arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
|
||||
|
|
@ -27810,6 +27810,11 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
|
|||
|
||||
/* Thumb2 mode. */
|
||||
regno = REGNO (first_op);
|
||||
/* For PUSH/STM under Thumb2 mode, we can use 16-bit encodings if the register
|
||||
list is 8-bit. Normally this means all registers in the list must be
|
||||
LO_REGS, that is (R0 -R7). If any HI_REGS used, then we must use 32-bit
|
||||
encodings. There is one exception for PUSH that LR in HI_REGS can be used
|
||||
with 16-bit encoding. */
|
||||
hi_reg = (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM);
|
||||
for (i = 1; i < num_saves && !hi_reg; i++)
|
||||
{
|
||||
|
|
@ -27822,6 +27827,56 @@ arm_attr_length_push_multi(rtx parallel_op, rtx first_op)
|
|||
return 4;
|
||||
}
|
||||
|
||||
/* Compute the attribute "length" of insn. Currently, this function is used
|
||||
for "*load_multiple_with_writeback", "*pop_multiple_with_return" and
|
||||
"*pop_multiple_with_writeback_and_return". OPERANDS is the toplevel PARALLEL
|
||||
rtx, RETURN_PC is true if OPERANDS contains return insn. WRITE_BACK_P is
|
||||
true if OPERANDS contains insn which explicit updates base register. */
|
||||
|
||||
int
|
||||
arm_attr_length_pop_multi (rtx *operands, bool return_pc, bool write_back_p)
|
||||
{
|
||||
/* ARM mode. */
|
||||
if (TARGET_ARM)
|
||||
return 4;
|
||||
/* Thumb1 mode. */
|
||||
if (TARGET_THUMB1)
|
||||
return 2;
|
||||
|
||||
rtx parallel_op = operands[0];
|
||||
/* Initialize to elements number of PARALLEL. */
|
||||
unsigned indx = XVECLEN (parallel_op, 0) - 1;
|
||||
/* Initialize the value to base register. */
|
||||
unsigned regno = REGNO (operands[1]);
|
||||
/* Skip return and write back pattern.
|
||||
We only need register pop pattern for later analysis. */
|
||||
unsigned first_indx = 0;
|
||||
first_indx += return_pc ? 1 : 0;
|
||||
first_indx += write_back_p ? 1 : 0;
|
||||
|
||||
/* A pop operation can be done through LDM or POP. If the base register is SP
|
||||
and if it's with write back, then a LDM will be alias of POP. */
|
||||
bool pop_p = (regno == SP_REGNUM && write_back_p);
|
||||
bool ldm_p = !pop_p;
|
||||
|
||||
/* Check base register for LDM. */
|
||||
if (ldm_p && REGNO_REG_CLASS (regno) == HI_REGS)
|
||||
return 4;
|
||||
|
||||
/* Check each register in the list. */
|
||||
for (; indx >= first_indx; indx--)
|
||||
{
|
||||
regno = REGNO (XEXP (XVECEXP (parallel_op, 0, indx), 0));
|
||||
/* For POP, PC in HI_REGS can be used with 16-bit encoding. See similar
|
||||
comment in arm_attr_length_push_multi. */
|
||||
if (REGNO_REG_CLASS (regno) == HI_REGS
|
||||
&& (regno != PC_REGNUM || ldm_p))
|
||||
return 4;
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Compute the number of instructions emitted by output_move_double. */
|
||||
int
|
||||
arm_count_output_move_double_insns (rtx *operands)
|
||||
|
|
|
|||
|
|
@ -10562,7 +10562,11 @@
|
|||
}
|
||||
"
|
||||
[(set_attr "type" "load4")
|
||||
(set_attr "predicable" "yes")]
|
||||
(set_attr "predicable" "yes")
|
||||
(set (attr "length")
|
||||
(symbol_ref "arm_attr_length_pop_multi (operands,
|
||||
/*return_pc=*/false,
|
||||
/*write_back_p=*/true)"))]
|
||||
)
|
||||
|
||||
;; Pop with return (as used in epilogue RTL)
|
||||
|
|
@ -10591,7 +10595,10 @@
|
|||
}
|
||||
"
|
||||
[(set_attr "type" "load4")
|
||||
(set_attr "predicable" "yes")]
|
||||
(set_attr "predicable" "yes")
|
||||
(set (attr "length")
|
||||
(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
|
||||
/*write_back_p=*/true)"))]
|
||||
)
|
||||
|
||||
(define_insn "*pop_multiple_with_return"
|
||||
|
|
@ -10611,7 +10618,10 @@
|
|||
}
|
||||
"
|
||||
[(set_attr "type" "load4")
|
||||
(set_attr "predicable" "yes")]
|
||||
(set_attr "predicable" "yes")
|
||||
(set (attr "length")
|
||||
(symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true,
|
||||
/*write_back_p=*/false)"))]
|
||||
)
|
||||
|
||||
;; Load into PC and return
|
||||
|
|
|
|||
Loading…
Reference in New Issue