From patchwork Thu May 30 03:49:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Schmidt X-Patchwork-Id: 1107515 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-501931-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="PsijVnyc"; 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 45DtrZ21VFz9sS9 for ; Thu, 30 May 2019 13:50:03 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:date:mime-version:message-id:content-type :content-transfer-encoding; q=dns; s=default; b=YPSDYO8rmPUE49yS kspPdGUJDNkIIYwRJ/0UUOfrxS+SY2Axq45zw/58QFXIn9JrKDTqeN/k+3qzq2SB IFqBqgJybdDD3ayHNHH/Aehzfgd8JqSNwsiTPPCu/QVj4lj1f9/fPrAauh2WTDav LJ46ckMcrTT6Hi84IDQ9av9NH68= 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:to:cc :from:subject:date:mime-version:message-id:content-type :content-transfer-encoding; s=default; bh=gAKUwGhS8XW36BD3mciSao wrb7I=; b=PsijVnycKhhF53G/JhSIwAQrm8LiqC4FcGial9SLPLnmhaEktkJP3q JHPUZW61g5VSkmcfVyB9HrFqvlTpbDkreHf1eT0YmHZzrsRGiMkoaRD7t8disHqz JgPLf30TvJHGXKlAiI+rEFcYEJZ12C+5IULJBSkgplIcBEWIwuBz0= 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-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 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: Wed, 29 May 2019 22:49:35 -0500 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: 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)