summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorcarrot <carrot@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-08 09:17:42 +0000
committercarrot <carrot@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-08 09:17:42 +0000
commit08508cbfcb1bcb6f8322f99ea812b7493bb4a4d8 (patch)
treebe5240f3b06afa52622ec493f89a65af400cff15 /gcc
parentfa8d6f0f40e31fb74fe71b29d9ea30640566fb2b (diff)
downloadgcc-08508cbfcb1bcb6f8322f99ea812b7493bb4a4d8.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172169 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c26
-rw-r--r--gcc/config/arm/arm.md24
4 files changed, 38 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 62df9162caa..3162967c67b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index f037a456a06..c8cadf34d99 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -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);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 533ad910c8f..44c8e2fd9a2 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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"
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 3a5bc42a2a8..e54acc72ea6 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -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"