arm-protos.h (arm_attr_length_push_multi): New prototype.
* config/arm/arm-protos.h (arm_attr_length_push_multi): New prototype. * config/arm/arm.c (arm_attr_length_push_multi): New function. * config/arm/arm.md (*push_multi): Change the length computation to call a C function. From-SVN: r172169
This commit is contained in:
parent
07c5f94e82
commit
0c27e2d89b
@ -1,3 +1,11 @@
|
||||
2011-04-08 Wei Guozhi <carrot@google.com>
|
||||
|
||||
PR target/47855
|
||||
* config/arm/arm-protos.h (arm_attr_length_push_multi): New prototype.
|
||||
* config/arm/arm.c (arm_attr_length_push_multi): New function.
|
||||
* config/arm/arm.md (*push_multi): Change the length computation to
|
||||
call a C function.
|
||||
|
||||
2011-04-08 Anatoly Sokolov <aesok@post.ru>
|
||||
|
||||
* doc/tm.texi.in (ASM_OUTPUT_BSS): Remove documentation.
|
||||
|
@ -152,6 +152,7 @@ extern void arm_expand_sync (enum machine_mode, struct arm_sync_generator *,
|
||||
extern const char *arm_output_memory_barrier (rtx *);
|
||||
extern const char *arm_output_sync_insn (rtx, rtx *);
|
||||
extern unsigned int arm_sync_loop_insns (rtx , rtx *);
|
||||
extern int arm_attr_length_push_multi(rtx, rtx);
|
||||
|
||||
#if defined TREE_CODE
|
||||
extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree);
|
||||
|
@ -23696,4 +23696,30 @@ arm_preferred_rename_class (reg_class_t rclass)
|
||||
return NO_REGS;
|
||||
}
|
||||
|
||||
/* Compute the atrribute "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)
|
||||
{
|
||||
int i, regno, hi_reg;
|
||||
int num_saves = XVECLEN (parallel_op, 0);
|
||||
|
||||
/* ARM mode. */
|
||||
if (TARGET_ARM)
|
||||
return 4;
|
||||
|
||||
/* Thumb2 mode. */
|
||||
regno = REGNO (first_op);
|
||||
hi_reg = (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM);
|
||||
for (i = 1; i < num_saves && !hi_reg; i++)
|
||||
{
|
||||
regno = REGNO (XEXP (XVECEXP (parallel_op, 0, i), 0));
|
||||
hi_reg |= (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM);
|
||||
}
|
||||
|
||||
if (!hi_reg)
|
||||
return 2;
|
||||
return 4;
|
||||
}
|
||||
|
||||
#include "gt-arm.h"
|
||||
|
@ -10249,6 +10249,8 @@
|
||||
;; Push multiple registers to the stack. Registers are in parallel (use ...)
|
||||
;; expressions. For simplicity, the first register is also in the unspec
|
||||
;; part.
|
||||
;; To avoid the usage of GNU extension, the length attribute is computed
|
||||
;; in a C function arm_attr_length_push_multi.
|
||||
(define_insn "*push_multi"
|
||||
[(match_parallel 2 "multi_register_push"
|
||||
[(set (match_operand:BLK 0 "memory_operand" "=m")
|
||||
@ -10290,27 +10292,7 @@
|
||||
}"
|
||||
[(set_attr "type" "store4")
|
||||
(set (attr "length")
|
||||
(if_then_else
|
||||
(and (ne (symbol_ref "TARGET_THUMB2") (const_int 0))
|
||||
(ne (symbol_ref "{
|
||||
/* Check if there are any high register (except lr)
|
||||
references in the list. KEEP the following iteration
|
||||
in sync with the template above. */
|
||||
int i, regno, hi_reg;
|
||||
int num_saves = XVECLEN (operands[2], 0);
|
||||
regno = REGNO (operands[1]);
|
||||
hi_reg = (REGNO_REG_CLASS (regno) == HI_REGS)
|
||||
&& (regno != LR_REGNUM);
|
||||
for (i = 1; i < num_saves && !hi_reg; i++)
|
||||
{
|
||||
regno = REGNO (XEXP (XVECEXP (operands[2], 0, i), 0));
|
||||
hi_reg |= (REGNO_REG_CLASS (regno) == HI_REGS)
|
||||
&& (regno != LR_REGNUM);
|
||||
}
|
||||
!hi_reg; }")
|
||||
(const_int 0)))
|
||||
(const_int 2)
|
||||
(const_int 4)))]
|
||||
(symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))]
|
||||
)
|
||||
|
||||
(define_insn "stack_tie"
|
||||
|
Loading…
Reference in New Issue
Block a user