summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjiez <jiez@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-03 16:49:05 +0000
committerjiez <jiez@138bc75d-0d04-0410-961f-82ee72b054a4>2010-07-03 16:49:05 +0000
commitba6c018a1d83d48597d122c1efd9d7b02feec88c (patch)
tree7ee72735e0f65edea09f4794793a672429c7d6d6
parent3cc80a304b23f16bc34c7479942d2865b01d61a6 (diff)
downloadgcc-ba6c018a1d83d48597d122c1efd9d7b02feec88c.tar.gz
* config/arm/arm.c (arm_attr_length_move_neon): New.
* config/arm/arm-protos.h (arm_attr_length_move_neon): Declare. * config/arm/neon.md (define_mode_attr V_slen): Remove. (neon_mov<mode> for VSTRUCT): Use arm_attr_length_move_neon to compute length attribute. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161776 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c51
-rw-r--r--gcc/config/arm/neon.md5
4 files changed, 61 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8aceaf78326..f20eccda7b4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,13 @@
2010-07-03 Jie Zhang <jie@codesourcery.com>
+ * config/arm/arm.c (arm_attr_length_move_neon): New.
+ * config/arm/arm-protos.h (arm_attr_length_move_neon): Declare.
+ * config/arm/neon.md (define_mode_attr V_slen): Remove.
+ (neon_mov<mode> for VSTRUCT): Use arm_attr_length_move_neon
+ to compute length attribute.
+
+2010-07-03 Jie Zhang <jie@codesourcery.com>
+
* config/arm/vfp.md (*push_multi_vfp): Use vfp_register_operand
as predicate for operand 1 and remove its constraint.
* config/arm/predicates.md (vfp_register_operand): New.
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 40d0f93a593..11e2e288ce9 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -131,6 +131,7 @@ extern const char *output_move_double (rtx *);
extern const char *output_move_quad (rtx *);
extern const char *output_move_vfp (rtx *operands);
extern const char *output_move_neon (rtx *operands);
+extern int arm_attr_length_move_neon (rtx);
extern const char *output_add_immediate (rtx *);
extern const char *arithmetic_instr (rtx, int);
extern void output_ascii_pseudo_op (FILE *, const unsigned char *, int);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index f59c1fcd3f9..85d1e8cb82b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -12859,6 +12859,57 @@ output_move_neon (rtx *operands)
return "";
}
+/* Compute and return the length of neon_mov<mode>, where <mode> is
+ one of VSTRUCT modes: EI, OI, CI or XI. */
+int
+arm_attr_length_move_neon (rtx insn)
+{
+ rtx reg, mem, addr;
+ int regno, load;
+ enum machine_mode mode;
+
+ extract_insn_cached (insn);
+
+ if (REG_P (recog_data.operand[0]) && REG_P (recog_data.operand[1]))
+ {
+ mode = GET_MODE (recog_data.operand[0]);
+ switch (mode)
+ {
+ case EImode:
+ case OImode:
+ return 8;
+ case CImode:
+ return 12;
+ case XImode:
+ return 16;
+ default:
+ gcc_unreachable ();
+ }
+ }
+
+ load = REG_P (recog_data.operand[0]);
+ reg = recog_data.operand[!load];
+ mem = recog_data.operand[load];
+
+ gcc_assert (MEM_P (mem));
+
+ mode = GET_MODE (reg);
+ regno = REGNO (reg);
+ addr = XEXP (mem, 0);
+
+ /* Strip off const from addresses like (const (plus (...))). */
+ if (GET_CODE (addr) == CONST && GET_CODE (XEXP (addr, 0)) == PLUS)
+ addr = XEXP (addr, 0);
+
+ if (GET_CODE (addr) == LABEL_REF || GET_CODE (addr) == PLUS)
+ {
+ int insns = HARD_REGNO_NREGS (REGNO (reg), mode) / 2;
+ return insns * 4;
+ }
+ else
+ return 4;
+}
+
/* Output an ADD r, s, #n where n may be too big for one instruction.
If adding zero to one register, output nothing. */
const char *
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index 08b6463d782..15f347c9607 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -166,9 +166,6 @@
;; Opaque structure types wider than TImode.
(define_mode_iterator VSTRUCT [EI OI CI XI])
-;; Number of instructions needed to load/store struct elements. FIXME!
-(define_mode_attr V_slen [(EI "2") (OI "2") (CI "3") (XI "4")])
-
;; Opaque structure types used in table lookups (except vtbl1/vtbx1).
(define_mode_iterator VTAB [TI EI OI])
@@ -576,7 +573,7 @@
}
}
[(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
- (set_attr "length" "<V_slen>,<V_slen>,<V_slen>")])
+ (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
(define_split
[(set (match_operand:EI 0 "s_register_operand" "")