From patchwork Thu Jul 21 06:41:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenglulu X-Patchwork-Id: 92 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e252:0:0:0:0:0 with SMTP id bl18csp1302299wrb; Wed, 20 Jul 2022 23:44:37 -0700 (PDT) X-Google-Smtp-Source: AGRyM1umDfFl81wyITTiFi5pzW6SpTLMD4KXj9HN5R2HW5ZISjTsXlXeICjOX0ki0StGkWipOQYk X-Received: by 2002:a05:6402:c47:b0:437:ce2d:c30d with SMTP id cs7-20020a0564020c4700b00437ce2dc30dmr54331372edb.395.1658385877539; Wed, 20 Jul 2022 23:44:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658385877; cv=none; d=google.com; s=arc-20160816; b=ufxKBw38P+l9qNP+7/fiHSP2T8d5uzFY8s/f73gV1Fb61EDewUzr3uamiMZ+bxQezX G9he/fLit2dJyB4a6EQZMThT3cVzlk1dQ+fRRXG4zVrhxTptBwm3MZbWko92b/s4hTmG VUzVZ6l62n5NevsmMKqrN4Boxq6RJF1srl538zby19tnnJRV8Gkkh9HLmFBWu0H6PN1z lHc9EKeWk45Q11Kuf1hQs7OKFZK1DpI7zptID09nZI4J3bEKvlft5W44Ta8Af+Bh8owi DIwfRqE7O0cJCM1MTCPf6S+5vryN1V3xXBuxiqwY9Z3ClkIQVcL54SQ9lQ7oGk+FD9aF Zlsg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dmarc-filter:delivered-to; bh=ePUTuyTgi6pBvb/tOTgVn5wz5U+HbSDus3x87iL3UFU=; b=SmRKFo+A5hajPeIQVVKvEbfYO9/2aqu83AxaB+EQjCLK+706laC54FZXQqJdcPwuyD Fj6AGVbPahaoKkhE8ocWxbYPFTYgf60FP7xx1k4XQz5bK/5dbxgJsvcStutUoA15xnfK x1wkYGSzvTgYA4sMBQKb8VlM0PHGDCL+U6Gd257I06glEFxiMjWjzpmqxrqbdM6PKyAy BAD6XBbVBHzdQi/p3kE/cJY/UO010X+S3UoOa3IpfZKd1t/PghA5zfGqygktEyTyxAsk RgHXwx073Q4+yuGdTZYplwpRvPS4/pphuWX3n2nvYekesJAjfYuzaXfQ2TCxQhUNKS/R h/Bg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id dm17-20020a170907949100b00727c6da65fasi1713596ejc.259.2022.07.20.23.44.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jul 2022 23:44:37 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id DD0BF384D149 for ; Thu, 21 Jul 2022 06:43:49 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 30F653857366 for ; Thu, 21 Jul 2022 06:43:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 30F653857366 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from 5.5.5 (unknown [10.2.5.5]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxf9N+9dhiwgssAA--.40495S3; Thu, 21 Jul 2022 14:43:17 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Subject: [PATCH v2 1/3] LoongArch: Subdivision symbol type, add SYMBOL_PCREL support. Date: Thu, 21 Jul 2022 14:41:21 +0800 Message-Id: <20220721064123.2981805-2-chenglulu@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220721064123.2981805-1-chenglulu@loongson.cn> References: <20220721064123.2981805-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dxf9N+9dhiwgssAA--.40495S3 X-Coremail-Antispam: 1UD129KBjvAXoWfAr1rKrW5GFWrCF15JrWkJFb_yoWrJw1fto WFyF4kAF1rGryUK39akFnxXFyDZFyjy3yfAasxA3Z09a1ktrW5trWxKa13Z3y3Xr97XrWU Xa4vga93Aas7JFs7n29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYA7AC8VAFwI0_Gr0_Xr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r18M28IrcIa0x kI8VCY1x0267AKxVWUXVWUCwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJw A2z4x0Y4vEx4A2jsIE14v26F4UJVW0owA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_Jrv_JF1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svPMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r1I6r4UMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Jr0_Gr1lIxAIcVC2z280aV CY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7VUbKii3UUUUU== X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: xuchenghua@loongson.cn, Lulu Cheng , i@xen0n.name Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738943630221827369?= X-GMAIL-MSGID: =?utf-8?q?1738943630221827369?= 1. Remove cModel type support other than normal. 2. The method that calls global functions from 'la.global + jirl' to 'bl' when build with '-fplt'. gcc/ChangeLog: * config/loongarch/constraints.md (a): Delete the constraint. (b): A constant call not local address. (h): Delete the constraint. (t): Delete the constraint. * config/loongarch/loongarch-protos.h (enum loongarch_symbol_type): Add new symbol type 'SYMBOL_PCREL', 'SYMBOL_TLS_IE' and 'SYMBOL_TLS_LE'. (loongarch_split_symbol): Delete useless function declarations. (loongarch_split_symbol_type): Delete useless function declarations. * config/loongarch/loongarch.cc (enum loongarch_address_type): Delete unnecessary comment information. (loongarch_symbol_binds_local_p): Modified the judgment order of label and symbol. (loongarch_classify_symbol): Return symbol type. If symbol is a label, or symbol is a local symbol return SYMBOL_PCREL. If is a tls symbol, return SYMBOL_TLS. If is a not local symbol return SYMBOL_GOT_DISP. (loongarch_symbolic_constant_p): Add handling of 'SYMBOL_TLS_IE' 'SYMBOL_TLS_LE' and 'SYMBOL_PCREL'. (loongarch_symbol_insns): Add handling of 'SYMBOL_TLS_IE' 'SYMBOL_TLS_LE' and 'SYMBOL_PCREL'. (loongarch_address_insns): Sort code. (loongarch_12bit_offset_address_p): Sort code. (loongarch_14bit_shifted_offset_address_p): Sort code. (loongarch_call_tls_get_addr): Sort code. (loongarch_legitimize_tls_address): Sort code. (loongarch_output_move): Remove schema support for cmodel other than normal. (loongarch_memmodel_needs_release_fence): Sort code. (loongarch_print_operand): Sort code. * config/loongarch/loongarch.h (LARCH_U12BIT_OFFSET_P): Rename to LARCH_12BIT_OFFSET_P. (LARCH_12BIT_OFFSET_P): New macro. * config/loongarch/loongarch.md: Reimplement the function call. Remove schema support for cmodel other than normal. * config/loongarch/predicates.md (is_const_call_weak_symbol): Delete this predicate. (is_const_call_plt_symbol): Delete this predicate. (is_const_call_global_noplt_symbol): Delete this predicate. (is_const_call_no_local_symbol): New predicate, determines whether it is a local symbol or label. gcc/testsuite/ChangeLog: * gcc.target/loongarch/func-call-1.c: New test. * gcc.target/loongarch/func-call-2.c: New test. * gcc.target/loongarch/func-call-3.c: New test. * gcc.target/loongarch/func-call-4.c: New test. --- gcc/config/loongarch/constraints.md | 24 +- gcc/config/loongarch/loongarch-protos.h | 9 +- gcc/config/loongarch/loongarch.cc | 256 +++++++--------- gcc/config/loongarch/loongarch.h | 2 +- gcc/config/loongarch/loongarch.md | 279 +++--------------- gcc/config/loongarch/predicates.md | 40 ++- .../gcc.target/loongarch/func-call-1.c | 32 ++ .../gcc.target/loongarch/func-call-2.c | 32 ++ .../gcc.target/loongarch/func-call-3.c | 32 ++ .../gcc.target/loongarch/func-call-4.c | 32 ++ 10 files changed, 305 insertions(+), 433 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-3.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-4.c diff --git a/gcc/config/loongarch/constraints.md b/gcc/config/loongarch/constraints.md index d0bfddbd5a9..43cb7b5f0f5 100644 --- a/gcc/config/loongarch/constraints.md +++ b/gcc/config/loongarch/constraints.md @@ -20,14 +20,14 @@ ;; Register constraints -;; "a" "A constant call global and noplt address." -;; "b" <-----unused +;; "a" <-----unused +;; "b" "A constant call not local address." ;; "c" "A constant call local address." ;; "d" <-----unused ;; "e" JIRL_REGS ;; "f" FP_REGS ;; "g" <-----unused -;; "h" "A constant call plt address." +;; "h" <-----unused ;; "i" "Matches a general integer constant." (Global non-architectural) ;; "j" SIBCALL_REGS ;; "k" "A memory operand whose address is formed by a base register and @@ -42,7 +42,7 @@ ;; "q" CSR_REGS ;; "r" GENERAL_REGS (Global non-architectural) ;; "s" "Matches a symbolic integer constant." (Global non-architectural) -;; "t" "A constant call weak address" +;; "t" <-----unused ;; "u" "A signed 52bit constant and low 32-bit is zero (for logic instructions)" ;; "v" "A signed 64-bit constant and low 44-bit is zero (for logic instructions)." ;; "w" "Matches any valid memory." @@ -89,10 +89,10 @@ ;; "<" "Matches a pre-dec or post-dec operand." (Global non-architectural) ;; ">" "Matches a pre-inc or post-inc operand." (Global non-architectural) -(define_constraint "a" +(define_constraint "b" "@internal - A constant call global and noplt address." - (match_operand 0 "is_const_call_global_noplt_symbol")) + A constant call no local address." + (match_operand 0 "is_const_call_no_local_symbol")) (define_constraint "c" "@internal @@ -105,11 +105,6 @@ (define_register_constraint "e" "JIRL_REGS" (define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS" "A floating-point register (if available).") -(define_constraint "h" - "@internal - A constant call plt address." - (match_operand 0 "is_const_call_plt_symbol")) - (define_register_constraint "j" "SIBCALL_REGS" "@internal") @@ -134,11 +129,6 @@ (define_memory_constraint "m" (define_register_constraint "q" "CSR_REGS" "A general-purpose register except for $r0 and $r1 for lcsr.") -(define_constraint "t" - "@internal - A constant call weak address." - (match_operand 0 "is_const_call_weak_symbol")) - (define_constraint "u" "A signed 52bit constant and low 32-bit is zero (for logic instructions)." (and (match_code "const_int") diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index 2287fd3763c..080766250d1 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -27,9 +27,13 @@ along with GCC; see the file COPYING3. If not see SYMBOL_GOT_DISP The symbol's value will be loaded directly from the GOT. + SYMBOL_PCREL + The symbol's value will be loaded directly from data section. + SYMBOL_TLS A thread-local symbol. + SYMBOL_TLS_IE SYMBOL_TLSGD SYMBOL_TLSLDM UNSPEC wrappers around SYMBOL_TLS, corresponding to the @@ -37,7 +41,10 @@ along with GCC; see the file COPYING3. If not see */ enum loongarch_symbol_type { SYMBOL_GOT_DISP, + SYMBOL_PCREL, SYMBOL_TLS, + SYMBOL_TLS_IE, + SYMBOL_TLS_LE, SYMBOL_TLSGD, SYMBOL_TLSLDM, }; @@ -61,7 +68,6 @@ extern int loongarch_idiv_insns (machine_mode); #ifdef RTX_CODE extern void loongarch_emit_binary (enum rtx_code, rtx, rtx, rtx); #endif -extern bool loongarch_split_symbol (rtx, rtx, machine_mode, rtx *); extern rtx loongarch_unspec_address (rtx, enum loongarch_symbol_type); extern rtx loongarch_strip_unspec_address (rtx); extern void loongarch_move_integer (rtx, rtx, unsigned HOST_WIDE_INT); @@ -154,7 +160,6 @@ extern rtx loongarch_expand_thread_pointer (rtx); extern bool loongarch_eh_uses (unsigned int); extern bool loongarch_epilogue_uses (unsigned int); extern bool loongarch_load_store_bonding_p (rtx *, machine_mode, bool); -extern bool loongarch_split_symbol_type (enum loongarch_symbol_type); typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx); diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 8b0d7f459e0..1cb5742f6dd 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -114,19 +114,7 @@ enum loongarch_address_type }; -/* Information about an address described by loongarch_address_type. - - ADDRESS_CONST_INT - No fields are used. - - ADDRESS_REG - REG is the base register and OFFSET is the constant offset. - - ADDRESS_REG_REG - A base register indexed by (optionally scaled) register. - - ADDRESS_SYMBOLIC - SYMBOL_TYPE is the type of symbol that the address references. */ +/* Information about an address described by loongarch_address_type. */ struct loongarch_address_info { enum loongarch_address_type type; @@ -1617,11 +1605,12 @@ loongarch_weak_symbol_p (const_rtx x) bool loongarch_symbol_binds_local_p (const_rtx x) { - if (LABEL_REF_P (x)) + if (SYMBOL_REF_P (x)) + return (SYMBOL_REF_DECL (x) + ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) + : SYMBOL_REF_LOCAL_P (x)); + else return false; - - return (SYMBOL_REF_DECL (x) ? targetm.binds_local_p (SYMBOL_REF_DECL (x)) - : SYMBOL_REF_LOCAL_P (x)); } /* Return true if rtx constants of mode MODE should be put into a small @@ -1640,17 +1629,16 @@ static enum loongarch_symbol_type loongarch_classify_symbol (const_rtx x) { if (LABEL_REF_P (x)) - return SYMBOL_GOT_DISP; - - gcc_assert (SYMBOL_REF_P (x)); + return SYMBOL_PCREL; if (SYMBOL_REF_TLS_MODEL (x)) return SYMBOL_TLS; - if (SYMBOL_REF_P (x)) + if (SYMBOL_REF_P (x) + && !loongarch_symbol_binds_local_p (x)) return SYMBOL_GOT_DISP; - return SYMBOL_GOT_DISP; + return SYMBOL_PCREL; } /* Return true if X is a symbolic constant. If it is, @@ -1683,9 +1671,15 @@ loongarch_symbolic_constant_p (rtx x, enum loongarch_symbol_type *symbol_type) relocations. */ switch (*symbol_type) { - case SYMBOL_GOT_DISP: + case SYMBOL_TLS_IE: + case SYMBOL_TLS_LE: case SYMBOL_TLSGD: case SYMBOL_TLSLDM: + case SYMBOL_PCREL: + /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */ + return sext_hwi (INTVAL (offset), 32) == INTVAL (offset); + + case SYMBOL_GOT_DISP: case SYMBOL_TLS: return false; } @@ -1707,9 +1701,14 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode) return 3; + case SYMBOL_PCREL: + case SYMBOL_TLS_IE: + case SYMBOL_TLS_LE: + return 2; + case SYMBOL_TLSGD: case SYMBOL_TLSLDM: - return 1; + return 3; case SYMBOL_TLS: /* We don't treat a bare TLS symbol as a constant. */ @@ -1937,11 +1936,7 @@ loongarch_address_insns (rtx x, machine_mode mode, bool might_split_p) switch (addr.type) { case ADDRESS_REG: - return factor; - case ADDRESS_REG_REG: - return factor; - case ADDRESS_CONST_INT: return factor; @@ -1983,7 +1978,7 @@ loongarch_12bit_offset_address_p (rtx x, machine_mode mode) return (loongarch_classify_address (&addr, x, mode, false) && addr.type == ADDRESS_REG && CONST_INT_P (addr.offset) - && LARCH_U12BIT_OFFSET_P (INTVAL (addr.offset))); + && LARCH_12BIT_OFFSET_P (INTVAL (addr.offset))); } /* Return true if X is a legitimate address with a 14-bit offset shifted 2. @@ -2001,6 +1996,9 @@ loongarch_14bit_shifted_offset_address_p (rtx x, machine_mode mode) && LARCH_SHIFT_2_OFFSET_P (INTVAL (addr.offset))); } +/* Return true if X is a legitimate address with base and index. + MODE is the mode of the value being accessed. */ + bool loongarch_base_index_address_p (rtx x, machine_mode mode) { @@ -2310,7 +2308,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return its address. The return value will be both a valid address and a valid - SET_SRC (either a REG or a LO_SUM). */ + SET_SRC. */ static rtx loongarch_legitimize_tls_address (rtx loc) @@ -2336,7 +2334,7 @@ loongarch_legitimize_tls_address (rtx loc) break; case TLS_MODEL_INITIAL_EXEC: - /* la.tls.ie; tp-relative add */ + /* la.tls.ie; tp-relative add. */ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); tmp = gen_reg_rtx (Pmode); emit_insn (loongarch_got_load_tls_ie (tmp, loc)); @@ -2345,7 +2343,7 @@ loongarch_legitimize_tls_address (rtx loc) break; case TLS_MODEL_LOCAL_EXEC: - /* la.tls.le; tp-relative add */ + /* la.tls.le; tp-relative add. */ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); tmp = gen_reg_rtx (Pmode); emit_insn (loongarch_got_load_tls_le (tmp, loc)); @@ -3371,6 +3369,7 @@ loongarch_output_move (rtx dest, rtx src) case 2: return "st.h\t%z1,%0"; case 4: + /* Matching address type with a 12bit offset. */ if (const_arith_operand (offset, Pmode)) return "st.w\t%z1,%0"; else @@ -3409,6 +3408,7 @@ loongarch_output_move (rtx dest, rtx src) case 2: return "ld.hu\t%0,%1"; case 4: + /* Matching address type with a 12bit offset. */ if (const_arith_operand (offset, Pmode)) return "ld.w\t%0,%1"; else @@ -3436,56 +3436,16 @@ loongarch_output_move (rtx dest, rtx src) else gcc_unreachable (); } + } - if (symbolic_operand (src, VOIDmode)) - { - if ((TARGET_CMODEL_TINY && (!loongarch_global_symbol_p (src) - || loongarch_symbol_binds_local_p (src))) - || (TARGET_CMODEL_TINY_STATIC && !loongarch_weak_symbol_p (src))) - { - /* The symbol must be aligned to 4 byte. */ - unsigned int align; - - if (LABEL_REF_P (src)) - align = 32 /* Whatever. */; - else if (CONSTANT_POOL_ADDRESS_P (src)) - align = GET_MODE_ALIGNMENT (get_pool_mode (src)); - else if (TREE_CONSTANT_POOL_ADDRESS_P (src)) - { - tree exp = SYMBOL_REF_DECL (src); - align = TYPE_ALIGN (TREE_TYPE (exp)); - align = loongarch_constant_alignment (exp, align); - } - else if (SYMBOL_REF_DECL (src)) - align = DECL_ALIGN (SYMBOL_REF_DECL (src)); - else if (SYMBOL_REF_HAS_BLOCK_INFO_P (src) - && SYMBOL_REF_BLOCK (src) != NULL) - align = SYMBOL_REF_BLOCK (src)->alignment; - else - align = BITS_PER_UNIT; - - if (align % (4 * 8) == 0) - return "pcaddi\t%0,%%pcrel(%1)>>2"; - } - if (TARGET_CMODEL_TINY - || TARGET_CMODEL_TINY_STATIC - || TARGET_CMODEL_NORMAL - || TARGET_CMODEL_LARGE) - { - if (!loongarch_global_symbol_p (src) - || loongarch_symbol_binds_local_p (src)) - return "la.local\t%0,%1"; - else - return "la.global\t%0,%1"; - } - if (TARGET_CMODEL_EXTREME) - { - sorry ("Normal symbol loading not implemented in extreme mode."); - gcc_unreachable (); - } - - } + if (dest_code == REG && symbolic_operand (src, VOIDmode)) + { + if (loongarch_classify_symbol (src) == SYMBOL_PCREL) + return "la.local\t%0,%1"; + else + return "la.global\t%0,%1"; } + if (src_code == REG && FP_REG_P (REGNO (src))) { if (dest_code == REG && FP_REG_P (REGNO (dest))) @@ -3503,6 +3463,7 @@ loongarch_output_move (rtx dest, rtx src) return dbl_p ? "fst.d\t%1,%0" : "fst.s\t%1,%0"; } } + if (dest_code == REG && FP_REG_P (REGNO (dest))) { if (src_code == MEM) @@ -3517,6 +3478,7 @@ loongarch_output_move (rtx dest, rtx src) return dbl_p ? "fld.d\t%0,%1" : "fld.s\t%0,%1"; } } + gcc_unreachable (); } @@ -4347,27 +4309,27 @@ loongarch_memmodel_needs_release_fence (enum memmodel model) /* Implement TARGET_PRINT_OPERAND. The LoongArch-specific operand codes are: - 'X' Print CONST_INT OP in hexadecimal format. - 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format. + 'A' Print a _DB suffix if the memory model requires a release. + 'b' Print the address of a memory operand, without offset. + 'C' Print the integer branch condition for comparison OP. 'd' Print CONST_INT OP in decimal. + 'F' Print the FPU branch condition for comparison OP. + 'G' Print a DBAR insn if the memory model requires a release. + 'i' Print i if the operand is not a register. 'm' Print one less than CONST_INT OP in decimal. - 'y' Print exact log2 of CONST_INT OP in decimal. - 'C' Print the integer branch condition for comparison OP. 'N' Print the inverse of the integer branch condition for comparison OP. - 'F' Print the FPU branch condition for comparison OP. - 'W' Print the inverse of the FPU branch condition for comparison OP. 'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...), 'z' for (eq:?I ...), 'n' for (ne:?I ...). 't' Like 'T', but with the EQ/NE cases reversed - 'Y' Print loongarch_fp_conditions[INTVAL (OP)] - 'Z' Print OP and a comma for 8CC, otherwise print nothing. - 'z' Print $0 if OP is zero, otherwise print OP normally. - 'b' Print the address of a memory operand, without offset. 'V' Print exact log2 of CONST_INT OP element 0 of a replicated CONST_VECTOR in decimal. - 'A' Print a _DB suffix if the memory model requires a release. - 'G' Print a DBAR insn if the memory model requires a release. - 'i' Print i if the operand is not a register. */ + 'W' Print the inverse of the FPU branch condition for comparison OP. + 'X' Print CONST_INT OP in hexadecimal format. + 'x' Print the low 16 bits of CONST_INT OP in hexadecimal format. + 'Y' Print loongarch_fp_conditions[INTVAL (OP)] + 'y' Print exact log2 of CONST_INT OP in decimal. + 'Z' Print OP and a comma for 8CC, otherwise print nothing. + 'z' Print $0 if OP is zero, otherwise print OP normally. */ static void loongarch_print_operand (FILE *file, rtx op, int letter) @@ -4385,18 +4347,13 @@ loongarch_print_operand (FILE *file, rtx op, int letter) switch (letter) { - case 'X': - if (CONST_INT_P (op)) - fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op)); - else - output_operand_lossage ("invalid use of '%%%c'", letter); + case 'A': + if (loongarch_memmodel_needs_rel_acq_fence ((enum memmodel) INTVAL (op))) + fputs ("_db", file); break; - case 'x': - if (CONST_INT_P (op)) - fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op) & 0xffff); - else - output_operand_lossage ("invalid use of '%%%c'", letter); + case 'C': + loongarch_print_int_branch_condition (file, code, letter); break; case 'd': @@ -4406,6 +4363,20 @@ loongarch_print_operand (FILE *file, rtx op, int letter) output_operand_lossage ("invalid use of '%%%c'", letter); break; + case 'F': + loongarch_print_float_branch_condition (file, code, letter); + break; + + case 'G': + if (loongarch_memmodel_needs_release_fence ((enum memmodel) INTVAL (op))) + fputs ("dbar\t0", file); + break; + + case 'i': + if (code != REG) + fputs ("i", file); + break; + case 'm': if (CONST_INT_P (op)) fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1); @@ -4413,17 +4384,17 @@ loongarch_print_operand (FILE *file, rtx op, int letter) output_operand_lossage ("invalid use of '%%%c'", letter); break; - case 'y': - if (CONST_INT_P (op)) - { - int val = exact_log2 (INTVAL (op)); - if (val != -1) - fprintf (file, "%d", val); - else - output_operand_lossage ("invalid use of '%%%c'", letter); - } - else - output_operand_lossage ("invalid use of '%%%c'", letter); + case 'N': + loongarch_print_int_branch_condition (file, reverse_condition (code), + letter); + break; + + case 't': + case 'T': + { + int truth = (code == NE) == (letter == 'T'); + fputc ("zfnt"[truth * 2 + FCC_REG_P (REGNO (XEXP (op, 0)))], file); + } break; case 'V': @@ -4441,30 +4412,36 @@ loongarch_print_operand (FILE *file, rtx op, int letter) output_operand_lossage ("invalid use of '%%%c'", letter); break; - case 'C': - loongarch_print_int_branch_condition (file, code, letter); - break; - - case 'N': - loongarch_print_int_branch_condition (file, reverse_condition (code), - letter); + case 'W': + loongarch_print_float_branch_condition (file, reverse_condition (code), + letter); break; - case 'F': - loongarch_print_float_branch_condition (file, code, letter); + case 'x': + if (CONST_INT_P (op)) + fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op) & 0xffff); + else + output_operand_lossage ("invalid use of '%%%c'", letter); break; - case 'W': - loongarch_print_float_branch_condition (file, reverse_condition (code), - letter); + case 'X': + if (CONST_INT_P (op)) + fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op)); + else + output_operand_lossage ("invalid use of '%%%c'", letter); break; - case 'T': - case 't': - { - int truth = (code == NE) == (letter == 'T'); - fputc ("zfnt"[truth * 2 + FCC_REG_P (REGNO (XEXP (op, 0)))], file); - } + case 'y': + if (CONST_INT_P (op)) + { + int val = exact_log2 (INTVAL (op)); + if (val != -1) + fprintf (file, "%d", val); + else + output_operand_lossage ("invalid use of '%%%c'", letter); + } + else + output_operand_lossage ("invalid use of '%%%c'", letter); break; case 'Y': @@ -4481,21 +4458,6 @@ loongarch_print_operand (FILE *file, rtx op, int letter) fputc (',', file); break; - case 'A': - if (loongarch_memmodel_needs_rel_acq_fence ((enum memmodel) INTVAL (op))) - fputs ("_db", file); - break; - - case 'G': - if (loongarch_memmodel_needs_release_fence ((enum memmodel) INTVAL (op))) - fputs ("dbar\t0", file); - break; - - case 'i': - if (code != REG) - fputs ("i", file); - break; - default: switch (code) { diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index f9de9a6e4fb..89a5bd728fe 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -614,7 +614,7 @@ enum reg_class #define LU12I_INT(X) LU12I_OPERAND (INTVAL (X)) #define LU32I_INT(X) LU32I_OPERAND (INTVAL (X)) #define LU52I_INT(X) LU52I_OPERAND (INTVAL (X)) -#define LARCH_U12BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -2048, 2047)) +#define LARCH_12BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -2048, 2047)) #define LARCH_9BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -256, 255)) #define LARCH_16BIT_OFFSET_P(OFFSET) (IN_RANGE (OFFSET, -32768, 32767)) #define LARCH_SHIFT_2_OFFSET_P(OFFSET) (((OFFSET) & 0x3) == 0) diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 5c0445dd879..376879fbccb 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -2844,48 +2844,14 @@ (define_expand "sibcall" }) (define_insn "sibcall_internal" - [(call (mem:SI (match_operand 0 "call_insn_operand" "j,c,a,t,h")) + [(call (mem:SI (match_operand 0 "call_insn_operand" "j,c,b")) (match_operand 1 "" ""))] "SIBLING_CALL_P (insn)" -{ - switch (which_alternative) - { - case 0: - return "jr\t%0"; - case 1: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r12,(%%pcrel(%0+0x20000))>>18\n\t" - "jirl\t$r0,$r12,%%pcrel(%0+4)-(%%pcrel(%0+4+0x20000)>>18<<18)"; - else if (TARGET_CMODEL_EXTREME) - return "la.local\t$r12,$r13,%0\n\tjr\t$r12"; - else - return "b\t%0"; - case 2: - if (TARGET_CMODEL_TINY_STATIC) - return "b\t%0"; - else if (TARGET_CMODEL_EXTREME) - return "la.global\t$r12,$r13,%0\n\tjr\t$r12"; - else - return "la.global\t$r12,%0\n\tjr\t$r12"; - case 3: - if (TARGET_CMODEL_EXTREME) - return "la.global\t$r12,$r13,%0\n\tjr\t$r12"; - else - return "la.global\t$r12,%0\n\tjr\t$r12"; - case 4: - if (TARGET_CMODEL_NORMAL || TARGET_CMODEL_TINY) - return "b\t%%plt(%0)"; - else if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r12,(%%plt(%0)+0x20000)>>18\n\t" - "jirl\t$r0,$r12,%%plt(%0)+4-((%%plt(%0)+(4+0x20000))>>18<<18)"; - else - /* Cmodel extreme and tiny static not support plt. */ - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - [(set_attr "jirl" "indirect,direct,direct,direct,direct")]) + "@ + jr\t%0 + b\t%0 + b\t%%plt(%0)" + [(set_attr "jirl" "indirect,direct,direct")]) (define_expand "sibcall_value" [(parallel [(set (match_operand 0 "") @@ -2920,96 +2886,28 @@ (define_expand "sibcall_value" (define_insn "sibcall_value_internal" [(set (match_operand 0 "register_operand" "") - (call (mem:SI (match_operand 1 "call_insn_operand" "j,c,a,t,h")) + (call (mem:SI (match_operand 1 "call_insn_operand" "j,c,b")) (match_operand 2 "" "")))] "SIBLING_CALL_P (insn)" -{ - switch (which_alternative) - { - case 0: - return "jr\t%1"; - case 1: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r12,%%pcrel(%1+0x20000)>>18\n\t" - "jirl\t$r0,$r12,%%pcrel(%1+4)-((%%pcrel(%1+4+0x20000))>>18<<18)"; - else if (TARGET_CMODEL_EXTREME) - return "la.local\t$r12,$r13,%1\n\tjr\t$r12"; - else - return "b\t%1"; - case 2: - if (TARGET_CMODEL_TINY_STATIC) - return "b\t%1"; - else if (TARGET_CMODEL_EXTREME) - return "la.global\t$r12,$r13,%1\n\tjr\t$r12"; - else - return "la.global\t$r12,%1\n\tjr\t$r12"; - case 3: - if (TARGET_CMODEL_EXTREME) - return "la.global\t$r12,$r13,%1\n\tjr\t$r12"; - else - return "la.global\t$r12,%1\n\tjr\t$r12"; - case 4: - if (TARGET_CMODEL_NORMAL || TARGET_CMODEL_TINY) - return " b\t%%plt(%1)"; - else if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r12,(%%plt(%1)+0x20000)>>18\n\t" - "jirl\t$r0,$r12,%%plt(%1)+4-((%%plt(%1)+(4+0x20000))>>18<<18)"; - else - /* Cmodel extreme and tiny static not support plt. */ - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - [(set_attr "jirl" "indirect,direct,direct,direct,direct")]) + "@ + jr\t%1 + b\t%1 + b\t%%plt(%1)" + [(set_attr "jirl" "indirect,direct,direct")]) (define_insn "sibcall_value_multiple_internal" [(set (match_operand 0 "register_operand" "") - (call (mem:SI (match_operand 1 "call_insn_operand" "j,c,a,t,h")) + (call (mem:SI (match_operand 1 "call_insn_operand" "j,c,b")) (match_operand 2 "" ""))) (set (match_operand 3 "register_operand" "") (call (mem:SI (match_dup 1)) (match_dup 2)))] "SIBLING_CALL_P (insn)" -{ - switch (which_alternative) - { - case 0: - return "jr\t%1"; - case 1: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r12,%%pcrel(%1+0x20000)>>18\n\t" - "jirl\t$r0,$r12,%%pcrel(%1+4)-(%%pcrel(%1+4+0x20000)>>18<<18)"; - else if (TARGET_CMODEL_EXTREME) - return "la.local\t$r12,$r13,%1\n\tjr\t$r12"; - else - return "b\t%1"; - case 2: - if (TARGET_CMODEL_TINY_STATIC) - return "b\t%1"; - else if (TARGET_CMODEL_EXTREME) - return "la.global\t$r12,$r13,%1\n\tjr\t$r12"; - else - return "la.global\t$r12,%1\n\tjr\t$r12"; - case 3: - if (TARGET_CMODEL_EXTREME) - return "la.global\t$r12,$r13,%1\n\tjr\t$r12"; - else - return "la.global\t$r12,%1\n\tjr\t$r12"; - case 4: - if (TARGET_CMODEL_NORMAL || TARGET_CMODEL_TINY) - return "b\t%%plt(%1)"; - else if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r12,(%%plt(%1)+0x20000)>>18\n\t" - "jirl\t$r0,$r12,%%plt(%1)+4-((%%plt(%1)+(4+0x20000))>>18<<18)"; - else - /* Cmodel extreme and tiny static not support plt. */ - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - [(set_attr "jirl" "indirect,direct,direct,direct,direct")]) + "@ + jr\t%1 + b\t%1 + b\t%%plt(%1)" + [(set_attr "jirl" "indirect,direct,direct")]) (define_expand "call" [(parallel [(call (match_operand 0 "") @@ -3025,50 +2923,15 @@ (define_expand "call" }) (define_insn "call_internal" - [(call (mem:SI (match_operand 0 "call_insn_operand" "e,c,a,t,h")) + [(call (mem:SI (match_operand 0 "call_insn_operand" "e,c,b")) (match_operand 1 "" "")) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" -{ - switch (which_alternative) - { - case 0: - return "jirl\t$r1,%0,0"; - case 1: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r1,%%pcrel(%0+0x20000)>>18\n\t" - "jirl\t$r1,$r1,%%pcrel(%0+4)-(%%pcrel(%0+4+0x20000)>>18<<18)"; - else if (TARGET_CMODEL_EXTREME) - return "la.local\t$r1,$r12,%0\n\tjirl\t$r1,$r1,0"; - else - return "bl\t%0"; - case 2: - if (TARGET_CMODEL_TINY_STATIC) - return "bl\t%0"; - else if (TARGET_CMODEL_EXTREME) - return "la.global\t$r1,$r12,%0\n\tjirl\t$r1,$r1,0"; - else - return "la.global\t$r1,%0\n\tjirl\t$r1,$r1,0"; - case 3: - if (TARGET_CMODEL_EXTREME) - return "la.global\t$r1,$r12,%0\n\tjirl\t$r1,$r1,0"; - else - return "la.global\t$r1,%0\n\tjirl\t$r1,$r1,0"; - case 4: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r1,(%%plt(%0)+0x20000)>>18\n\t" - "jirl\t$r1,$r1,%%plt(%0)+4-((%%plt(%0)+(4+0x20000))>>18<<18)"; - else if (TARGET_CMODEL_NORMAL || TARGET_CMODEL_TINY) - return "bl\t%%plt(%0)"; - else - /* Cmodel extreme and tiny static not support plt. */ - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - [(set_attr "jirl" "indirect,direct,direct,direct,direct") - (set_attr "insn_count" "1,2,3,3,2")]) + "@ + jirl\t$r1,%0,0 + bl\t%0 + bl\t%%plt(%0)" + [(set_attr "jirl" "indirect,direct,direct")]) (define_expand "call_value" [(parallel [(set (match_operand 0 "") @@ -3101,100 +2964,30 @@ (define_expand "call_value" (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "") - (call (mem:SI (match_operand 1 "call_insn_operand" "e,c,a,t,h")) + (call (mem:SI (match_operand 1 "call_insn_operand" "e,c,b")) (match_operand 2 "" ""))) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" -{ - switch (which_alternative) - { - case 0: - return "jirl\t$r1,%1,0"; - case 1: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r1,%%pcrel(%1+0x20000)>>18\n\t" - "jirl\t$r1,$r1,%%pcrel(%1+4)-(%%pcrel(%1+4+0x20000)>>18<<18)"; - else if (TARGET_CMODEL_EXTREME) - return "la.local\t$r1,$r12,%1\n\tjirl\t$r1,$r1,0"; - else - return "bl\t%1"; - case 2: - if (TARGET_CMODEL_TINY_STATIC) - return "bl\t%1"; - else if (TARGET_CMODEL_EXTREME) - return "la.global\t$r1,$r12,%1\n\tjirl\t$r1,$r1,0"; - else - return "la.global\t$r1,%1\n\tjirl\t$r1,$r1,0"; - case 3: - if (TARGET_CMODEL_EXTREME) - return "la.global\t$r1,$r12,%1\n\tjirl\t$r1,$r1,0"; - else - return "la.global\t$r1,%1\n\tjirl\t$r1,$r1,0"; - case 4: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r1,(%%plt(%1)+0x20000)>>18\n\t" - "jirl\t$r1,$r1,%%plt(%1)+4-((%%plt(%1)+(4+0x20000))>>18<<18)"; - else if (TARGET_CMODEL_NORMAL || TARGET_CMODEL_TINY) - return "bl\t%%plt(%1)"; - else - /* Cmodel extreme and tiny static not support plt. */ - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - [(set_attr "jirl" "indirect,direct,direct,direct,direct") - (set_attr "insn_count" "1,2,3,3,2")]) + "@ + jirl\t$r1,%1,0 + bl\t%1 + bl\t%%plt(%1)" + [(set_attr "jirl" "indirect,direct,direct")]) (define_insn "call_value_multiple_internal" [(set (match_operand 0 "register_operand" "") - (call (mem:SI (match_operand 1 "call_insn_operand" "e,c,a,t,h")) + (call (mem:SI (match_operand 1 "call_insn_operand" "e,c,b")) (match_operand 2 "" ""))) (set (match_operand 3 "register_operand" "") (call (mem:SI (match_dup 1)) (match_dup 2))) (clobber (reg:SI RETURN_ADDR_REGNUM))] "" -{ - switch (which_alternative) - { - case 0: - return "jirl\t$r1,%1,0"; - case 1: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r1,%%pcrel(%1+0x20000)>>18\n\t" - "jirl\t$r1,$r1,%%pcrel(%1+4)-(%%pcrel(%1+4+0x20000)>>18<<18)"; - else if (TARGET_CMODEL_EXTREME) - return "la.local\t$r1,$r12,%1\n\tjirl\t$r1,$r1,0"; - else - return "bl\t%1"; - case 2: - if (TARGET_CMODEL_TINY_STATIC) - return "bl\t%1"; - else if (TARGET_CMODEL_EXTREME) - return "la.global\t$r1,$r12,%1\n\tjirl\t$r1,$r1,0 "; - else - return "la.global\t$r1,%1\n\tjirl\t$r1,$r1,0"; - case 3: - if (TARGET_CMODEL_EXTREME) - return "la.global\t$r1,$r12,%1\n\tjirl\t$r1,$r1,0"; - else - return "la.global\t$r1,%1\n\tjirl\t$r1,$r1,0"; - case 4: - if (TARGET_CMODEL_LARGE) - return "pcaddu18i\t$r1,(%%plt(%1)+0x20000)>>18\n\t" - "jirl\t$r1,$r1,%%plt(%1)+4-((%%plt(%1)+(4+0x20000))>>18<<18)"; - else if (TARGET_CMODEL_NORMAL || TARGET_CMODEL_TINY) - return "bl\t%%plt(%1)"; - else - /* Cmodel extreme and tiny static not support plt. */ - gcc_unreachable (); - default: - gcc_unreachable (); - } -} - [(set_attr "jirl" "indirect,direct,direct,direct,direct") - (set_attr "insn_count" "1,2,3,3,2")]) + "@ + jirl\t$r1,%1,0 + bl\t%1 + bl\t%%plt(%1)" + [(set_attr "jirl" "indirect,direct,direct")]) ;; Call subroutine returning any type. diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md index edd74d4783d..2243ef71c1a 100644 --- a/gcc/config/loongarch/predicates.md +++ b/gcc/config/loongarch/predicates.md @@ -111,20 +111,25 @@ (define_predicate "const_call_insn_operand" (match_code "const,symbol_ref,label_ref") { enum loongarch_symbol_type symbol_type; + loongarch_symbolic_constant_p (op, &symbol_type); - if (!loongarch_symbolic_constant_p (op, &symbol_type)) + rtx offset, x = op; + split_const (x, &x, &offset); + + if (offset != const0_rtx) return false; switch (symbol_type) { - case SYMBOL_GOT_DISP: - /* Without explicit relocs, there is no special syntax for - loading the address of a call destination into a register. - Using "la.global JIRL_REGS,foo; jirl JIRL_REGS" would prevent the lazy - binding of "foo", so keep the address of global symbols with the jirl - macro. */ + case SYMBOL_PCREL: return 1; + case SYMBOL_GOT_DISP: + if (!flag_plt) + return false; + else + return 1; + default: return false; } @@ -140,22 +145,11 @@ (define_predicate "is_const_call_local_symbol" (match_test "loongarch_symbol_binds_local_p (op) != 0")) (match_test "CONSTANT_P (op)"))) -(define_predicate "is_const_call_weak_symbol" - (and (match_operand 0 "const_call_insn_operand") - (not (match_operand 0 "is_const_call_local_symbol")) - (match_test "loongarch_weak_symbol_p (op) != 0") - (match_test "CONSTANT_P (op)"))) - -(define_predicate "is_const_call_plt_symbol" - (and (match_operand 0 "const_call_insn_operand") - (match_test "flag_plt != 0") - (match_test "loongarch_global_symbol_noweak_p (op) != 0") - (match_test "CONSTANT_P (op)"))) - -(define_predicate "is_const_call_global_noplt_symbol" +(define_predicate "is_const_call_no_local_symbol" (and (match_operand 0 "const_call_insn_operand") - (match_test "flag_plt == 0") - (match_test "loongarch_global_symbol_noweak_p (op) != 0") + (ior (match_test "loongarch_global_symbol_p (op) != 0") + (match_test "loongarch_symbol_binds_local_p (op) == 0") + (match_test "loongarch_weak_symbol_p (op) != 0")) (match_test "CONSTANT_P (op)"))) ;; A legitimate CONST_INT operand that takes more than one instruction @@ -219,7 +213,7 @@ (define_predicate "move_operand" case CONST: case SYMBOL_REF: case LABEL_REF: - return (loongarch_symbolic_constant_p (op, &symbol_type)); + return loongarch_symbolic_constant_p (op, &symbol_type); default: return true; } diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-1.c new file mode 100644 index 00000000000..b0482761aab --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-2.c b/gcc/testsuite/gcc.target/loongarch/func-call-2.c new file mode 100644 index 00000000000..f5e061c299c --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-2.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-3.c b/gcc/testsuite/gcc.target/loongarch/func-call-3.c new file mode 100644 index 00000000000..75082c57466 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-3.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt" } */ +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-4.c b/gcc/testsuite/gcc.target/loongarch/func-call-4.c new file mode 100644 index 00000000000..e8a8395493e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-4.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt" } */ +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} From patchwork Thu Jul 21 06:41:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenglulu X-Patchwork-Id: 94 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e252:0:0:0:0:0 with SMTP id bl18csp1302599wrb; Wed, 20 Jul 2022 23:45:50 -0700 (PDT) X-Google-Smtp-Source: AGRyM1v0X87SxNeKOo3cHc9gAdUAOlG6WNT2dkyyWtmsyD/tV658VgmmTdHBJ2VV/SSLYYewzhof X-Received: by 2002:a05:6402:348c:b0:43a:915f:d403 with SMTP id v12-20020a056402348c00b0043a915fd403mr54202276edc.326.1658385950494; Wed, 20 Jul 2022 23:45:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658385950; cv=none; d=google.com; s=arc-20160816; b=Q+si7AOLEps0tL636XDczkl8iWa+7QGEnYTvBHwW8nUSl8ylnxVcbdsrEwhNtEWDv7 bIMrQqgJTnU9HwGwnDqfGjX+kYw9yxQfNzBzjJg3ZMTWnyrEY3zGGRFPPWNM2a1IPCHD TkSik78xdeSo8L1K8cbcWK/reJKN8wYOksiMh++ojIK54oalnnKVjzXb/YMyAd0zRqki G3dUfS7SMI+aVe3twJiIWS3GF1N13EVt3AiAtl/miOaEjLiDxZHmhZ11sVLphKEiIX+3 WUCz0zz+z46vmWXoHIHXfRBG46T1n+rczTuw0CwNntjzMZE3EBv4Z7z856Ri+0FYUnoG 4jlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dmarc-filter:delivered-to; bh=iOyuI6PGZaaMWEFqJg5aCS+SoZDizTMCt1TXnudO2nI=; b=qHk0Gre7XFccZ9TxR5SxT/jnjMO8jYWV90G645ba/91fn8FuuTzNtV0PUEiQZJyvrr j3Z97YU32akyzrJVhjwSlSDx9d0RP5HOq70MOI1D6q9ZEcF+tZoYIJcvM4X01hr06I8K BaeMOTWqEqaVBDOAzndTYnR197BcDydljayeOTRJtg4GhJ2IIYcVYkw+/ViVypKTq3Rj C5hGZDA25EXdcmiwQJdczYEBkG58vaQW8qTA9nver2VYyWRBaZwWMPllyLbPox2MLWXC w/bcguRf7QIgFOk3OlOXIw+7aduVmuM+tc+q8kRDBwdJuV7m3YYPm5X86ux4DGnQpJTD 3h8w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id gb25-20020a170907961900b0072a7a097e3csi1864624ejc.464.2022.07.20.23.45.50 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jul 2022 23:45:50 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1389A385BAD3 for ; Thu, 21 Jul 2022 06:44:21 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id CE0713857B8D for ; Thu, 21 Jul 2022 06:43:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CE0713857B8D Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from 5.5.5 (unknown [10.2.5.5]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxf9N+9dhiwgssAA--.40495S4; Thu, 21 Jul 2022 14:43:18 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Subject: [PATCH v2 2/3] LoongArch: Support split symbol. Date: Thu, 21 Jul 2022 14:41:22 +0800 Message-Id: <20220721064123.2981805-3-chenglulu@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220721064123.2981805-1-chenglulu@loongson.cn> References: <20220721064123.2981805-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dxf9N+9dhiwgssAA--.40495S4 X-Coremail-Antispam: 1UD129KBjvAXoWDJF4rXr4UWw4xCFykAryDAwb_yoWrWw1rJo WrAFWkWw18Gr1Ykws7KrnxW34vqF1vyrWxAa9Ivw1rCa1xAryDAry3Ka15Z3sxJryDXry5 Aa4xua9rArW7XFn5n29KB7ZKAUJUUUU5529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYA7AC8VAFwI0_Xr0_Wr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l82xGYIkIc2x26280x7IE14v26r15M28IrcIa0x kI8VCY1x0267AKxVWUCVW8JwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK021l84AC jcxK6xIIjxv20xvE14v26F1j6w1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26F4j6r4UJw A2z4x0Y4vEx4A2jsIE14v26F4UJVW0owA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_GcCE3s1l e2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E2Ix0cI 8IcVAFwI0_Jrv_JF1lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbVWUJVW8JwAC jcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc2xSY4AK6svPMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aV CY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7VUbwZ23UUUUU== X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-12.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: xuchenghua@loongson.cn, Lulu Cheng , i@xen0n.name Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738943706247242021?= X-GMAIL-MSGID: =?utf-8?q?1738943706247242021?= Add compilation option '-mexplicit-relocs', and if enable '-mexplicit-relocs' the symbolic address load instruction 'la.*' will be split into two instructions. This ckompilation option enabled by default. gcc/ChangeLog: * common/config/loongarch/loongarch-common.cc: Enable '-fsection-anchors' when O1 and more advanced optimization. * config/loongarch/genopts/loongarch.opt.in: Add new option '-mexplicit-relocs', and enable by default. * config/loongarch/loongarch-protos.h (loongarch_split_move_insn_p): Delete function declaration. (loongarch_split_move_insn): Delete function declaration. (loongarch_split_symbol_type): Add function declaration. * config/loongarch/loongarch.cc (enum loongarch_address_type): Add new address type 'ADDRESS_LO_SUM'. (loongarch_classify_symbolic_expression): New function definitions. Classify the base of symbolic expression X, given that X appears in context CONTEXT. (loongarch_symbol_insns): Add a judgment condition TARGET_EXPLICIT_RELOCS. (loongarch_split_symbol_type): New function definitions. Determines whether the symbol load should be split into two instructions. (loongarch_valid_lo_sum_p): New function definitions. Return true if a LO_SUM can address a value of mode MODE when the LO_SUM symbol has type SYMBOL_TYPE. (loongarch_classify_address): Add handling of 'LO_SUM'. (loongarch_address_insns): Add handling of 'ADDRESS_LO_SUM'. (loongarch_signed_immediate_p): Sort code. (loongarch_12bit_offset_address_p): Return true if address type is ADDRESS_LO_SUM. (loongarch_const_insns): Add handling of 'HIGH'. (loongarch_split_move_insn_p): Add the static attribute to the function. (loongarch_emit_set): New function definitions. (loongarch_call_tls_get_addr): Add symbol handling when defining TARGET_EXPLICIT_RELOCS. (loongarch_legitimize_tls_address): Add symbol handling when defining the TARGET_EXPLICIT_RELOCS macro. (loongarch_split_symbol): New function definitions. Split symbol. (loongarch_legitimize_address): Add codes see if the address can split into a high part and a LO_SUM. (loongarch_legitimize_const_move): Add codes split moves of symbolic constants into high and low. (loongarch_split_move_insn): Delete function definitions. (loongarch_output_move): Add support for HIGH and LO_SUM. (loongarch_print_operand_reloc): New function definitions. Print symbolic operand OP, which is part of a HIGH or LO_SUM in context CONTEXT. (loongarch_memmodel_needs_release_fence): Sort code. (loongarch_print_operand): Rearrange alphabetical order and add H and L to support HIGH and LOW output. (loongarch_print_operand_address): Add handling of 'ADDRESS_LO_SUM'. (TARGET_MIN_ANCHOR_OFFSET): Define macro to -IMM_REACH/2. (TARGET_MAX_ANCHOR_OFFSET): Define macro to IMM_REACH/2-1. * config/loongarch/loongarch.md (movti): Delete the template. (*movti): Delete the template. (movtf): Delete the template. (*movtf): Delete the template. (*low): New template of normal symbol low address. (@tls_low): New template of tls symbol low address. (@ld_from_got): New template load address from got table. (@ori_l_lo12): New template. * config/loongarch/loongarch.opt: Update from loongarch.opt.in. * config/loongarch/predicates.md: Add support for symbol_type HIGH. gcc/testsuite/ChangeLog: * gcc.target/loongarch/func-call-1.c: Add build option '-mno-explicit-relocs'. * gcc.target/loongarch/func-call-2.c: Add build option '-mno-explicit-relocs'. * gcc.target/loongarch/func-call-3.c: Add build option '-mno-explicit-relocs'. * gcc.target/loongarch/func-call-4.c: Add build option '-mno-explicit-relocs'. * gcc.target/loongarch/func-call-5.c: New test. * gcc.target/loongarch/func-call-6.c: New test. * gcc.target/loongarch/func-call-7.c: New test. * gcc.target/loongarch/func-call-8.c: New test. * gcc.target/loongarch/relocs-symbol-noaddend.c: New test. --- .../config/loongarch/loongarch-common.cc | 1 + gcc/config/loongarch/genopts/loongarch.opt.in | 4 + gcc/config/loongarch/loongarch-protos.h | 3 +- gcc/config/loongarch/loongarch.cc | 412 ++++++++++++++++-- gcc/config/loongarch/loongarch.md | 122 +++--- gcc/config/loongarch/loongarch.opt | 4 + gcc/config/loongarch/predicates.md | 20 +- .../gcc.target/loongarch/func-call-1.c | 2 +- .../gcc.target/loongarch/func-call-2.c | 2 +- .../gcc.target/loongarch/func-call-3.c | 2 +- .../gcc.target/loongarch/func-call-4.c | 2 +- .../gcc.target/loongarch/func-call-5.c | 33 ++ .../gcc.target/loongarch/func-call-6.c | 33 ++ .../gcc.target/loongarch/func-call-7.c | 34 ++ .../gcc.target/loongarch/func-call-8.c | 33 ++ .../loongarch/relocs-symbol-noaddend.c | 23 + 16 files changed, 614 insertions(+), 116 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-5.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-6.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-7.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-8.c create mode 100644 gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c diff --git a/gcc/common/config/loongarch/loongarch-common.cc b/gcc/common/config/loongarch/loongarch-common.cc index ed3730fce8b..f8b4660fabf 100644 --- a/gcc/common/config/loongarch/loongarch-common.cc +++ b/gcc/common/config/loongarch/loongarch-common.cc @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3. If not see static const struct default_options loongarch_option_optimization_table[] = { { OPT_LEVELS_ALL, OPT_fasynchronous_unwind_tables, NULL, 1 }, + { OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 }, { OPT_LEVELS_NONE, 0, NULL, 0 } }; diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in index 61e7d72a0a1..6f39500935d 100644 --- a/gcc/config/loongarch/genopts/loongarch.opt.in +++ b/gcc/config/loongarch/genopts/loongarch.opt.in @@ -154,6 +154,10 @@ mmax-inline-memcpy-size= Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024) -mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024. +mexplicit-relocs +Target Var(TARGET_EXPLICIT_RELOCS) Init(1) +Use %reloc() assembly operators. + ; The code model option names for -mcmodel. Enum Name(cmodel) Type(int) diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index 080766250d1..cadaad7519c 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -77,8 +77,6 @@ extern rtx loongarch_legitimize_call_address (rtx); extern rtx loongarch_subword (rtx, bool); extern bool loongarch_split_move_p (rtx, rtx); extern void loongarch_split_move (rtx, rtx, rtx); -extern bool loongarch_split_move_insn_p (rtx, rtx); -extern void loongarch_split_move_insn (rtx, rtx, rtx); extern const char *loongarch_output_move (rtx, rtx); extern bool loongarch_cfun_has_cprestore_slot_p (void); #ifdef RTX_CODE @@ -160,6 +158,7 @@ extern rtx loongarch_expand_thread_pointer (rtx); extern bool loongarch_eh_uses (unsigned int); extern bool loongarch_epilogue_uses (unsigned int); extern bool loongarch_load_store_bonding_p (rtx *, machine_mode, bool); +extern bool loongarch_split_symbol_type (enum loongarch_symbol_type); typedef rtx (*mulsidi3_gen_fn) (rtx, rtx, rtx); diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 1cb5742f6dd..79687340dfd 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -100,6 +100,10 @@ along with GCC; see the file COPYING3. If not see ADDRESS_REG_REG A base register indexed by (optionally scaled) register. + ADDRESS_LO_SUM + A LO_SUM rtx. The first operand is a valid base register and the second + operand is a symbolic address. + ADDRESS_CONST_INT A signed 16-bit constant address. @@ -109,6 +113,7 @@ enum loongarch_address_type { ADDRESS_REG, ADDRESS_REG_REG, + ADDRESS_LO_SUM, ADDRESS_CONST_INT, ADDRESS_SYMBOLIC }; @@ -1641,6 +1646,21 @@ loongarch_classify_symbol (const_rtx x) return SYMBOL_PCREL; } +/* Classify the base of symbolic expression X, given that X appears in + context CONTEXT. */ + +static enum loongarch_symbol_type +loongarch_classify_symbolic_expression (rtx x) +{ + rtx offset; + + split_const (x, &x, &offset); + if (UNSPEC_ADDRESS_P (x)) + return UNSPEC_ADDRESS_TYPE (x); + + return loongarch_classify_symbol (x); +} + /* Return true if X is a symbolic constant. If it is, store the type of the symbol in *SYMBOL_TYPE. */ @@ -1696,7 +1716,7 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode) case SYMBOL_GOT_DISP: /* The constant will have to be loaded from the GOT before it is used in an address. */ - if (mode != MAX_MACHINE_MODE) + if (!TARGET_EXPLICIT_RELOCS && mode != MAX_MACHINE_MODE) return 0; return 3; @@ -1814,6 +1834,84 @@ loongarch_valid_offset_p (rtx x, machine_mode mode) return true; } +/* Should a symbol of type SYMBOL_TYPE should be split in two? */ + +bool +loongarch_split_symbol_type (enum loongarch_symbol_type symbol_type) +{ + switch (symbol_type) + { + case SYMBOL_PCREL: + case SYMBOL_GOT_DISP: + case SYMBOL_TLS_IE: + case SYMBOL_TLS_LE: + case SYMBOL_TLSGD: + case SYMBOL_TLSLDM: + return true; + + case SYMBOL_TLS: + return false; + + default: + gcc_unreachable (); + } +} + +/* Return true if a LO_SUM can address a value of mode MODE when the + LO_SUM symbol has type SYMBOL_TYPE. */ + +static bool +loongarch_valid_lo_sum_p (enum loongarch_symbol_type symbol_type, + machine_mode mode, rtx x) +{ + int align, size; + + /* Check that symbols of type SYMBOL_TYPE can be used to access values + of mode MODE. */ + if (loongarch_symbol_insns (symbol_type, mode) == 0) + return false; + + /* Check that there is a known low-part relocation. */ + if (!loongarch_split_symbol_type (symbol_type)) + return false; + + /* We can't tell size or alignment when we have BLKmode, so try extracing a + decl from the symbol if possible. */ + if (mode == BLKmode) + { + rtx offset; + + /* Extract the symbol from the LO_SUM operand, if any. */ + split_const (x, &x, &offset); + + /* Might be a CODE_LABEL. We can compute align but not size for that, + so don't bother trying to handle it. */ + if (!SYMBOL_REF_P (x)) + return false; + + /* Use worst case assumptions if we don't have a SYMBOL_REF_DECL. */ + align = (SYMBOL_REF_DECL (x) + ? DECL_ALIGN (SYMBOL_REF_DECL (x)) + : 1); + size = (SYMBOL_REF_DECL (x) && DECL_SIZE (SYMBOL_REF_DECL (x)) + ? tree_to_uhwi (DECL_SIZE (SYMBOL_REF_DECL (x))) + : 2*BITS_PER_WORD); + } + else + { + align = GET_MODE_ALIGNMENT (mode); + size = GET_MODE_BITSIZE (mode); + } + + /* We may need to split multiword moves, so make sure that each word + can be accessed without inducing a carry. */ + if (size > BITS_PER_WORD + && (!TARGET_STRICT_ALIGN || size > align)) + return false; + + return true; +} + static bool loongarch_valid_index_p (struct loongarch_address_info *info, rtx x, machine_mode mode, bool strict_p) @@ -1880,6 +1978,26 @@ loongarch_classify_address (struct loongarch_address_info *info, rtx x, info->offset = XEXP (x, 1); return (loongarch_valid_base_register_p (info->reg, mode, strict_p) && loongarch_valid_offset_p (info->offset, mode)); + + case LO_SUM: + info->type = ADDRESS_LO_SUM; + info->reg = XEXP (x, 0); + info->offset = XEXP (x, 1); + /* We have to trust the creator of the LO_SUM to do something vaguely + sane. Target-independent code that creates a LO_SUM should also + create and verify the matching HIGH. Target-independent code that + adds an offset to a LO_SUM must prove that the offset will not + induce a carry. Failure to do either of these things would be + a bug, and we are not required to check for it here. The MIPS + backend itself should only create LO_SUMs for valid symbolic + constants, with the high part being either a HIGH or a copy + of _gp. */ + info->symbol_type + = loongarch_classify_symbolic_expression (info->offset); + return (loongarch_valid_base_register_p (info->reg, mode, strict_p) + && loongarch_valid_lo_sum_p (info->symbol_type, mode, + info->offset)); + default: return false; } @@ -1940,6 +2058,9 @@ loongarch_address_insns (rtx x, machine_mode mode, bool might_split_p) case ADDRESS_CONST_INT: return factor; + case ADDRESS_LO_SUM: + return factor + 1; + case ADDRESS_SYMBOLIC: return factor * loongarch_symbol_insns (addr.symbol_type, mode); } @@ -1967,7 +2088,8 @@ loongarch_signed_immediate_p (unsigned HOST_WIDE_INT x, int bits, return loongarch_unsigned_immediate_p (x, bits, shift); } -/* Return true if X is a legitimate address with a 12-bit offset. +/* Return true if X is a legitimate address with a 12-bit offset + or addr.type is ADDRESS_LO_SUM. MODE is the mode of the value being accessed. */ bool @@ -1976,9 +2098,10 @@ loongarch_12bit_offset_address_p (rtx x, machine_mode mode) struct loongarch_address_info addr; return (loongarch_classify_address (&addr, x, mode, false) - && addr.type == ADDRESS_REG - && CONST_INT_P (addr.offset) - && LARCH_12BIT_OFFSET_P (INTVAL (addr.offset))); + && ((addr.type == ADDRESS_REG + && CONST_INT_P (addr.offset) + && LARCH_12BIT_OFFSET_P (INTVAL (addr.offset))) + || addr.type == ADDRESS_LO_SUM)); } /* Return true if X is a legitimate address with a 14-bit offset shifted 2. @@ -2020,6 +2143,14 @@ loongarch_const_insns (rtx x) switch (GET_CODE (x)) { + case HIGH: + if (!loongarch_symbolic_constant_p (XEXP (x, 0), &symbol_type) + || !loongarch_split_symbol_type (symbol_type)) + return 0; + + /* This is simply a PCALAU12I. */ + return 1; + case CONST_INT: return loongarch_integer_cost (INTVAL (x)); @@ -2080,6 +2211,8 @@ loongarch_split_const_insns (rtx x) return low + high; } +static bool loongarch_split_move_insn_p (rtx dest, rtx src); + /* Return the number of instructions needed to implement INSN, given that it loads from or stores to MEM. */ @@ -2197,6 +2330,15 @@ loongarch_unspec_address (rtx address, enum loongarch_symbol_type symbol_type) return loongarch_unspec_address_offset (base, offset, symbol_type); } +/* Emit an instruction of the form (set TARGET SRC). */ + +static rtx +loongarch_emit_set (rtx target, rtx src) +{ + emit_insn (gen_rtx_SET (target, src)); + return target; +} + /* If OP is an UNSPEC address, return the address to which it refers, otherwise return OP itself. */ @@ -2278,6 +2420,7 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) { rtx loc, a0; rtx_insn *insn; + rtx tmp = gen_reg_rtx (Pmode); a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST); @@ -2288,12 +2431,22 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) start_sequence (); - if (type == SYMBOL_TLSLDM) - emit_insn (loongarch_got_load_tls_ld (a0, loc)); - else if (type == SYMBOL_TLSGD) - emit_insn (loongarch_got_load_tls_gd (a0, loc)); + if (TARGET_EXPLICIT_RELOCS) + { + /* Split tls symbol to high and low. */ + rtx high = gen_rtx_HIGH (Pmode, copy_rtx (loc)); + high = loongarch_force_temporary (tmp, high); + emit_insn (gen_tls_low (Pmode, a0, high, loc)); + } else - gcc_unreachable (); + { + if (type == SYMBOL_TLSLDM) + emit_insn (loongarch_got_load_tls_ld (a0, loc)); + else if (type == SYMBOL_TLSGD) + emit_insn (loongarch_got_load_tls_gd (a0, loc)); + else + gcc_unreachable (); + } insn = emit_call_insn (gen_call_value_internal (v0, loongarch_tls_symbol, const0_rtx)); @@ -2308,12 +2461,12 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) /* Generate the code to access LOC, a thread-local SYMBOL_REF, and return its address. The return value will be both a valid address and a valid - SET_SRC. */ + SET_SRC (either a REG or a LO_SUM). */ static rtx loongarch_legitimize_tls_address (rtx loc) { - rtx dest, tp, tmp; + rtx dest, tp, tmp, tmp1, tmp2, tmp3; enum tls_model model = SYMBOL_REF_TLS_MODEL (loc); rtx_insn *insn; @@ -2334,21 +2487,45 @@ loongarch_legitimize_tls_address (rtx loc) break; case TLS_MODEL_INITIAL_EXEC: - /* la.tls.ie; tp-relative add. */ - tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); - tmp = gen_reg_rtx (Pmode); - emit_insn (loongarch_got_load_tls_ie (tmp, loc)); - dest = gen_reg_rtx (Pmode); - emit_insn (gen_add3_insn (dest, tmp, tp)); + { + /* la.tls.ie; tp-relative add. */ + tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); + tmp1 = gen_reg_rtx (Pmode); + dest = gen_reg_rtx (Pmode); + if (TARGET_EXPLICIT_RELOCS) + { + tmp2 = loongarch_unspec_address (loc, SYMBOL_TLS_IE); + tmp3 = gen_reg_rtx (Pmode); + rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2)); + high = loongarch_force_temporary (tmp3, high); + emit_insn (gen_ld_from_got (Pmode, tmp1, high, tmp2)); + } + else + emit_insn (loongarch_got_load_tls_ie (tmp1, loc)); + emit_insn (gen_add3_insn (dest, tmp1, tp)); + } break; case TLS_MODEL_LOCAL_EXEC: - /* la.tls.le; tp-relative add. */ - tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); - tmp = gen_reg_rtx (Pmode); - emit_insn (loongarch_got_load_tls_le (tmp, loc)); - dest = gen_reg_rtx (Pmode); - emit_insn (gen_add3_insn (dest, tmp, tp)); + { + /* la.tls.le; tp-relative add. */ + tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); + tmp1 = gen_reg_rtx (Pmode); + dest = gen_reg_rtx (Pmode); + + if (TARGET_EXPLICIT_RELOCS) + { + tmp2 = loongarch_unspec_address (loc, SYMBOL_TLS_LE); + tmp3 = gen_reg_rtx (Pmode); + rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2)); + high = loongarch_force_temporary (tmp3, high); + emit_insn (gen_ori_l_lo12 (Pmode, tmp1, high, tmp2)); + } + else + emit_insn (loongarch_got_load_tls_le (tmp1, loc)); + emit_insn (gen_add3_insn (dest, tmp1, tp)); + + } break; default: @@ -2397,6 +2574,68 @@ loongarch_force_address (rtx x, machine_mode mode) return x; } +/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise + it appears in a MEM of that mode. Return true if ADDR is a legitimate + constant in that context and can be split into high and low parts. + If so, and if LOW_OUT is nonnull, emit the high part and store the + low part in *LOW_OUT. Leave *LOW_OUT unchanged otherwise. + + Return false if build with '-mno-explicit-relocs'. + + TEMP is as for loongarch_force_temporary and is used to load the high + part into a register. + + When MODE is MAX_MACHINE_MODE, the low part is guaranteed to be + a legitimize SET_SRC for an .md pattern, otherwise the low part + is guaranteed to be a legitimate address for mode MODE. */ + +bool +loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) +{ + enum loongarch_symbol_type symbol_type; + rtx high; + + /* If build with '-mno-explicit-relocs', don't split symbol. */ + if (!TARGET_EXPLICIT_RELOCS) + return false; + + if ((GET_CODE (addr) == HIGH && mode == MAX_MACHINE_MODE) + || !loongarch_symbolic_constant_p (addr, &symbol_type) + || loongarch_symbol_insns (symbol_type, mode) == 0 + || !loongarch_split_symbol_type (symbol_type)) + return false; + + if (temp == NULL) + temp = gen_reg_rtx (Pmode); + + /* Get the 12-31 bits of the address. */ + high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); + high = loongarch_force_temporary (temp, high); + + if (low_out) + switch (symbol_type) + { + case SYMBOL_PCREL: + *low_out = gen_rtx_LO_SUM (Pmode, high, addr); + break; + + case SYMBOL_GOT_DISP: + /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */ + { + rtx low = gen_rtx_LO_SUM (Pmode, high, addr); + rtx mem = gen_rtx_MEM (Pmode, low); + *low_out = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, mem), + UNSPEC_LOAD_FROM_GOT); + break; + } + + default: + gcc_unreachable (); + } + + return true; +} + /* This function is used to implement LEGITIMIZE_ADDRESS. If X can be legitimized in a way that the generic machinery might not expect, return a new address, otherwise return NULL. MODE is the mode of @@ -2412,6 +2651,10 @@ loongarch_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED, if (loongarch_tls_symbol_p (x)) return loongarch_legitimize_tls_address (x); + /* See if the address can split into a high part and a LO_SUM. */ + if (loongarch_split_symbol (NULL, x, mode, &addr)) + return loongarch_force_address (addr, mode); + /* Handle BASE + OFFSET using loongarch_add_offset. */ loongarch_split_plus (x, &base, &offset); if (offset != 0) @@ -2499,6 +2742,13 @@ loongarch_legitimize_const_move (machine_mode mode, rtx dest, rtx src) return; } + /* Split moves of symbolic constants into high and low. */ + if (loongarch_split_symbol (dest, src, MAX_MACHINE_MODE, &src)) + { + loongarch_emit_set (dest, src); + return; + } + /* Generate the appropriate access sequences for TLS symbols. */ if (loongarch_tls_symbol_p (src)) { @@ -3241,21 +3491,12 @@ loongarch_split_move (rtx dest, rtx src, rtx insn_) /* Return true if a move from SRC to DEST in INSN should be split. */ -bool +static bool loongarch_split_move_insn_p (rtx dest, rtx src) { return loongarch_split_move_p (dest, src); } -/* Split a move from SRC to DEST in INSN, given that - loongarch_split_move_insn_p holds. */ - -void -loongarch_split_move_insn (rtx dest, rtx src, rtx insn) -{ - loongarch_split_move (dest, src, insn); -} - /* Implement TARGET_CONSTANT_ALIGNMENT. */ static HOST_WIDE_INT @@ -3369,13 +3610,16 @@ loongarch_output_move (rtx dest, rtx src) case 2: return "st.h\t%z1,%0"; case 4: - /* Matching address type with a 12bit offset. */ - if (const_arith_operand (offset, Pmode)) + /* Matching address type with a 12bit offset and + ADDRESS_LO_SUM. */ + if (const_arith_operand (offset, Pmode) + || GET_CODE (offset) == LO_SUM) return "st.w\t%z1,%0"; else return "stptr.w\t%z1,%0"; case 8: - if (const_arith_operand (offset, Pmode)) + if (const_arith_operand (offset, Pmode) + || GET_CODE (offset) == LO_SUM) return "st.d\t%z1,%0"; else return "stptr.d\t%z1,%0"; @@ -3408,13 +3652,16 @@ loongarch_output_move (rtx dest, rtx src) case 2: return "ld.hu\t%0,%1"; case 4: - /* Matching address type with a 12bit offset. */ - if (const_arith_operand (offset, Pmode)) + /* Matching address type with a 12bit offset and + ADDRESS_LO_SUM. */ + if (const_arith_operand (offset, Pmode) + || GET_CODE (offset) == LO_SUM) return "ld.w\t%0,%1"; else return "ldptr.w\t%0,%1"; case 8: - if (const_arith_operand (offset, Pmode)) + if (const_arith_operand (offset, Pmode) + || GET_CODE (offset) == LO_SUM) return "ld.d\t%0,%1"; else return "ldptr.d\t%0,%1"; @@ -3423,6 +3670,21 @@ loongarch_output_move (rtx dest, rtx src) } } + if (src_code == HIGH) + { + rtx offset, x; + split_const (XEXP (src, 0), &x, &offset); + enum loongarch_symbol_type type = SYMBOL_PCREL; + + if (UNSPEC_ADDRESS_P (x)) + type = UNSPEC_ADDRESS_TYPE (x); + + if (type == SYMBOL_TLS_LE) + return "lu12i.w\t%0,%h1"; + else + return "pcalau12i\t%0,%h1"; + } + if (src_code == CONST_INT) { if (LU12I_INT (src)) @@ -3438,7 +3700,8 @@ loongarch_output_move (rtx dest, rtx src) } } - if (dest_code == REG && symbolic_operand (src, VOIDmode)) + if (!TARGET_EXPLICIT_RELOCS + && dest_code == REG && symbolic_operand (src, VOIDmode)) { if (loongarch_classify_symbol (src) == SYMBOL_PCREL) return "la.local\t%0,%1"; @@ -4307,6 +4570,49 @@ loongarch_memmodel_needs_release_fence (enum memmodel model) } } +/* Print symbolic operand OP, which is part of a HIGH or LO_SUM + in context CONTEXT. HI_RELOC indicates a high-part reloc. */ + +static void +loongarch_print_operand_reloc (FILE *file, rtx op, bool hi_reloc) +{ + const char *reloc; + + switch (loongarch_classify_symbolic_expression (op)) + { + case SYMBOL_PCREL: + reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12"; + break; + + case SYMBOL_GOT_DISP: + reloc = hi_reloc ? "%got_pc_hi20" : "%got_pc_lo12"; + break; + + case SYMBOL_TLS_IE: + reloc = hi_reloc ? "%ie_pc_hi20" : "%ie_pc_lo12"; + break; + + case SYMBOL_TLS_LE: + reloc = hi_reloc ? "%le_hi20" : "%le_lo12"; + break; + + case SYMBOL_TLSGD: + reloc = hi_reloc ? "%gd_pc_hi20" : "%got_pc_lo12"; + break; + + case SYMBOL_TLSLDM: + reloc = hi_reloc ? "%ld_pc_hi20" : "%got_pc_lo12"; + break; + + default: + gcc_unreachable (); + } + + fprintf (file, "%s(", reloc); + output_addr_const (file, loongarch_strip_unspec_address (op)); + fputc (')', file); +} + /* Implement TARGET_PRINT_OPERAND. The LoongArch-specific operand codes are: 'A' Print a _DB suffix if the memory model requires a release. @@ -4315,7 +4621,10 @@ loongarch_memmodel_needs_release_fence (enum memmodel model) 'd' Print CONST_INT OP in decimal. 'F' Print the FPU branch condition for comparison OP. 'G' Print a DBAR insn if the memory model requires a release. + 'H' Print address 52-61bit relocation associated with OP. + 'h' Print the high-part relocation associated with OP. 'i' Print i if the operand is not a register. + 'L' Print the low-part relocation associated with OP. 'm' Print one less than CONST_INT OP in decimal. 'N' Print the inverse of the integer branch condition for comparison OP. 'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...), @@ -4372,11 +4681,21 @@ loongarch_print_operand (FILE *file, rtx op, int letter) fputs ("dbar\t0", file); break; + case 'h': + if (code == HIGH) + op = XEXP (op, 0); + loongarch_print_operand_reloc (file, op, true /* hi_reloc */); + break; + case 'i': if (code != REG) fputs ("i", file); break; + case 'L': + loongarch_print_operand_reloc (file, op, false /* lo_reloc */); + break; + case 'm': if (CONST_INT_P (op)) fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1); @@ -4517,6 +4836,11 @@ loongarch_print_operand_address (FILE *file, machine_mode /* mode */, rtx x) reg_names[REGNO (addr.offset)]); return; + case ADDRESS_LO_SUM: + fprintf (file, "%s,", reg_names[REGNO (addr.reg)]); + loongarch_print_operand_reloc (file, addr.offset, false /* hi_reloc */); + return; + case ADDRESS_CONST_INT: fprintf (file, "%s,", reg_names[GP_REG_FIRST]); output_addr_const (file, x); @@ -5891,6 +6215,12 @@ loongarch_starting_frame_offset (void) #undef TARGET_TRAMPOLINE_INIT #define TARGET_TRAMPOLINE_INIT loongarch_trampoline_init +#undef TARGET_MIN_ANCHOR_OFFSET +#define TARGET_MIN_ANCHOR_OFFSET (-IMM_REACH/2) + +#undef TARGET_MAX_ANCHOR_OFFSET +#define TARGET_MAX_ANCHOR_OFFSET (IMM_REACH/2-1) + #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV loongarch_atomic_assign_expand_fenv diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 376879fbccb..6b6df22a5f1 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -57,6 +57,10 @@ (define_c_enum "unspec" [ ;; CRC UNSPEC_CRC UNSPEC_CRCC + + UNSPEC_LOAD_FROM_GOT + UNSPEC_ORI_L_LO12 + UNSPEC_TLS_LOW ]) (define_c_enum "unspecv" [ @@ -1743,73 +1747,6 @@ (define_insn "*movdf_softfloat" [(set_attr "move_type" "move,load,store") (set_attr "mode" "DF")]) - -;; 128-bit integer moves - -(define_expand "movti" - [(set (match_operand:TI 0) - (match_operand:TI 1))] - "TARGET_64BIT" -{ - if (loongarch_legitimize_move (TImode, operands[0], operands[1])) - DONE; -}) - -(define_insn "*movti" - [(set (match_operand:TI 0 "nonimmediate_operand" "=r,r,r,m") - (match_operand:TI 1 "move_operand" "r,i,m,rJ"))] - "TARGET_64BIT - && (register_operand (operands[0], TImode) - || reg_or_0_operand (operands[1], TImode))" - { return loongarch_output_move (operands[0], operands[1]); } - [(set_attr "move_type" "move,const,load,store") - (set (attr "mode") - (if_then_else (eq_attr "move_type" "imul") - (const_string "SI") - (const_string "TI")))]) - -;; 128-bit floating point moves - -(define_expand "movtf" - [(set (match_operand:TF 0) - (match_operand:TF 1))] - "TARGET_64BIT" -{ - if (loongarch_legitimize_move (TFmode, operands[0], operands[1])) - DONE; -}) - -;; This pattern handles both hard- and soft-float cases. -(define_insn "*movtf" - [(set (match_operand:TF 0 "nonimmediate_operand" "=r,r,m,f,r,f,m") - (match_operand:TF 1 "move_operand" "rG,m,rG,rG,f,m,f"))] - "TARGET_64BIT - && (register_operand (operands[0], TFmode) - || reg_or_0_operand (operands[1], TFmode))" - "#" - [(set_attr "move_type" "move,load,store,mgtf,mftg,fpload,fpstore") - (set_attr "mode" "TF")]) - -(define_split - [(set (match_operand:MOVE64 0 "nonimmediate_operand") - (match_operand:MOVE64 1 "move_operand"))] - "reload_completed && loongarch_split_move_insn_p (operands[0], operands[1])" - [(const_int 0)] -{ - loongarch_split_move_insn (operands[0], operands[1], curr_insn); - DONE; -}) - -(define_split - [(set (match_operand:MOVE128 0 "nonimmediate_operand") - (match_operand:MOVE128 1 "move_operand"))] - "reload_completed && loongarch_split_move_insn_p (operands[0], operands[1])" - [(const_int 0)] -{ - loongarch_split_move_insn (operands[0], operands[1], curr_insn); - DONE; -}) - ;; Emit a doubleword move in which exactly one of the operands is ;; a floating-point register. We can't just emit two normal moves ;; because of the constraints imposed by the FPU register model; @@ -1938,6 +1875,57 @@ (define_insn "lu52i_d" [(set_attr "type" "arith") (set_attr "mode" "DI")]) +;; Instructions for adding the low 12 bits of an address to a register. +;; Operand 2 is the address: loongarch_print_operand works out which relocation +;; should be applied. + +(define_insn "*low" + [(set (match_operand:P 0 "register_operand" "=r") + (lo_sum:P (match_operand:P 1 "register_operand" " r") + (match_operand:P 2 "symbolic_operand" "")))] + "TARGET_EXPLICIT_RELOCS" + "addi.\t%0,%1,%L2" + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +(define_insn "@tls_low" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(mem:P (lo_sum:P (match_operand:P 1 "register_operand" "r") + (match_operand:P 2 "symbolic_operand" "")))] + UNSPEC_TLS_LOW))] + "TARGET_EXPLICIT_RELOCS" + "addi.\t%0,%1,%L2" + [(set_attr "type" "arith") + (set_attr "mode" "")]) + +;; Instructions for loading address from GOT entry. +;; operands[1] is pc plus the high half of the address difference with the got +;; entry; +;; operands[2] is low 12 bits for low 12 bit of the address difference with the +;; got entry. +;; loongarch_print_operand works out which relocation should be applied. + +(define_insn "@ld_from_got" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(mem:P (lo_sum:P + (match_operand:P 1 "register_operand" "r") + (match_operand:P 2 "symbolic_operand")))] + UNSPEC_LOAD_FROM_GOT))] + "TARGET_EXPLICIT_RELOCS" + "ld.\t%0,%1,%L2" + [(set_attr "type" "move")] +) + +(define_insn "@ori_l_lo12" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "r") + (match_operand:P 2 "symbolic_operand")] + UNSPEC_ORI_L_LO12))] + "" + "ori\t%0,%1,%L2" + [(set_attr "type" "move")] +) + ;; Convert floating-point numbers to integers (define_insn "frint_" [(set (match_operand:ANYF 0 "register_operand" "=f") diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt index 3ff0d860413..7a8c5b44418 100644 --- a/gcc/config/loongarch/loongarch.opt +++ b/gcc/config/loongarch/loongarch.opt @@ -161,6 +161,10 @@ mmax-inline-memcpy-size= Target Joined RejectNegative UInteger Var(loongarch_max_inline_memcpy_size) Init(1024) -mmax-inline-memcpy-size=SIZE Set the max size of memcpy to inline, default is 1024. +mexplicit-relocs +Target Var(TARGET_EXPLICIT_RELOCS) Init(1) +Use %reloc() assembly operators. + ; The code model option names for -mcmodel. Enum Name(cmodel) Type(int) diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md index 2243ef71c1a..cd3528c7c97 100644 --- a/gcc/config/loongarch/predicates.md +++ b/gcc/config/loongarch/predicates.md @@ -110,6 +110,10 @@ (define_predicate "low_bitmask_operand" (define_predicate "const_call_insn_operand" (match_code "const,symbol_ref,label_ref") { + /* Split symbol to high and low if return false. + If defined TARGET_CMODEL_LARGE, all symbol would be splited, + else if offset is not zero, the symbol would be splited. */ + enum loongarch_symbol_type symbol_type; loongarch_symbolic_constant_p (op, &symbol_type); @@ -125,7 +129,7 @@ (define_predicate "const_call_insn_operand" return 1; case SYMBOL_GOT_DISP: - if (!flag_plt) + if (TARGET_CMODEL_LARGE || !flag_plt) return false; else return 1; @@ -213,7 +217,19 @@ (define_predicate "move_operand" case CONST: case SYMBOL_REF: case LABEL_REF: - return loongarch_symbolic_constant_p (op, &symbol_type); + return (loongarch_symbolic_constant_p (op, &symbol_type) + && (!TARGET_EXPLICIT_RELOCS + || !loongarch_split_symbol_type (symbol_type))); + + case HIGH: + /* '-mno-explicit-relocs' don't generate high/low pairs. */ + if (!TARGET_EXPLICIT_RELOCS) + return false; + + op = XEXP (op, 0); + return (loongarch_symbolic_constant_p (op, &symbol_type) + && loongarch_split_symbol_type (symbol_type)); + default: return true; } diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-1.c index b0482761aab..01b8ea23fb9 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-1.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fplt" } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs" } */ /* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ /* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-2.c b/gcc/testsuite/gcc.target/loongarch/func-call-2.c index f5e061c299c..4565baaec9e 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-2.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt" } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs" } */ /* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ /* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-3.c b/gcc/testsuite/gcc.target/loongarch/func-call-3.c index 75082c57466..4f669a029e7 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-3.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt" } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs" } */ /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ /* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-4.c b/gcc/testsuite/gcc.target/loongarch/func-call-4.c index e8a8395493e..943adb6403f 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-4.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt" } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs" } */ /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ /* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-5.c b/gcc/testsuite/gcc.target/loongarch/func-call-5.c new file mode 100644 index 00000000000..2c2a1c8a1b6 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-5.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-6.c b/gcc/testsuite/gcc.target/loongarch/func-call-6.c new file mode 100644 index 00000000000..4b0e4266ec8 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-6.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs" } */ +/* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-7.c b/gcc/testsuite/gcc.target/loongarch/func-call-7.c new file mode 100644 index 00000000000..51792711f72 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-7.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*pcalau12i\t.*%got_pc_hi20\\(f\\)\n\tld\.d\t.*%got_pc_lo12\\(f\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-8.c b/gcc/testsuite/gcc.target/loongarch/func-call-8.c new file mode 100644 index 00000000000..330140d883d --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-8.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs" } */ +/* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ +/* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ +/* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ + +extern void g (void); + +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +void +test2 (void) +{ + l (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c b/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c new file mode 100644 index 00000000000..bfcc9bc338f --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -mexplicit-relocs -fno-pic -O2" } */ +/* { dg-final { scan-assembler "pcalau12i.*%pc_hi20\\(\.LANCHOR0\\)\n" } } */ +/* { dg-final { scan-assembler "addi\.d.*%pc_lo12\\(\.LANCHOR0\\)\n" } } */ +/* { dg-final { scan-assembler "ldptr.d\t\\\$r4,.*,0\n" } } */ +/* { dg-final { scan-assembler "ld.d\t\\\$r5,.*,8\n" } } */ +/* { dg-final { scan-assembler-not "\.LANCHOR0+8" } } */ + + +struct S +{ + char *a; + unsigned short int b; +}; + +struct S s1; + +void test(struct S); +void test1(void) +{ + test(s1); +} + From patchwork Thu Jul 21 06:41:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenglulu X-Patchwork-Id: 93 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:e252:0:0:0:0:0 with SMTP id bl18csp1302437wrb; Wed, 20 Jul 2022 23:45:07 -0700 (PDT) X-Google-Smtp-Source: AGRyM1t4yXkQLpekzPyat1bOZNYRw9hMp7bIFjShzWHukQwkjbw7YJdM9UfH/DIRcUUq5O9+Nf/v X-Received: by 2002:a17:907:3d94:b0:72b:54bc:aa38 with SMTP id he20-20020a1709073d9400b0072b54bcaa38mr39425179ejc.679.1658385907043; Wed, 20 Jul 2022 23:45:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1658385907; cv=none; d=google.com; s=arc-20160816; b=cFj3KJZtwhLAN8VBnOUdpT43oNoC+H5tyRDVKLPbdDDx0TMj8CRnK9yL48l/VafQbH i5e+tmS6seGYt8ciluoqY3ltu+LpLQgtL3gZdiVfLCSSWFsB8wUuf2sk6zTGjopCxS8c wdqK+Zk8W2ARPJs3g/75bqjzP8NbubIfyKu7GakYBhec0IBAgttH+wHxyLsiwbFVZtO8 GekrVOmXSYEakNytlJ1p0/ywipVc7gQpEPCtAj5qEhmWWjO9bGywooZUB9CaCPCbNu03 /E125PJ4wFPauYbU9n9tiihFA33x4/gBMoEaZGUncyLGwBjKplRBcCzHf6jcfnfUAuVf aW3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:to:from :dmarc-filter:delivered-to; bh=QfCia1/qg9NzCf2orYXKVGGO3VYxaQJfm6BG8WdaoNo=; b=SavO5yrCbFF6DLoLgBRek/46BL+vtOZL174rpVpt92p72Y2xtyvi/8VRFAnje4kvek I+w0z2EFpStP+lphwZzP+OYcSkJ1rgoittPQuI7E5Yp2XDKr79deuBmtXqaRaIS0hltR YJo8sb2YWodg/80BZPIyZNpyIf/KanaF7MMCT9VafhLiVI/mIBZMJdZeQcUdDVUOvxI9 Chfl4aefxNysXuvEG/5Pz38QTp2jCTbvQ4BUcFRGTlpONVP1X0jVRCzLmmxzbbE8du5+ MULF9yeFFMWralZrtrnrqoSp4pM19pzOMxWGjoJk/zw6qtqv0NITwP91dRWVMEoIfZxE JIdg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id h5-20020a170906718500b00722f48fa044si1492109ejk.192.2022.07.20.23.45.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Jul 2022 23:45:07 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 8D47D384D16F for ; Thu, 21 Jul 2022 06:43:59 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id F076F3857014 for ; Thu, 21 Jul 2022 06:43:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org F076F3857014 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from 5.5.5 (unknown [10.2.5.5]) by mail.loongson.cn (Coremail) with SMTP id AQAAf9Dxf9N+9dhiwgssAA--.40495S5; Thu, 21 Jul 2022 14:43:20 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Subject: [PATCH v2 3/3] LoongArch: Modify the definition of the ASM_PREFERRED_EH_DATA_FORMAT macro. Date: Thu, 21 Jul 2022 14:41:23 +0800 Message-Id: <20220721064123.2981805-4-chenglulu@loongson.cn> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20220721064123.2981805-1-chenglulu@loongson.cn> References: <20220721064123.2981805-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf9Dxf9N+9dhiwgssAA--.40495S5 X-Coremail-Antispam: 1UD129KBjvdXoW7Xw48Wr4fXry3Cr45JrWrXwb_yoWDZFb_Xr y3t3ZrCw4rta48twn0q3yft3W8Za1rJFnYvF93Ar4vkF15XrsxA395X3W5CryFgrnF9F98 Jrs5Krn8ZwnFqjkaLaAFLSUrUUUUbb8apTn2vfkv8UJUUUU8Yxn0WfASr-VFAUDa7-sFnT 9fnUUIcSsGvfJTRUUUbS8FF20E14v26ryj6rWUM7CY07I20VC2zVCF04k26cxKx2IYs7xG 6rWj6s0DM7CIcVAFz4kK6r1j6r18M28IrcIa0xkI8VA2jI8067AKxVWUWwA2048vs2IY02 0Ec7CjxVAFwI0_Gr0_Xr1l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2x7M28EF7xv wVC0I7IYx2IY67AKxVW7JVWDJwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWxJVW8Jr1l84 ACjcxK6I8E87Iv67AKxVWxJr0_GcWl84ACjcxK6I8E87Iv6xkF7I0E14v26rxl6s0DM2AI xVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj6xIIjxv20x vE14v26r1Y6r17McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr0_Gr1lF7xv r2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm-wCF04k20xvY0x 0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r18MI8I3I0E 7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcV C0I7IYx2IY67AKxVW8JVW5JwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF 04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j6F4UMIIF0xvEx4A2jsIEc7 CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUxuc_UUUUU= X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: xuchenghua@loongson.cn, Lulu Cheng , i@xen0n.name Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1738943660903927335?= X-GMAIL-MSGID: =?utf-8?q?1738943660903927335?= Some R_LARCH_64 in section .eh_frame will to generate R_LARCH_NONE, we change relocation to R_LARCH_32_PCREL from R_LARCH_64 in setction .eh_frame and not generate dynamic relocation for R_LARCH_32_PCREL. gcc/ChangeLog: * config/loongarch/loongarch.h (ASM_PREFERRED_EH_DATA_FORMAT): Modify the definition of the ASM_PREFERRED_EH_DATA_FORMAT macro. --- gcc/config/loongarch/loongarch.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gcc/config/loongarch/loongarch.h b/gcc/config/loongarch/loongarch.h index 89a5bd728fe..222b58b838d 100644 --- a/gcc/config/loongarch/loongarch.h +++ b/gcc/config/loongarch/loongarch.h @@ -1128,7 +1128,7 @@ struct GTY (()) machine_function #endif #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \ - (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_absptr) + (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) /* Do emit .note.GNU-stack by default. */ #ifndef NEED_INDICATE_EXEC_STACK