From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 67451 invoked by alias); 30 May 2019 03:49:54 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 67218 invoked by uid 89); 30 May 2019 03:49:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-21.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,HTML_MESSAGE,KAM_STOCKGEN,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0a-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.156.1) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 30 May 2019 03:49:44 +0000 Received: from pps.filterd (m0098409.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id x4U3laC5069941 for ; Wed, 29 May 2019 23:49:41 -0400 Received: from e16.ny.us.ibm.com (e16.ny.us.ibm.com [129.33.205.206]) by mx0a-001b2d01.pphosted.com with ESMTP id 2st3241jqs-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Wed, 29 May 2019 23:49:41 -0400 Received: from localhost by e16.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 30 May 2019 04:49:40 +0100 Received: from b01cxnp22034.gho.pok.ibm.com (9.57.198.24) by e16.ny.us.ibm.com (146.89.104.203) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Thu, 30 May 2019 04:49:37 +0100 Received: from b01ledav006.gho.pok.ibm.com (b01ledav006.gho.pok.ibm.com [9.57.199.111]) by b01cxnp22034.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id x4U3nap831916108 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 30 May 2019 03:49:37 GMT Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id DFDE6AC05F; Thu, 30 May 2019 03:49:36 +0000 (GMT) Received: from b01ledav006.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6EBF9AC05B; Thu, 30 May 2019 03:49:36 +0000 (GMT) Received: from BigMac.local (unknown [9.85.143.85]) by b01ledav006.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 30 May 2019 03:49:36 +0000 (GMT) To: GCC Patches Cc: Segher Boessenkool From: Bill Schmidt Subject: [PATCH] rs6000: Add basic support for prefixed and PC-relative addresses Date: Thu, 30 May 2019 03:52:00 -0000 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 x-cbid: 19053003-0072-0000-0000-0000043513D8 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00011182; HX=3.00000242; KW=3.00000007; PH=3.00000004; SC=3.00000286; SDB=6.01210562; UDB=6.00636024; IPR=6.00991596; MB=3.00027111; MTD=3.00000008; XFM=3.00000015; UTC=2019-05-30 03:49:39 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 19053003-0073-0000-0000-00004C6A06F7 Message-Id: Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-SW-Source: 2019-05/txt/msg01984.txt.bz2 Hi, This patch adds basic infrastructure for prefixed and PC-relative addresses, including new predicates and functions to detect when they apply. Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions. Is this okay for trunk? Thanks, Bill 2019-05-29 Bill Schmidt Michael Meissner * config/rs6000/predicates.md (pcrel_address): New define_predicate. (prefixed_mem_operand): Likewise. (non_prefixed_mem_operand): Likewise. * config/rs6000/rs6000-protos.h (rs6000_prefixed_address): New prototype. * config/rs6000/rs6000.c (print_operand_address): Handle PC-relative addresses. (mode_supports_prefixed_address_p): New function. (rs6000_prefixed_address): New function. * config/rs6000/rs6000.h (SYMBOL_FLAG_PCREL): New #define. (SYMBOL_REF_PCREL_P): Likewise. diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index a578e0f27f7..8ca98299950 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1622,6 +1622,45 @@ return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL; }) +;; Return true if the operand is a pc-relative address. +(define_predicate "pcrel_address" + (match_code "label_ref,symbol_ref,const") +{ + if (!TARGET_PCREL) + return false; + + /* Discard any CONST's. */ + if (GET_CODE (op) == CONST) + op = XEXP (op, 0); + + /* Validate offset. */ + if (GET_CODE (op) == PLUS) + { + rtx op0 = XEXP (op, 0); + rtx op1 = XEXP (op, 1); + + if (!CONST_INT_P (op1) || !SIGNED_34BIT_OFFSET_P (INTVAL (op1), 0)) + return false; + + op = op0; + } + + return LABEL_REF_P (op) || SYMBOL_REF_PCREL_P (op); +}) + +;; Return 1 if op is a prefixed memory operand +(define_predicate "prefixed_mem_operand" + (match_code "mem") +{ + return rs6000_prefixed_address (XEXP (op, 0), GET_MODE (op)); +}) + +;; Return 1 if op is a memory operand that is not a prefixed memory +;; operand. +(define_predicate "non_prefixed_mem_operand" + (and (match_operand 0 "memory_operand") + (not (match_operand 0 "prefixed_mem_operand")))) + ;; Match the first insn (addis) in fusing the combination of addis and loads to ;; GPR registers on power8. (define_predicate "fusion_gpr_addis" diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 18ece005a96..feb1250fb8b 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -154,6 +154,7 @@ extern align_flags rs6000_loop_align (rtx); extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool); extern bool rs6000_pcrel_p (struct function *); extern bool rs6000_fndecl_pcrel_p (const_tree); +extern bool rs6000_prefixed_address (rtx, machine_mode); #endif /* RTX_CODE */ #ifdef TREE_CODE diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index f9ef8e38314..31b86633118 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21085,6 +21085,34 @@ print_operand_address (FILE *file, rtx x) { if (REG_P (x)) fprintf (file, "0(%s)", reg_names[ REGNO (x) ]); + + /* Is it a pc-relative address? */ + else if (pcrel_address (x, Pmode)) + { + HOST_WIDE_INT offset; + + if (GET_CODE (x) == CONST) + x = XEXP (x, 0); + + if (GET_CODE (x) == PLUS) + { + offset = INTVAL (XEXP (x, 1)); + x = XEXP (x, 0); + } + else + offset = 0; + + if (LABEL_REF_P (x)) + output_asm_label (x); + else + output_addr_const (file, x); + + if (offset) + fprintf (file, "%s" HOST_WIDE_INT_PRINT_DEC, (offset > 0) ? "+" : "", + offset); + + fputs ("@pcrel", file); + } else if (SYMBOL_REF_P (x) || GET_CODE (x) == CONST || GET_CODE (x) == LABEL_REF) { @@ -21569,6 +21597,71 @@ rs6000_pltseq_template (rtx *operands, int which) } #endif +/* Helper function to return whether a MODE can do prefixed loads/stores. + VOIDmode is used when we are loading the pc-relative address into a base + register, but we are not using it as part of a memory operation. As modes + add support for prefixed memory, they will be added here. */ + +static bool +mode_supports_prefixed_address_p (machine_mode mode) +{ + return mode == VOIDmode; +} + +/* Function to return true if ADDR is a valid prefixed memory address that uses + mode MODE. */ + +bool +rs6000_prefixed_address (rtx addr, machine_mode mode) +{ + if (!TARGET_PREFIXED_ADDR || !mode_supports_prefixed_address_p (mode)) + return false; + + /* Check for PC-relative addresses. */ + if (pcrel_address (addr, Pmode)) + return true; + + /* Check for prefixed memory addresses that have a large numeric offset, + or an offset that can't be used for a DS/DQ-form memory operation. */ + if (GET_CODE (addr) == PLUS) + { + HOST_WIDE_INT value, mask; + rtx op0 = XEXP (addr, 0); + rtx op1 = XEXP (addr, 1); + + if (!base_reg_operand (op0, Pmode) || !CONST_INT_P (op1)) + return false; + + value = INTVAL (op1); + if (!SIGNED_34BIT_OFFSET_P (value, 0)) + return false; + + /* Offset larger than 16-bits? */ + if (!SIGNED_16BIT_OFFSET_P (value, 0)) + return true; + + /* DQ instruction (bottom 4 bits must be 0) for vectors. */ + if (GET_MODE_SIZE (mode) >= 16) + mask = 15; + + /* DS instruction (bottom 2 bits must be 0). For 32-bit integers, we + need to use DS instructions if we are sign-extending the value with + LWA. For 32-bit floating point, we need DS instructions to load and + store values to the traditional Altivec registers. */ + else if (GET_MODE_SIZE (mode) >= 4) + mask = 3; + + /* QImode/HImode has no restrictions. */ + else + return true; + + /* Return true if we must use a prefixed instruction. */ + return ((value & ~mask) != value); + } + + return false; +} + #if defined (HAVE_GAS_HIDDEN) && !TARGET_MACHO /* Emit an assembler directive to set symbol visibility for DECL to VISIBILITY_TYPE. */ diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 8119c6621d5..34fa36b6ed9 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -2516,3 +2516,10 @@ extern GTY(()) tree rs6000_builtin_decls[RS6000_BUILTIN_COUNT]; IN_RANGE (VALUE, \ -(HOST_WIDE_INT_1 << 33), \ (HOST_WIDE_INT_1 << 33) - 1 - (EXTRA)) + +/* Flag to mark SYMBOL_REF objects to say they are local addresses and are used + in pc-relative addresses. */ +#define SYMBOL_FLAG_PCREL SYMBOL_FLAG_MACH_DEP + +#define SYMBOL_REF_PCREL_P(X) \ + (SYMBOL_REF_P (X) && SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_PCREL)