From patchwork Wed Mar 14 22:54:08 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 886069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-474748-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.vnet.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="f9fMrRPN"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 401n9C3k3Yz9sSN for ; Thu, 15 Mar 2018 09:54:39 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:mime-version:content-type:message-id; q=dns; s= default; b=wjJVML9ffXalmZH6/7C5bh6sfn0fr103X1slqTace2m2W+hOMdqTR isEhuc9DONCVdgHLEFOD0F1CNfSlmgIWuBwAhbpDdHinvu48DF3BGDxws7PVULmX tCXK2I9FRrz2JvniWfupSeHKLrbR8vidsEhew6AP194ZOuqrZ5tH2Y= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:mime-version:content-type:message-id; s= default; bh=/81qFYd/8xJFfe+jhTsJEBmn/24=; b=f9fMrRPN+u/2u33lUe9z T+YCXufqZixzK0Ik0oaXVdcL2By0k8RkmVlDMxZoxUqbW3ergAS+YUdZ+bGGEzW3 TNGd1OZgKhj67gdXd7dyzudgNp5Qu5ipPKCphFgMT1DRUkX9qkj6BN8cFLJv6EBm vZpwnOMI5jxtjFRqGieXbH8= Received: (qmail 34070 invoked by alias); 14 Mar 2018 22:54:31 -0000 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 Received: (qmail 34045 invoked by uid 89); 14 Mar 2018 22:54:30 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-9.6 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, KAM_LAZY_DOMAIN_SECURITY, KAM_NUMSUBJECT, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy= X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 14 Mar 2018 22:54:25 +0000 Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w2EMsNcd101590 for ; Wed, 14 Mar 2018 18:54:23 -0400 Received: from e33.co.us.ibm.com (e33.co.us.ibm.com [32.97.110.151]) by mx0b-001b2d01.pphosted.com with ESMTP id 2gq9mff1sa-1 (version=TLSv1.2 cipher=AES256-SHA256 bits=256 verify=NOT) for ; Wed, 14 Mar 2018 18:54:15 -0400 Received: from localhost by e33.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 14 Mar 2018 16:54:14 -0600 Received: from b03cxnp07029.gho.boulder.ibm.com (9.17.130.16) by e33.co.us.ibm.com (192.168.1.133) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Wed, 14 Mar 2018 16:54:10 -0600 Received: from b03ledav004.gho.boulder.ibm.com (b03ledav004.gho.boulder.ibm.com [9.17.130.235]) by b03cxnp07029.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w2EMsAfY11075904; Wed, 14 Mar 2018 15:54:10 -0700 Received: from b03ledav004.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2219378038; Wed, 14 Mar 2018 16:54:10 -0600 (MDT) Received: from ibm-tiger.the-meissners.org (unknown [9.32.77.111]) by b03ledav004.gho.boulder.ibm.com (Postfix) with ESMTP id DF0AB7803F; Wed, 14 Mar 2018 16:54:09 -0600 (MDT) Received: by ibm-tiger.the-meissners.org (Postfix, from userid 500) id 242824A183; Wed, 14 Mar 2018 18:54:08 -0400 (EDT) Date: Wed, 14 Mar 2018 18:54:08 -0400 From: Michael Meissner To: GCC Patches , Segher Boessenkool , David Edelsohn , Bill Schmidt Subject: [RFC Patch], PowerPC memory support pre-gcc9, patch #1 Mail-Followup-To: Michael Meissner , GCC Patches , Segher Boessenkool , David Edelsohn , Bill Schmidt MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-12-10) X-TM-AS-GCONF: 00 x-cbid: 18031422-0008-0000-0000-000009758BD5 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00008675; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000254; SDB=6.01003114; UDB=6.00510477; IPR=6.00782444; MB=3.00020038; MTD=3.00000008; XFM=3.00000015; UTC=2018-03-14 22:54:12 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18031422-0009-0000-0000-00004665412B Message-Id: <20180314225408.GA3365@ibm-tiger.the-meissners.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-03-14_12:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1803140243 X-IsSubscribed: yes I am starting to work on cleaning up the memory addressing support in the GCC 9 time frame. At the moment, I am working on upgrading the infrastructure to allow in the future to prevent splitting memory on 64-bit LE systems too early, rework the fusion support, and provide a pathway for future processor support. The first patch in the series moves most of the reg_addr structure from rs6000.c to rs6000-protos.h, so that in the next patch, we can start splitting some of the address code to other files. In addition to just moving the reg_addr stuff to be global, there are a few minor changes in this patch: 1) I was playing with making r12 be fixed with a new option (not in this set of patches), and I noticed it wasn't reflected in the -mdebug=reg debug dump, due to the debug dump being done before the conditional registers are setup. I made the debug dump set conditional registers. 2) I renamed some of the mode_suppports helper functions to be more consistent the instruction documentation (i.e. there are helper functions for normal d-form register+offset instructions, ds-form where the bottom 2 bits must be 0 and dq-form where the bottom 4 bits must be 0). I added optional arguments to the helper functions, so that secondary reload in the future can narrow down whether a particular register class has particular support. 3) I did a simplification in setting up the reg_addr address masks, where instead of 3 states which two set INDEXED and the other sets MULTIPLE register, it only has 1 place where it sets INDEXED. I have tested this with full bootstrap and make check on a little endian power8 with no regressions. Since we are in stage4 currently, I am not asking for permission to check it in, but if you have any comments on how you would like to see the eventual patches when stage1 opens up, let me know. It would be simpler to make the changes now, rather than when the number of patches have accumulated. The second patch that I will submit shortly will move the rs6000_output_move_128bit function to a new file (rs6000-output.c). The third patch that I will submit will be to move the movdi patterns to a separate function (rs6000_output_move_64bit) also in rs6000-output.c, so that in the future we can use C++ code to check on constraints, etc. I haven't written it yet, but the fourth patch is likely to similarly move DF and DD output templates to use the same function. One thing I plan to do for DF/DD is to structure the comments about the alternatives so that it is more readable, much like I've done for movdi, etc. I likely will remove the undocumented toc-fusion all together, and eventually rework the p8/p9 fusion support. 2018-03-14 Michael Meissner * config/rs6000/rs6000-protos.h (regno_or_subregno): Add declaration. (enum rs6000_reg_type): Move the basic reg_addr support from rs6000.c to rs6000-protos.h, except for the parts that store insn_code's for the register allocator to allow future patches to move parts of rs6000.c to other files. Change the bool flags to bit-fields. Add a flag to indicate the mode/reload register class uses DS-form (14-bit offset) addresses. (reg_class_to_reg_type): Likwise. (IS_STD_REG_TYPE): Likwise. (IS_FP_VECT_REG_TYPE): Likwise. (enum rs6000_reload_reg_type): Likwise. (struct rs6000_reg_addr): Likwise. (reg_addr): Likwise. (RELOAD_REG_*): Likewise. (mode_supports_pre_incdec_p): Move the mode supports helper functions to rs6000-protos.h. Add an optional argument to use a particular reload register class instead of RELOAD_REG_ANY. Rename mode_supports_vsx_dform_quad -> mode_supports_dq_form. Add mode_supports_ds_form for DS-form addresses. Add mode_supports_x_form for X-form (indexed) addresses. (mode_supports_pre_modify_p): Likewise. (mode_supports_d_form): Likewise. (mode_supports_ds_form): Likewise. (mode_supports_dq_form): Likewise. (mode_supports_x_form): Likewise. * config/rs6000/rs6000.c (enum rs6000_reg_type): Move basic reg_addr support to rs6000-protos.h. (IS_STD_REG_TYPE): Likewise. (IS_FP_VECT_REG_TYPE): Likewise. (enum rs6000_reload_reg_typ): Likewise. (reg_class_to_reg_type): Make global. (addr_mask_type): Move basic reg_addr support to rs6000-protos.h. (reg_addr): Make global. (RELOAD_REG_VALID): Move basic reg_addr support to rs6000-protos.h. (RELOAD_REG_*): Likewise. (struct rs6000_insn_functions): New structure that includes the parts of the old reg_addr structure that did not move to rs6000-protos.h because it contains insn codes. (rs6000_insns): Likewise. (mode_supports_pre_modify_p): Move to rs6000-protos.h. (mode_supports_pre_modify_p): Likewise. (mode_supports_vmx_dform): Likewise. (mode_supports_vsx_dform_quad): Likewise. (rs6000_conditional_register_usage): Add forward declaration. (rs6000_debug_addr_mask): Print whether the mode/reload register class uses DS-form memory instructions. (rs6000_debug_print_mode): Call rs6000_conditional_register_usage in order to print the status of the registers properly. Use rs6000_insns instead of reg_addr for the insn code elements. (rs6000_setup_reg_addr_masks): Simplify the code to set whether a mode uses multiple registers or provides indexed mode. Don't allow update addresses on modes that only support indexed mode. Note that DI/SI in 64-bit use DS-form addresses as well as ISA 3.0 scalar altivec offset references. (rs6000_init_hard_regno_mode_ok): Clear rs6000_insns. Change to use rs6000_insns instead of reg_addr for saving the insn codes for secondary reload and fusion support. (regno_or_subregno): Make global. (quad_address_p): Rename mode_supports_vsx_dform_quad to mode_supports_dq_form. (reg_offset_addressing_ok_p): Likewise. (offsettable_ok_by_alignment): Likewise. (rs6000_legitimate_offset_address_p): Likewise. (legitimate_lo_sum_address_p): Likewise. (rs6000_legitimize_address): Likewise. (rs6000_legitimize_reload_address): Likewise. (rs6000_legitimate_address_p): Likewise. (rs6000_secondary_reload_direct_move): Use rs6000_insns to pick up secondary reload and fusion insn codes instead of reg_addr. (rs6000_secondary_reload): Likewise. (rs6000_secondary_reload_inner): Rename mode_supports_vsx_dform_quad to mode_supports_dq_form. Use mode_supports_d_form with RELOAD_REG_VMX instead of calling mode_supports_vmx_dform. (rs6000_preferred_reload_class): Likewise. (rs6000_secondary_reload_class): Likewise. (rs6000_output_move_128bit): Likewise. Index: gcc/config/rs6000/rs6000-protos.h =================================================================== --- gcc/config/rs6000/rs6000-protos.h (revision 258530) +++ gcc/config/rs6000/rs6000-protos.h (working copy) @@ -61,6 +61,7 @@ extern void paired_expand_vector_init (r extern void rs6000_expand_vector_set (rtx, rtx, int); extern void rs6000_expand_vector_extract (rtx, rtx, rtx); extern void rs6000_split_vec_extract_var (rtx, rtx, rtx, rtx, rtx); +extern int regno_or_subregno (rtx); extern rtx rs6000_adjust_vec_address (rtx, rtx, rtx, rtx, machine_mode); extern void rs6000_split_v4si_init (rtx []); extern void altivec_expand_vec_perm_le (rtx op[4]); @@ -258,4 +259,116 @@ extern bool rs6000_quadword_masked_addre extern rtx rs6000_gen_lvx (enum machine_mode, rtx, rtx); extern rtx rs6000_gen_stvx (enum machine_mode, rtx, rtx); + +/* Simplfy register classes into simpler classifications. We assume + GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range + check for standard register classes (gpr/floating/altivec/vsx) and + floating/vector classes (float/altivec/vsx). */ + +enum rs6000_reg_type { + NO_REG_TYPE, + PSEUDO_REG_TYPE, + GPR_REG_TYPE, + VSX_REG_TYPE, + ALTIVEC_REG_TYPE, + FPR_REG_TYPE, + SPR_REG_TYPE, + CR_REG_TYPE +}; + +/* Map register class to register type. */ +extern enum rs6000_reg_type reg_class_to_reg_type[]; + +/* First/last register type for the 'normal' register types (i.e. general + purpose, floating point, altivec, and VSX registers). */ +#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE) + +#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, FPR_REG_TYPE) + +/* Register classes we care about in secondary reload or go if legitimate + address. We only need to worry about GPR, FPR, and Altivec registers here, + along an ANY field that is the OR of the 3 register classes. */ + +enum rs6000_reload_reg_type { + RELOAD_REG_GPR, /* General purpose registers. */ + RELOAD_REG_FPR, /* Traditional floating point regs. */ + RELOAD_REG_VMX, /* Altivec (VMX) registers. */ + RELOAD_REG_ANY, /* OR of GPR, FPR, Altivec masks. */ + N_RELOAD_REG +}; + +/* Mask bits for each register class, indexed per mode. Historically the + compiler has been more restrictive which types can do PRE_MODIFY instead of + PRE_INC and PRE_DEC, so keep track of sepaate bits for these two. */ +typedef unsigned short addr_mask_type; + +#define RELOAD_REG_VALID 0x001 /* Mode valid in register.. */ +#define RELOAD_REG_MULTIPLE 0x002 /* Mode takes multiple registers. */ +#define RELOAD_REG_INDEXED 0x004 /* Reg+reg addressing. */ +#define RELOAD_REG_OFFSET 0x008 /* Reg+offset addressing. */ +#define RELOAD_REG_PRE_INCDEC 0x010 /* PRE_INC/PRE_DEC valid. */ +#define RELOAD_REG_PRE_MODIFY 0x020 /* PRE_MODIFY valid. */ +#define RELOAD_REG_AND_M16 0x040 /* AND -16 addressing. */ +#define RELOAD_REG_QUAD_OFFSET 0x080 /* Bottom 4 bits must be 0. */ +#define RELOAD_REG_DS_OFFSET 0x100 /* Bottom 2 bits must be 0. */ + +/* Register type masks based on the type, of valid addressing modes. */ +struct rs6000_reg_addr { + addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks. */ + unsigned char scalar_in_vmx_p : 1; /* Scalar can go in VMX. */ + unsigned char fused_toc : 1; /* Mode supports TOC fusion. */ +}; + +extern struct rs6000_reg_addr reg_addr[]; + +/* Helper function to say whether a mode supports PRE_INC or PRE_DEC. */ +static inline bool +mode_supports_pre_incdec_p (machine_mode mode, + enum rs6000_reload_reg_type rt = RELOAD_REG_ANY) +{ + return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_PRE_INCDEC) != 0); +} + +/* Helper function to say whether a mode supports PRE_MODIFY. */ +static inline bool +mode_supports_pre_modify_p (machine_mode mode, + enum rs6000_reload_reg_type rt = RELOAD_REG_ANY) +{ + return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_PRE_MODIFY) != 0); +} + +/* Return true if we have offset addressing (d-form). The offset may be 12 bit + (dq-form), 14 bits (ds-form), or 16 (d-form) bits. */ +static inline bool +mode_supports_d_form (machine_mode mode, + enum rs6000_reload_reg_type rt = RELOAD_REG_ANY) +{ + return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_OFFSET) != 0); +} + +/* Return true if we have DS-form addressing in any registers where the bottom + 2 bits must be 0 (i.e. LD, ST, etc.). */ +static inline bool +mode_supports_ds_form (machine_mode mode, + enum rs6000_reload_reg_type rt = RELOAD_REG_ANY) +{ + return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_DS_OFFSET) != 0); +} + +/* Return true if we have DQ-form addressing. The bottom 4 bits must be 0. */ +static inline bool +mode_supports_dq_form (machine_mode mode, + enum rs6000_reload_reg_type rt = RELOAD_REG_ANY) +{ + return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_QUAD_OFFSET) != 0); +} + +/* Return true if we have indexed addressing (x-form). */ +static inline bool +mode_supports_x_form (machine_mode mode, + enum rs6000_reload_reg_type rt = RELOAD_REG_ANY) +{ + return ((reg_addr[mode].addr_mask[rt] & RELOAD_REG_INDEXED) != 0); +} + #endif /* rs6000-protos.h */ Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 258531) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -443,43 +443,8 @@ bool cpu_builtin_p; don't link in rs6000-c.c, so we can't call it directly. */ void (*rs6000_target_modify_macros_ptr) (bool, HOST_WIDE_INT, HOST_WIDE_INT); -/* Simplfy register classes into simpler classifications. We assume - GPR_REG_TYPE - FPR_REG_TYPE are ordered so that we can use a simple range - check for standard register classes (gpr/floating/altivec/vsx) and - floating/vector classes (float/altivec/vsx). */ - -enum rs6000_reg_type { - NO_REG_TYPE, - PSEUDO_REG_TYPE, - GPR_REG_TYPE, - VSX_REG_TYPE, - ALTIVEC_REG_TYPE, - FPR_REG_TYPE, - SPR_REG_TYPE, - CR_REG_TYPE -}; - /* Map register class to register type. */ -static enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES]; - -/* First/last register type for the 'normal' register types (i.e. general - purpose, floating point, altivec, and VSX registers). */ -#define IS_STD_REG_TYPE(RTYPE) IN_RANGE(RTYPE, GPR_REG_TYPE, FPR_REG_TYPE) - -#define IS_FP_VECT_REG_TYPE(RTYPE) IN_RANGE(RTYPE, VSX_REG_TYPE, FPR_REG_TYPE) - - -/* Register classes we care about in secondary reload or go if legitimate - address. We only need to worry about GPR, FPR, and Altivec registers here, - along an ANY field that is the OR of the 3 register classes. */ - -enum rs6000_reload_reg_type { - RELOAD_REG_GPR, /* General purpose registers. */ - RELOAD_REG_FPR, /* Traditional floating point regs. */ - RELOAD_REG_VMX, /* Altivec (VMX) registers. */ - RELOAD_REG_ANY, /* OR of GPR, FPR, Altivec masks. */ - N_RELOAD_REG -}; +enum rs6000_reg_type reg_class_to_reg_type[N_REG_CLASSES]; /* For setting up register classes, loop through the 3 register classes mapping into real registers, and skip the ANY class, which is just an OR of the @@ -500,22 +465,12 @@ static const struct reload_reg_map_type { "Any", -1 }, /* RELOAD_REG_ANY. */ }; -/* Mask bits for each register class, indexed per mode. Historically the - compiler has been more restrictive which types can do PRE_MODIFY instead of - PRE_INC and PRE_DEC, so keep track of sepaate bits for these two. */ -typedef unsigned char addr_mask_type; - -#define RELOAD_REG_VALID 0x01 /* Mode valid in register.. */ -#define RELOAD_REG_MULTIPLE 0x02 /* Mode takes multiple registers. */ -#define RELOAD_REG_INDEXED 0x04 /* Reg+reg addressing. */ -#define RELOAD_REG_OFFSET 0x08 /* Reg+offset addressing. */ -#define RELOAD_REG_PRE_INCDEC 0x10 /* PRE_INC/PRE_DEC valid. */ -#define RELOAD_REG_PRE_MODIFY 0x20 /* PRE_MODIFY valid. */ -#define RELOAD_REG_AND_M16 0x40 /* AND -16 addressing. */ -#define RELOAD_REG_QUAD_OFFSET 0x80 /* quad offset is limited. */ - /* Register type masks based on the type, of valid addressing modes. */ -struct rs6000_reg_addr { +struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES]; + +/* Insns to use for loading/storing various register types, and for creating + various combined fusion instructions. */ +struct rs6000_insn_functions { enum insn_code reload_load; /* INSN to reload for loading. */ enum insn_code reload_store; /* INSN to reload for storing. */ enum insn_code reload_fpr_gpr; /* INSN to move from FPR to GPR. */ @@ -530,28 +485,9 @@ struct rs6000_reg_addr { or stores for each reg. class. */ enum insn_code fusion_addis_ld[(int)N_RELOAD_REG]; enum insn_code fusion_addis_st[(int)N_RELOAD_REG]; - addr_mask_type addr_mask[(int)N_RELOAD_REG]; /* Valid address masks. */ - bool scalar_in_vmx_p; /* Scalar value can go in VMX. */ - bool fused_toc; /* Mode supports TOC fusion. */ }; -static struct rs6000_reg_addr reg_addr[NUM_MACHINE_MODES]; - -/* Helper function to say whether a mode supports PRE_INC or PRE_DEC. */ -static inline bool -mode_supports_pre_incdec_p (machine_mode mode) -{ - return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_INCDEC) - != 0); -} - -/* Helper function to say whether a mode supports PRE_MODIFY. */ -static inline bool -mode_supports_pre_modify_p (machine_mode mode) -{ - return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_PRE_MODIFY) - != 0); -} +static struct rs6000_insn_functions rs6000_insns[NUM_MACHINE_MODES]; /* Given that there exists at least one variable that is set (produced) by OUT_INSN and read (consumed) by IN_INSN, return true iff @@ -638,23 +574,6 @@ rs6000_store_data_bypass_p (rtx_insn *ou return store_data_bypass_p (out_insn, in_insn); } -/* Return true if we have D-form addressing in altivec registers. */ -static inline bool -mode_supports_vmx_dform (machine_mode mode) -{ - return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 0); -} - -/* Return true if we have D-form addressing in VSX registers. This addressing - is more limited than normal d-form addressing in that the offset must be - aligned on a 16-byte boundary. */ -static inline bool -mode_supports_vsx_dform_quad (machine_mode mode) -{ - return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET) - != 0); -} - /* Processor costs (relative to an add) */ @@ -1395,6 +1314,7 @@ static bool rs6000_debug_can_change_mode reg_class_t); static bool rs6000_save_toc_in_prologue_p (void); static rtx rs6000_internal_arg_pointer (void); +static void rs6000_conditional_register_usage (void); rtx (*rs6000_legitimize_reload_address_ptr) (rtx, machine_mode, int, int, int, int *) @@ -2224,6 +2144,10 @@ rs6000_debug_reg_print (int first_regno, { int r, m; + /* Insure the conditional registers are up to date when printing the debug + information. */ + rs6000_conditional_register_usage (); + for (r = first_regno; r <= last_regno; ++r) { const char *comma = ""; @@ -2344,6 +2268,8 @@ rs6000_debug_addr_mask (addr_mask_type m if ((mask & RELOAD_REG_QUAD_OFFSET) != 0) *p++ = 'O'; + else if ((mask & RELOAD_REG_DS_OFFSET) != 0) + *p++ = 'D'; else if ((mask & RELOAD_REG_OFFSET) != 0) *p++ = 'o'; else if (keep_spaces) @@ -2382,11 +2308,11 @@ rs6000_debug_print_mode (ssize_t m) fprintf (stderr, " %s: %s", reload_reg_map[rc].name, rs6000_debug_addr_mask (reg_addr[m].addr_mask[rc], true)); - if ((reg_addr[m].reload_store != CODE_FOR_nothing) - || (reg_addr[m].reload_load != CODE_FOR_nothing)) + if ((rs6000_insns[m].reload_store != CODE_FOR_nothing) + || (rs6000_insns[m].reload_load != CODE_FOR_nothing)) fprintf (stderr, " Reload=%c%c", - (reg_addr[m].reload_store != CODE_FOR_nothing) ? 's' : '*', - (reg_addr[m].reload_load != CODE_FOR_nothing) ? 'l' : '*'); + (rs6000_insns[m].reload_store != CODE_FOR_nothing) ? 's' : '*', + (rs6000_insns[m].reload_load != CODE_FOR_nothing) ? 'l' : '*'); else spaces += sizeof (" Reload=sl") - 1; @@ -2398,7 +2324,7 @@ rs6000_debug_print_mode (ssize_t m) else spaces += sizeof (" Upper=y") - 1; - fuse_extra_p = ((reg_addr[m].fusion_gpr_ld != CODE_FOR_nothing) + fuse_extra_p = (rs6000_insns[m].fusion_gpr_ld != CODE_FOR_nothing || reg_addr[m].fused_toc); if (!fuse_extra_p) { @@ -2406,11 +2332,11 @@ rs6000_debug_print_mode (ssize_t m) { if (rc != RELOAD_REG_ANY) { - if (reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing - || reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing - || reg_addr[m].fusion_addi_st[rc] != CODE_FOR_nothing - || reg_addr[m].fusion_addis_ld[rc] != CODE_FOR_nothing - || reg_addr[m].fusion_addis_st[rc] != CODE_FOR_nothing) + if (rs6000_insns[m].fusion_addi_ld[rc] != CODE_FOR_nothing + || rs6000_insns[m].fusion_addi_ld[rc] != CODE_FOR_nothing + || rs6000_insns[m].fusion_addi_st[rc] != CODE_FOR_nothing + || rs6000_insns[m].fusion_addis_ld[rc] != CODE_FOR_nothing + || rs6000_insns[m].fusion_addis_st[rc] != CODE_FOR_nothing) { fuse_extra_p = true; break; @@ -2430,16 +2356,16 @@ rs6000_debug_print_mode (ssize_t m) { char load, store; - if (reg_addr[m].fusion_addis_ld[rc] != CODE_FOR_nothing) + if (rs6000_insns[m].fusion_addis_ld[rc] != CODE_FOR_nothing) load = 'l'; - else if (reg_addr[m].fusion_addi_ld[rc] != CODE_FOR_nothing) + else if (rs6000_insns[m].fusion_addi_ld[rc] != CODE_FOR_nothing) load = 'L'; else load = '-'; - if (reg_addr[m].fusion_addis_st[rc] != CODE_FOR_nothing) + if (rs6000_insns[m].fusion_addis_st[rc] != CODE_FOR_nothing) store = 's'; - else if (reg_addr[m].fusion_addi_st[rc] != CODE_FOR_nothing) + else if (rs6000_insns[m].fusion_addi_st[rc] != CODE_FOR_nothing) store = 'S'; else store = '-'; @@ -2455,7 +2381,7 @@ rs6000_debug_print_mode (ssize_t m) } } - if (reg_addr[m].fusion_gpr_ld != CODE_FOR_nothing) + if (rs6000_insns[m].fusion_gpr_ld != CODE_FOR_nothing) { fprintf (stderr, "%*sP8gpr", (spaces + 1), ""); spaces = 0; @@ -2951,8 +2877,11 @@ rs6000_setup_reg_addr_masks (void) /* SDmode is special in that we want to access it only via REG+REG addressing on power7 and above, since we want to use the LFIWZX and - STFIWZX instructions to load it. */ - bool indexed_only_p = (m == SDmode && TARGET_NO_SDMODE_STACK); + STFIWZX instructions to load it. Paired floating point is also + only indexed mode. */ + bool indexed_only_p = ((m == E_SDmode && TARGET_NO_SDMODE_STACK) + || (TARGET_PAIRED_FLOAT + && (m == E_V2SImode || m == E_V2SFmode))); any_addr_mask = 0; for (rc = FIRST_RELOAD_REG_CLASS; rc <= LAST_RELOAD_REG_CLASS; rc++) @@ -2972,11 +2901,8 @@ rs6000_setup_reg_addr_masks (void) /* Indicate if the mode takes more than 1 physical register. If it takes a single register, indicate it can do REG+REG - addressing. Small integers in VSX registers can only do - REG+REG addressing. */ - if (small_int_vsx_p) - addr_mask |= RELOAD_REG_INDEXED; - else if (nregs > 1 || m == BLKmode || complex_p) + addressing. */ + if (nregs > 1 || m == BLKmode || complex_p) addr_mask |= RELOAD_REG_MULTIPLE; else addr_mask |= RELOAD_REG_INDEXED; @@ -3001,7 +2927,8 @@ rs6000_setup_reg_addr_masks (void) && !complex_p && (m != E_DFmode || !TARGET_VSX) && (m != E_SFmode || !TARGET_P8_VECTOR) - && !small_int_vsx_p) + && !small_int_vsx_p + && !indexed_only_p) { addr_mask |= RELOAD_REG_PRE_INCDEC; @@ -3053,6 +2980,22 @@ rs6000_setup_reg_addr_masks (void) addr_mask |= RELOAD_REG_QUAD_OFFSET; } + /* LD and STD are DS-form instructions, which must have the bottom 2 + bits be 0. However, since DFmode is primarily used in the + floating point/vector registers, don't restrict the offsets in ISA + 2.xx. */ + if (rc == RELOAD_REG_GPR && msize == 8 && TARGET_POWERPC64 + && (addr_mask & RELOAD_REG_OFFSET) != 0 + && INTEGRAL_MODE_P (m2)) + addr_mask |= RELOAD_REG_DS_OFFSET; + + /* ISA 3.0 LXSD, LXSSP, STXSD, STXSSP altivec load/store instructions + are DS-FORM. */ + else if (rc == RELOAD_REG_VMX && TARGET_P9_VECTOR + && (addr_mask & RELOAD_REG_OFFSET) != 0 + && (msize == 8 || m2 == SFmode)) + addr_mask |= RELOAD_REG_DS_OFFSET; + /* VMX registers can do (REG & -16) and ((REG+REG) & -16) addressing on 128-bit types. */ if (rc == RELOAD_REG_VMX && msize == 16 @@ -3142,6 +3085,7 @@ rs6000_init_hard_regno_mode_ok (bool glo gcc_assert ((int)CODE_FOR_nothing == 0); memset ((void *) ®_addr[0], '\0', sizeof (reg_addr)); + memset ((void *) &rs6000_insns, '\0', sizeof (rs6000_insns)); gcc_assert ((int)NO_REGS == 0); memset ((void *) &rs6000_constraints[0], '\0', sizeof (rs6000_constraints)); @@ -3394,142 +3338,167 @@ rs6000_init_hard_regno_mode_ok (bool glo { if (TARGET_64BIT) { - reg_addr[V16QImode].reload_store = CODE_FOR_reload_v16qi_di_store; - reg_addr[V16QImode].reload_load = CODE_FOR_reload_v16qi_di_load; - reg_addr[V8HImode].reload_store = CODE_FOR_reload_v8hi_di_store; - reg_addr[V8HImode].reload_load = CODE_FOR_reload_v8hi_di_load; - reg_addr[V4SImode].reload_store = CODE_FOR_reload_v4si_di_store; - reg_addr[V4SImode].reload_load = CODE_FOR_reload_v4si_di_load; - reg_addr[V2DImode].reload_store = CODE_FOR_reload_v2di_di_store; - reg_addr[V2DImode].reload_load = CODE_FOR_reload_v2di_di_load; - reg_addr[V1TImode].reload_store = CODE_FOR_reload_v1ti_di_store; - reg_addr[V1TImode].reload_load = CODE_FOR_reload_v1ti_di_load; - reg_addr[V4SFmode].reload_store = CODE_FOR_reload_v4sf_di_store; - reg_addr[V4SFmode].reload_load = CODE_FOR_reload_v4sf_di_load; - reg_addr[V2DFmode].reload_store = CODE_FOR_reload_v2df_di_store; - reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_di_load; - reg_addr[DFmode].reload_store = CODE_FOR_reload_df_di_store; - reg_addr[DFmode].reload_load = CODE_FOR_reload_df_di_load; - reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_di_store; - reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_di_load; - reg_addr[SFmode].reload_store = CODE_FOR_reload_sf_di_store; - reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_di_load; + rs6000_insns[V16QImode].reload_store = CODE_FOR_reload_v16qi_di_store; + rs6000_insns[V16QImode].reload_load = CODE_FOR_reload_v16qi_di_load; + rs6000_insns[V8HImode].reload_store = CODE_FOR_reload_v8hi_di_store; + rs6000_insns[V8HImode].reload_load = CODE_FOR_reload_v8hi_di_load; + rs6000_insns[V4SImode].reload_store = CODE_FOR_reload_v4si_di_store; + rs6000_insns[V4SImode].reload_load = CODE_FOR_reload_v4si_di_load; + rs6000_insns[V2DImode].reload_store = CODE_FOR_reload_v2di_di_store; + rs6000_insns[V2DImode].reload_load = CODE_FOR_reload_v2di_di_load; + rs6000_insns[V1TImode].reload_store = CODE_FOR_reload_v1ti_di_store; + rs6000_insns[V1TImode].reload_load = CODE_FOR_reload_v1ti_di_load; + rs6000_insns[V4SFmode].reload_store = CODE_FOR_reload_v4sf_di_store; + rs6000_insns[V4SFmode].reload_load = CODE_FOR_reload_v4sf_di_load; + rs6000_insns[V2DFmode].reload_store = CODE_FOR_reload_v2df_di_store; + rs6000_insns[V2DFmode].reload_load = CODE_FOR_reload_v2df_di_load; + rs6000_insns[DFmode].reload_store = CODE_FOR_reload_df_di_store; + rs6000_insns[DFmode].reload_load = CODE_FOR_reload_df_di_load; + rs6000_insns[DDmode].reload_store = CODE_FOR_reload_dd_di_store; + rs6000_insns[DDmode].reload_load = CODE_FOR_reload_dd_di_load; + rs6000_insns[SFmode].reload_store = CODE_FOR_reload_sf_di_store; + rs6000_insns[SFmode].reload_load = CODE_FOR_reload_sf_di_load; if (FLOAT128_VECTOR_P (KFmode)) { - reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_di_store; - reg_addr[KFmode].reload_load = CODE_FOR_reload_kf_di_load; + rs6000_insns[KFmode].reload_store = CODE_FOR_reload_kf_di_store; + rs6000_insns[KFmode].reload_load = CODE_FOR_reload_kf_di_load; } if (FLOAT128_VECTOR_P (TFmode)) { - reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_di_store; - reg_addr[TFmode].reload_load = CODE_FOR_reload_tf_di_load; + rs6000_insns[TFmode].reload_store = CODE_FOR_reload_tf_di_store; + rs6000_insns[TFmode].reload_load = CODE_FOR_reload_tf_di_load; } /* Only provide a reload handler for SDmode if lfiwzx/stfiwx are available. */ if (TARGET_NO_SDMODE_STACK) { - reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_di_store; - reg_addr[SDmode].reload_load = CODE_FOR_reload_sd_di_load; + rs6000_insns[SDmode].reload_store = CODE_FOR_reload_sd_di_store; + rs6000_insns[SDmode].reload_load = CODE_FOR_reload_sd_di_load; } if (TARGET_VSX) { - reg_addr[TImode].reload_store = CODE_FOR_reload_ti_di_store; - reg_addr[TImode].reload_load = CODE_FOR_reload_ti_di_load; + rs6000_insns[TImode].reload_store = CODE_FOR_reload_ti_di_store; + rs6000_insns[TImode].reload_load = CODE_FOR_reload_ti_di_load; } if (TARGET_DIRECT_MOVE && !TARGET_DIRECT_MOVE_128) { - reg_addr[TImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxti; - reg_addr[V1TImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv1ti; - reg_addr[V2DFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv2df; - reg_addr[V2DImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv2di; - reg_addr[V4SFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv4sf; - reg_addr[V4SImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv4si; - reg_addr[V8HImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv8hi; - reg_addr[V16QImode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxv16qi; - reg_addr[SFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxsf; - - reg_addr[TImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprti; - reg_addr[V1TImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv1ti; - reg_addr[V2DFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv2df; - reg_addr[V2DImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv2di; - reg_addr[V4SFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv4sf; - reg_addr[V4SImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv4si; - reg_addr[V8HImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv8hi; - reg_addr[V16QImode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprv16qi; - reg_addr[SFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprsf; + rs6000_insns[TImode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxti; + rs6000_insns[V1TImode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv1ti; + rs6000_insns[V2DFmode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv2df; + rs6000_insns[V2DImode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv2di; + rs6000_insns[V4SFmode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv4sf; + rs6000_insns[V4SImode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv4si; + rs6000_insns[V8HImode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv8hi; + rs6000_insns[V16QImode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxv16qi; + rs6000_insns[SFmode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxsf; + + rs6000_insns[TImode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprti; + rs6000_insns[V1TImode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv1ti; + rs6000_insns[V2DFmode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv2df; + rs6000_insns[V2DImode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv2di; + rs6000_insns[V4SFmode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv4sf; + rs6000_insns[V4SImode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv4si; + rs6000_insns[V8HImode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv8hi; + rs6000_insns[V16QImode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprv16qi; + rs6000_insns[SFmode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprsf; if (FLOAT128_VECTOR_P (KFmode)) { - reg_addr[KFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxkf; - reg_addr[KFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprkf; + rs6000_insns[KFmode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxkf; + rs6000_insns[KFmode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprkf; } if (FLOAT128_VECTOR_P (TFmode)) { - reg_addr[TFmode].reload_gpr_vsx = CODE_FOR_reload_gpr_from_vsxtf; - reg_addr[TFmode].reload_vsx_gpr = CODE_FOR_reload_vsx_from_gprtf; + rs6000_insns[TFmode].reload_gpr_vsx + = CODE_FOR_reload_gpr_from_vsxtf; + rs6000_insns[TFmode].reload_vsx_gpr + = CODE_FOR_reload_vsx_from_gprtf; } } } else { - reg_addr[V16QImode].reload_store = CODE_FOR_reload_v16qi_si_store; - reg_addr[V16QImode].reload_load = CODE_FOR_reload_v16qi_si_load; - reg_addr[V8HImode].reload_store = CODE_FOR_reload_v8hi_si_store; - reg_addr[V8HImode].reload_load = CODE_FOR_reload_v8hi_si_load; - reg_addr[V4SImode].reload_store = CODE_FOR_reload_v4si_si_store; - reg_addr[V4SImode].reload_load = CODE_FOR_reload_v4si_si_load; - reg_addr[V2DImode].reload_store = CODE_FOR_reload_v2di_si_store; - reg_addr[V2DImode].reload_load = CODE_FOR_reload_v2di_si_load; - reg_addr[V1TImode].reload_store = CODE_FOR_reload_v1ti_si_store; - reg_addr[V1TImode].reload_load = CODE_FOR_reload_v1ti_si_load; - reg_addr[V4SFmode].reload_store = CODE_FOR_reload_v4sf_si_store; - reg_addr[V4SFmode].reload_load = CODE_FOR_reload_v4sf_si_load; - reg_addr[V2DFmode].reload_store = CODE_FOR_reload_v2df_si_store; - reg_addr[V2DFmode].reload_load = CODE_FOR_reload_v2df_si_load; - reg_addr[DFmode].reload_store = CODE_FOR_reload_df_si_store; - reg_addr[DFmode].reload_load = CODE_FOR_reload_df_si_load; - reg_addr[DDmode].reload_store = CODE_FOR_reload_dd_si_store; - reg_addr[DDmode].reload_load = CODE_FOR_reload_dd_si_load; - reg_addr[SFmode].reload_store = CODE_FOR_reload_sf_si_store; - reg_addr[SFmode].reload_load = CODE_FOR_reload_sf_si_load; + rs6000_insns[V16QImode].reload_store = CODE_FOR_reload_v16qi_si_store; + rs6000_insns[V16QImode].reload_load = CODE_FOR_reload_v16qi_si_load; + rs6000_insns[V8HImode].reload_store = CODE_FOR_reload_v8hi_si_store; + rs6000_insns[V8HImode].reload_load = CODE_FOR_reload_v8hi_si_load; + rs6000_insns[V4SImode].reload_store = CODE_FOR_reload_v4si_si_store; + rs6000_insns[V4SImode].reload_load = CODE_FOR_reload_v4si_si_load; + rs6000_insns[V2DImode].reload_store = CODE_FOR_reload_v2di_si_store; + rs6000_insns[V2DImode].reload_load = CODE_FOR_reload_v2di_si_load; + rs6000_insns[V1TImode].reload_store = CODE_FOR_reload_v1ti_si_store; + rs6000_insns[V1TImode].reload_load = CODE_FOR_reload_v1ti_si_load; + rs6000_insns[V4SFmode].reload_store = CODE_FOR_reload_v4sf_si_store; + rs6000_insns[V4SFmode].reload_load = CODE_FOR_reload_v4sf_si_load; + rs6000_insns[V2DFmode].reload_store = CODE_FOR_reload_v2df_si_store; + rs6000_insns[V2DFmode].reload_load = CODE_FOR_reload_v2df_si_load; + rs6000_insns[DFmode].reload_store = CODE_FOR_reload_df_si_store; + rs6000_insns[DFmode].reload_load = CODE_FOR_reload_df_si_load; + rs6000_insns[DDmode].reload_store = CODE_FOR_reload_dd_si_store; + rs6000_insns[DDmode].reload_load = CODE_FOR_reload_dd_si_load; + rs6000_insns[SFmode].reload_store = CODE_FOR_reload_sf_si_store; + rs6000_insns[SFmode].reload_load = CODE_FOR_reload_sf_si_load; if (FLOAT128_VECTOR_P (KFmode)) { - reg_addr[KFmode].reload_store = CODE_FOR_reload_kf_si_store; - reg_addr[KFmode].reload_load = CODE_FOR_reload_kf_si_load; + rs6000_insns[KFmode].reload_store = CODE_FOR_reload_kf_si_store; + rs6000_insns[KFmode].reload_load = CODE_FOR_reload_kf_si_load; } if (FLOAT128_IEEE_P (TFmode)) { - reg_addr[TFmode].reload_store = CODE_FOR_reload_tf_si_store; - reg_addr[TFmode].reload_load = CODE_FOR_reload_tf_si_load; + rs6000_insns[TFmode].reload_store = CODE_FOR_reload_tf_si_store; + rs6000_insns[TFmode].reload_load = CODE_FOR_reload_tf_si_load; } /* Only provide a reload handler for SDmode if lfiwzx/stfiwx are available. */ if (TARGET_NO_SDMODE_STACK) { - reg_addr[SDmode].reload_store = CODE_FOR_reload_sd_si_store; - reg_addr[SDmode].reload_load = CODE_FOR_reload_sd_si_load; + rs6000_insns[SDmode].reload_store = CODE_FOR_reload_sd_si_store; + rs6000_insns[SDmode].reload_load = CODE_FOR_reload_sd_si_load; } if (TARGET_VSX) { - reg_addr[TImode].reload_store = CODE_FOR_reload_ti_si_store; - reg_addr[TImode].reload_load = CODE_FOR_reload_ti_si_load; + rs6000_insns[TImode].reload_store = CODE_FOR_reload_ti_si_store; + rs6000_insns[TImode].reload_load = CODE_FOR_reload_ti_si_load; } if (TARGET_DIRECT_MOVE) { - reg_addr[DImode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdi; - reg_addr[DDmode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdd; - reg_addr[DFmode].reload_fpr_gpr = CODE_FOR_reload_fpr_from_gprdf; + rs6000_insns[DImode].reload_fpr_gpr + = CODE_FOR_reload_fpr_from_gprdi; + rs6000_insns[DDmode].reload_fpr_gpr + = CODE_FOR_reload_fpr_from_gprdd; + rs6000_insns[DFmode].reload_fpr_gpr + = CODE_FOR_reload_fpr_from_gprdf; } } @@ -3552,11 +3521,11 @@ rs6000_init_hard_regno_mode_ok (bool glo /* Setup the fusion operations. */ if (TARGET_P8_FUSION) { - reg_addr[QImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_qi; - reg_addr[HImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_hi; - reg_addr[SImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_si; + rs6000_insns[QImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_qi; + rs6000_insns[HImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_hi; + rs6000_insns[SImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_si; if (TARGET_64BIT) - reg_addr[DImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_di; + rs6000_insns[DImode].fusion_gpr_ld = CODE_FOR_fusion_gpr_load_di; } if (TARGET_P9_FUSION) @@ -3649,14 +3618,14 @@ rs6000_init_hard_regno_mode_ok (bool glo if (rtype == RELOAD_REG_FPR && !TARGET_HARD_FLOAT) continue; - reg_addr[xmode].fusion_addis_ld[rtype] = addis_insns[i].load; - reg_addr[xmode].fusion_addis_st[rtype] = addis_insns[i].store; + rs6000_insns[xmode].fusion_addis_ld[rtype] = addis_insns[i].load; + rs6000_insns[xmode].fusion_addis_st[rtype] = addis_insns[i].store; if (rtype == RELOAD_REG_FPR && TARGET_P9_VECTOR) { - reg_addr[xmode].fusion_addis_ld[RELOAD_REG_VMX] + rs6000_insns[xmode].fusion_addis_ld[RELOAD_REG_VMX] = addis_insns[i].load; - reg_addr[xmode].fusion_addis_st[RELOAD_REG_VMX] + rs6000_insns[xmode].fusion_addis_st[RELOAD_REG_VMX] = addis_insns[i].store; } } @@ -7427,7 +7396,7 @@ rs6000_expand_vector_extract (rtx target } /* Helper function to return the register number of a RTX. */ -static inline int +int regno_or_subregno (rtx op) { if (REG_P (op)) @@ -8107,7 +8076,7 @@ quad_address_p (rtx addr, machine_mode m if (legitimate_indirect_address_p (addr, strict)) return true; - if (VECTOR_MODE_P (mode) && !mode_supports_vsx_dform_quad (mode)) + if (VECTOR_MODE_P (mode) && !mode_supports_dq_form (mode)) return false; if (GET_CODE (addr) != PLUS) @@ -8289,7 +8258,7 @@ reg_offset_addressing_ok_p (machine_mode IEEE 128-bit floating point that is passed in a single vector register. */ if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode)) - return mode_supports_vsx_dform_quad (mode); + return mode_supports_dq_form (mode); break; case E_V2SImode: @@ -8356,7 +8325,7 @@ offsettable_ok_by_alignment (rtx op, HOS /* ISA 3.0 vector d-form addressing is restricted, don't allow SYMBOL_REF. */ - if (mode_supports_vsx_dform_quad (mode)) + if (mode_supports_dq_form (mode)) return false; dsize = GET_MODE_SIZE (mode); @@ -8527,7 +8496,7 @@ rs6000_legitimate_offset_address_p (mach return false; if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)) return false; - if (mode_supports_vsx_dform_quad (mode)) + if (mode_supports_dq_form (mode)) return quad_address_p (x, mode, strict); if (!reg_offset_addressing_ok_p (mode)) return virtual_stack_registers_memory_p (x); @@ -8645,7 +8614,7 @@ legitimate_lo_sum_address_p (machine_mod if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict)) return false; /* quad word addresses are restricted, and we can't use LO_SUM. */ - if (mode_supports_vsx_dform_quad (mode)) + if (mode_supports_dq_form (mode)) return false; x = XEXP (x, 1); @@ -8710,7 +8679,7 @@ rs6000_legitimize_address (rtx x, rtx ol unsigned int extra; if (!reg_offset_addressing_ok_p (mode) - || mode_supports_vsx_dform_quad (mode)) + || mode_supports_dq_form (mode)) { if (virtual_stack_registers_memory_p (x)) return x; @@ -9454,7 +9423,7 @@ rs6000_legitimize_reload_address (rtx x, int ind_levels ATTRIBUTE_UNUSED, int *win) { bool reg_offset_p = reg_offset_addressing_ok_p (mode); - bool quad_offset_p = mode_supports_vsx_dform_quad (mode); + bool quad_offset_p = mode_supports_dq_form (mode); /* Nasty hack for vsx_splat_v2df/v2di load from mem, which takes a DFmode/DImode MEM. Ditto for ISA 3.0 vsx_splat_v4sf/v4si. */ @@ -9742,7 +9711,7 @@ static bool rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict) { bool reg_offset_p = reg_offset_addressing_ok_p (mode); - bool quad_offset_p = mode_supports_vsx_dform_quad (mode); + bool quad_offset_p = mode_supports_dq_form (mode); /* If this is an unaligned stvx/ldvx type address, discard the outer AND. */ if (VECTOR_MEM_ALTIVEC_P (mode) @@ -19913,7 +19882,7 @@ rs6000_secondary_reload_direct_move (enu if (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE) { cost = 3; /* 2 mtvsrd's, 1 xxpermdi. */ - icode = reg_addr[mode].reload_vsx_gpr; + icode = rs6000_insns[mode].reload_vsx_gpr; } /* Handle moving 128-bit values from VSX point registers to GPRs on @@ -19922,7 +19891,7 @@ rs6000_secondary_reload_direct_move (enu else if (to_type == GPR_REG_TYPE && from_type == VSX_REG_TYPE) { cost = 3; /* 2 mfvsrd's, 1 xxpermdi. */ - icode = reg_addr[mode].reload_gpr_vsx; + icode = rs6000_insns[mode].reload_gpr_vsx; } } @@ -19931,13 +19900,13 @@ rs6000_secondary_reload_direct_move (enu if (to_type == GPR_REG_TYPE && from_type == VSX_REG_TYPE) { cost = 3; /* xscvdpspn, mfvsrd, and. */ - icode = reg_addr[mode].reload_gpr_vsx; + icode = rs6000_insns[mode].reload_gpr_vsx; } else if (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE) { cost = 2; /* mtvsrz, xscvspdpn. */ - icode = reg_addr[mode].reload_vsx_gpr; + icode = rs6000_insns[mode].reload_vsx_gpr; } } @@ -19953,7 +19922,7 @@ rs6000_secondary_reload_direct_move (enu if (to_type == VSX_REG_TYPE && from_type == GPR_REG_TYPE && !altivec_p) { cost = 3; /* 2 mtvsrwz's, 1 fmrgow. */ - icode = reg_addr[mode].reload_fpr_gpr; + icode = rs6000_insns[mode].reload_fpr_gpr; } } @@ -20045,8 +20014,8 @@ rs6000_secondary_reload (bool in_p, sri->t_icode = CODE_FOR_nothing; sri->extra_cost = 0; icode = ((in_p) - ? reg_addr[mode].reload_load - : reg_addr[mode].reload_store); + ? rs6000_insns[mode].reload_load + : rs6000_insns[mode].reload_store); if (REG_P (x) || register_operand (x, mode)) { @@ -20081,7 +20050,7 @@ rs6000_secondary_reload (bool in_p, point register, unless we have D-form addressing. Also make sure that non-zero constants use a FPR. */ if (!done_p && reg_addr[mode].scalar_in_vmx_p - && !mode_supports_vmx_dform (mode) + && !mode_supports_d_form (mode, RELOAD_REG_VMX) && (rclass == VSX_REGS || rclass == ALTIVEC_REGS) && (memory_p || (GET_CODE (x) == CONST_DOUBLE))) { @@ -20409,7 +20378,7 @@ rs6000_secondary_reload_inner (rtx reg, } } - else if (mode_supports_vsx_dform_quad (mode) && CONST_INT_P (op1)) + else if (mode_supports_dq_form (mode) && CONST_INT_P (op1)) { if (((addr_mask & RELOAD_REG_QUAD_OFFSET) == 0) || !quad_address_p (addr, mode, false)) @@ -20450,7 +20419,7 @@ rs6000_secondary_reload_inner (rtx reg, } /* Quad offsets are restricted and can't handle normal addresses. */ - else if (mode_supports_vsx_dform_quad (mode)) + else if (mode_supports_dq_form (mode)) { emit_insn (gen_rtx_SET (scratch, addr)); new_addr = scratch; @@ -20644,8 +20613,8 @@ rs6000_preferred_reload_class (rtx x, en } /* D-form addressing can easily reload the value. */ - if (mode_supports_vmx_dform (mode) - || mode_supports_vsx_dform_quad (mode)) + if (mode_supports_d_form (mode, RELOAD_REG_VMX) + || mode_supports_dq_form (mode)) return rclass; /* If this is a scalar floating point value and we don't have D-form @@ -20801,7 +20770,7 @@ rs6000_secondary_reload_class (enum reg_ instead of reloading the secondary memory address for Altivec moves. */ if (TARGET_VSX && GET_MODE_SIZE (mode) < 16 - && !mode_supports_vmx_dform (mode) + && !mode_supports_d_form (mode, RELOAD_REG_VMX) && (((rclass == GENERAL_REGS || rclass == BASE_REGS) && (regno >= 0 && ALTIVEC_REGNO_P (regno))) || ((rclass == VSX_REGS || rclass == ALTIVEC_REGS) @@ -21048,7 +21017,7 @@ rs6000_output_move_128bit (rtx operands[ else if (TARGET_VSX && dest_vsx_p) { - if (mode_supports_vsx_dform_quad (mode) + if (mode_supports_dq_form (mode) && quad_address_p (XEXP (src, 0), mode, true)) return "lxv %x0,%1"; @@ -21086,7 +21055,7 @@ rs6000_output_move_128bit (rtx operands[ else if (TARGET_VSX && src_vsx_p) { - if (mode_supports_vsx_dform_quad (mode) + if (mode_supports_dq_form (mode) && quad_address_p (XEXP (dest, 0), mode, true)) return "stxv %x1,%0";