From patchwork Wed Jun 30 05:05:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Zhang X-Patchwork-Id: 57376 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E6CF4B6EED for ; Wed, 30 Jun 2010 15:05:30 +1000 (EST) Received: (qmail 7043 invoked by alias); 30 Jun 2010 05:05:28 -0000 Received: (qmail 6838 invoked by uid 22791); 30 Jun 2010 05:05:27 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 30 Jun 2010 05:05:20 +0000 Received: (qmail 31908 invoked from network); 30 Jun 2010 05:05:17 -0000 Received: from unknown (HELO ?192.168.0.124?) (jie@127.0.0.2) by mail.codesourcery.com with ESMTPA; 30 Jun 2010 05:05:17 -0000 Message-ID: <4C2AD08A.2040104@codesourcery.com> Date: Wed, 30 Jun 2010 13:05:14 +0800 From: Jie Zhang User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.4) Gecko/20100608 Lightning/1.0b2 Thunderbird/3.1 MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org Subject: [ARM] Fix length attribute for neon_mov of VSTRUCT X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org I just found that the length attribute of neon_mov pattern for VSTRUCT is not calculated correctly. This patch should fix it. Testing on arm-none-eabi for NEON has no regressions. Is it OK to commit? Regards, --- Jie CodeSourcery * 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 for VSTRUCT): Use arm_attr_length_move_neon to compute length attribute. Index: config/arm/arm.c =================================================================== --- config/arm/arm.c (revision 161525) +++ config/arm/arm.c (working copy) @@ -12698,6 +12698,57 @@ output_move_neon (rtx *operands) return ""; } +/* Compute and return the length of neon_mov, where 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 * Index: config/arm/arm-protos.h =================================================================== --- config/arm/arm-protos.h (revision 161525) +++ config/arm/arm-protos.h (working copy) @@ -131,6 +131,7 @@ extern const char *output_move_double (r 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); Index: config/arm/neon.md =================================================================== --- config/arm/neon.md (revision 161525) +++ config/arm/neon.md (working copy) @@ -185,9 +185,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]) @@ -587,7 +584,7 @@ } } [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2") - (set_attr "length" ",,")]) + (set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))]) (define_split [(set (match_operand:EI 0 "s_register_operand" "")