diff options
author | jiez <jiez@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-03 16:49:05 +0000 |
---|---|---|
committer | jiez <jiez@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-03 16:49:05 +0000 |
commit | ba6c018a1d83d48597d122c1efd9d7b02feec88c (patch) | |
tree | 7ee72735e0f65edea09f4794793a672429c7d6d6 | |
parent | 3cc80a304b23f16bc34c7479942d2865b01d61a6 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 51 | ||||
-rw-r--r-- | gcc/config/arm/neon.md | 5 |
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" "") |