From patchwork Tue Aug 23 14:51:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xi Ruoyao X-Patchwork-Id: 679 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:ecc5:0:0:0:0:0 with SMTP id s5csp991416wro; Tue, 23 Aug 2022 07:52:53 -0700 (PDT) X-Google-Smtp-Source: AA6agR45Pt3wzSg+OhHn30ie7EaVFKx49okrdw4QMYAHPDOy1NxzJeLqgVGM4p8fDOLzfWqb73Hl X-Received: by 2002:a05:6402:2792:b0:446:8864:26c1 with SMTP id b18-20020a056402279200b00446886426c1mr3956854ede.70.1661266372702; Tue, 23 Aug 2022 07:52:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1661266372; cv=none; d=google.com; s=arc-20160816; b=yPvrH4z/PGaqgM7EHPmpSshHcIAgaX68u5MEhYi55SOL2go3Ziv4cIEyAf8RFli4iD vQ2FgwUcrJMWi6UMgRMTrv3mE9NytNDsJDUO+0Ka6gIJmuLf8btG+iY5LdsxJfS/4+ZE mUP0M9K+1cTSXwF4RADNREjwKx3HATxNu9AA6kRpAZ1JwofLWIyqra+adfxMI6NBuctk +MsZ7Hjj4hjvfvS50Yg6z2G8oOcPtVv74bLWjchc2m4AMOOZuINzuopkSKClDvjUfA3G 5RaNvsuOf7ec+E2/Ze09G2FRUrjvtSNITF1mGhD9/g7TrBQa6JjPj1rvIxo0Mzl+NFjG WX0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:reply-to:from:list-subscribe:list-help :list-post:list-archive:list-unsubscribe:list-id:precedence :mime-version:user-agent:content-transfer-encoding:date:to:subject :message-id:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=2/Ife8tenhmWyk1FjqNEkjNUaCkD9a2ODsrKxohG+5w=; b=Alaq5h2GuuG1YNb7uYtcV9lJS3K0Ziqr8w1S9pZj/CNvgGH+0KQpv34w5kCqgJfv8K 0UYQbDP6dkfAx1obEZ4kmPr2WGoVSu8mWNvtYu7+wXCwiSZwd/7DKfIiYmG9ay5UYAfQ 5M6x0UcQnhn14HGNtBwM7t3ex108L6eWKXXXGEIaV511/U1g6jeeq1LAw2AAo5I+qFke MJsM999cVNXHtUBJDmB5Pe0dPdDOqNjoSy1fLktUwLNVTIWIYKozmkjSzYjWOvN0ZZD3 y80kA0ias3UVaqEX4n7GDb1I8dX0mpOMXdamsHL7VR2x1xqICJZEPcl3qE61rRNetuvI cQVw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="g6SrKyg/"; 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"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id nb22-20020a1709071c9600b0073d6c0facdcsi9136860ejc.259.2022.08.23.07.52.52 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Aug 2022 07:52:52 -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; dkim=pass header.i=@gcc.gnu.org header.s=default header.b="g6SrKyg/"; 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"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 4E3123858288 for ; Tue, 23 Aug 2022 14:52:51 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 4E3123858288 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1661266371; bh=2/Ife8tenhmWyk1FjqNEkjNUaCkD9a2ODsrKxohG+5w=; h=Subject:To:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=g6SrKyg/9inB4s1XH0vEryp4QKqSBVAJPki5LEhm4v8EgZFFfyAjoHAi8L6ofId6/ sArIshunu33LRp9k9zE1OCBTkbBcm+9gU/qmCAZgkTZvYi/gwVRbNXC0PUaQe7USyA jrd3vcL2WM2ZbZFvZAflbAhjHVeGsjXh1dHZAMjE= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from xry111.site (xry111.site [IPv6:2001:470:683e::1]) by sourceware.org (Postfix) with ESMTPS id 8C8BA3858C62 for ; Tue, 23 Aug 2022 14:52:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8C8BA3858C62 Received: from [IPv6:240e:358:113a:9c00:dc73:854d:832e:3] (unknown [IPv6:240e:358:113a:9c00:dc73:854d:832e:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature ECDSA (P-384) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: xry111@xry111.site) by xry111.site (Postfix) with ESMTPSA id 9E24466808; Tue, 23 Aug 2022 10:51:57 -0400 (EDT) Message-ID: Subject: LoongArch: add model attribute To: gcc-patches@gcc.gnu.org, Lulu Cheng Date: Tue, 23 Aug 2022 22:51:45 +0800 User-Agent: Evolution 3.45.2 MIME-Version: 1.0 X-Spam-Status: No, score=-5.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FROM_SUSPICIOUS_NTLD, FROM_SUSPICIOUS_NTLD_FP, GIT_PATCH_0, KAM_SHORT, KAM_STOCKGEN, LIKELY_SPAM_FROM, PDS_OTHER_BAD_TLD, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE 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: , X-Patchwork-Original-From: Xi Ruoyao via Gcc-patches From: Xi Ruoyao Reply-To: Xi Ruoyao Cc: Jinyang He , Chenghua Xu , Huacai Chen , Youling Tang , Wang Xuerui 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?1741964048208830646?= X-GMAIL-MSGID: =?utf-8?q?1741964048208830646?= Another attempt to make kernel module happy. One remaining issue: the patch cannot diagnostic some insane thing like int x __attribute__((model("normal"))); int x __attribute__((model("extreme"))); It seems incredibly difficult to diagnose such thing: I can't figure out any solution w/o invasion into the frontend. IA-64 model() only accepts small so this is not a problem for them, and M32R model() also cannot diagnose such error. Any suggestion is welcomed. -- >8 -- A linker script and/or a section attribute may locate some object specially, so we need to handle the code model for such objects differently than the -mcmodel setting. This happens when the Linux kernel loads a module with per-CPU variables. Add an attribute to override the code model for a specific variable. gcc/ChangeLog: * config/loongarch/loongarch-protos.h (loongarch_symbol_type): Add SYMBOL_PCREL32 and SYMBOL_PCREL64. * config/loongarch/loongarch.cc (loongarch_attribute_table): New attribute table. (TARGET_ATTRIBUTE_TABLE): Define the target hook. (loongarch_handle_model_attribute): New static function. (loongarch_classify_symbol): Return SYMBOL_PCREL{32,64} for SYMBOL_REF_DECL with model attribute. (loongarch_use_anchors_for_symbol_p): New static function. (TARGET_USE_ANCHORS_FOR_SYMBOL_P): Define the target hook. * doc/extend.texi (Variable Attributes): Document new LoongArch specific attribute. gcc/testsuite/ChangeLog: * gcc.target/loongarch/attr-model-test.c: New test. * gcc.target/loongarch/attr-model-1.c: New test. * gcc.target/loongarch/attr-model-2.c: New test. * gcc.target/loongarch/attr-model-diag.c: New test. --- gcc/config/loongarch/loongarch-protos.h | 8 + gcc/config/loongarch/loongarch.cc | 175 +++++++++++++++++- gcc/doc/extend.texi | 16 ++ .../gcc.target/loongarch/attr-model-1.c | 6 + .../gcc.target/loongarch/attr-model-2.c | 6 + .../gcc.target/loongarch/attr-model-diag.c | 7 + .../gcc.target/loongarch/attr-model-test.c | 25 +++ 7 files changed, 236 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-2.c create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-diag.c create mode 100644 gcc/testsuite/gcc.target/loongarch/attr-model-test.c diff --git a/gcc/config/loongarch/loongarch-protos.h b/gcc/config/loongarch/loongarch-protos.h index cadaad7519c..4e925aa3876 100644 --- a/gcc/config/loongarch/loongarch-protos.h +++ b/gcc/config/loongarch/loongarch-protos.h @@ -30,6 +30,12 @@ along with GCC; see the file COPYING3. If not see SYMBOL_PCREL The symbol's value will be loaded directly from data section. + SYMBOL_PCREL32 + SYMBOL_PCREL64 + Like SYMBOL_PCREL, but the PC-relative offset of the symbol is + assumed to be in the +/- 2GiB or +/- 8 EiB range, instead of the + code model specification. + SYMBOL_TLS A thread-local symbol. @@ -42,6 +48,8 @@ along with GCC; see the file COPYING3. If not see enum loongarch_symbol_type { SYMBOL_GOT_DISP, SYMBOL_PCREL, + SYMBOL_PCREL32, + SYMBOL_PCREL64, SYMBOL_TLS, SYMBOL_TLS_IE, SYMBOL_TLS_LE, diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 207ac2762c6..3917c53dd27 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -1643,6 +1643,32 @@ loongarch_classify_symbol (const_rtx x) && !loongarch_symbol_binds_local_p (x)) return SYMBOL_GOT_DISP; + if (SYMBOL_REF_P (x)) + { + tree t = SYMBOL_REF_DECL (x); + if (!t) + return SYMBOL_PCREL; + + t = lookup_attribute ("model", DECL_ATTRIBUTES (t)); + if (!t) + return SYMBOL_PCREL; + + t = TREE_VALUE (TREE_VALUE (t)); + + /* loongarch_handle_model_attribute should reject other values. */ + gcc_assert (TREE_CODE (t) == STRING_CST); + + const char *model = TREE_STRING_POINTER (t); + if (strcmp (model, "normal") == 0) + return SYMBOL_PCREL32; + if (strcmp (model, "extreme") == 0) + return SYMBOL_PCREL64; + + /* loongarch_handle_model_attribute should reject unknown model + name. */ + gcc_unreachable (); + } + return SYMBOL_PCREL; } @@ -1696,6 +1722,8 @@ loongarch_symbolic_constant_p (rtx x, enum loongarch_symbol_type *symbol_type) case SYMBOL_TLSGD: case SYMBOL_TLSLDM: case SYMBOL_PCREL: + case SYMBOL_PCREL32: + case SYMBOL_PCREL64: /* GAS rejects offsets outside the range [-2^31, 2^31-1]. */ return sext_hwi (INTVAL (offset), 32) == INTVAL (offset); @@ -1721,7 +1749,7 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode) return 3; - case SYMBOL_PCREL: + case SYMBOL_PCREL32: case SYMBOL_TLS_IE: case SYMBOL_TLS_LE: return 2; @@ -1730,6 +1758,12 @@ loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode) case SYMBOL_TLSLDM: return 3; + case SYMBOL_PCREL64: + return 5; + + case SYMBOL_PCREL: + return TARGET_CMODEL_EXTREME ? 5 : 2; + case SYMBOL_TLS: /* We don't treat a bare TLS symbol as a constant. */ return 0; @@ -1834,7 +1868,7 @@ loongarch_valid_offset_p (rtx x, machine_mode mode) return true; } -/* Should a symbol of type SYMBOL_TYPE should be split in two? */ +/* Should a symbol of type SYMBOL_TYPE should be split in two or more? */ bool loongarch_split_symbol_type (enum loongarch_symbol_type symbol_type) @@ -1842,6 +1876,8 @@ loongarch_split_symbol_type (enum loongarch_symbol_type symbol_type) switch (symbol_type) { case SYMBOL_PCREL: + case SYMBOL_PCREL32: + case SYMBOL_PCREL64: case SYMBOL_GOT_DISP: case SYMBOL_TLS_IE: case SYMBOL_TLS_LE: @@ -2649,6 +2685,22 @@ loongarch_force_address (rtx x, machine_mode mode) return x; } +static bool +loongarch_symbol_extreme_p (enum loongarch_symbol_type *type) +{ + switch (*type) + { + case SYMBOL_PCREL32: + *type = SYMBOL_PCREL; + return false; + case SYMBOL_PCREL64: + *type = SYMBOL_PCREL; + return true; + default: + return TARGET_CMODEL_EXTREME; + } +} + /* 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. @@ -2688,7 +2740,9 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); high = loongarch_force_temporary (temp, high); - if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) + bool extreme = loongarch_symbol_extreme_p (&symbol_type); + + if (extreme && can_create_pseudo_p ()) { gcc_assert (TARGET_EXPLICIT_RELOCS); @@ -2704,7 +2758,7 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) { case SYMBOL_PCREL: { - if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) + if (extreme && can_create_pseudo_p ()) *low_out = gen_rtx_PLUS (Pmode, high, temp1); else *low_out = gen_rtx_LO_SUM (Pmode, high, addr); @@ -4676,16 +4730,19 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part, bool hi_reloc) { const char *reloc; + enum loongarch_symbol_type symbol_type = + loongarch_classify_symbolic_expression (op); + bool extreme = loongarch_symbol_extreme_p (&symbol_type); - if (TARGET_CMODEL_EXTREME) + if (extreme) gcc_assert (TARGET_EXPLICIT_RELOCS); - switch (loongarch_classify_symbolic_expression (op)) + switch (symbol_type) { case SYMBOL_PCREL: if (hi64_part) { - if (TARGET_CMODEL_EXTREME) + if (extreme) reloc = hi_reloc ? "%pc64_hi12" : "%pc64_lo20"; else gcc_unreachable (); @@ -6246,6 +6303,104 @@ loongarch_starting_frame_offset (void) return crtl->outgoing_args_size; } +static tree +loongarch_handle_model_attribute (tree *node, tree name, tree arg, int, + bool *no_add_attrs) +{ + tree decl = *node; + if (TREE_CODE (decl) == VAR_DECL) + { + if (DECL_THREAD_LOCAL_P (decl)) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute cannot be specified for thread-local " + "variables", name); + *no_add_attrs = true; + return NULL_TREE; + } + if (DECL_CONTEXT (decl) + && TREE_CODE (DECL_CONTEXT (decl)) == FUNCTION_DECL + && !TREE_STATIC (decl)) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute cannot be specified for local " + "variables", name); + *no_add_attrs = true; + return NULL_TREE; + } + if (DECL_REGISTER (decl)) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute cannot be specified for register " + "variables", name); + *no_add_attrs = true; + return NULL_TREE; + } + if (!TARGET_EXPLICIT_RELOCS) + { + error_at (DECL_SOURCE_LOCATION (decl), + "%qE attribute requires %s", name, "-mexplicit-relocs"); + *no_add_attrs = true; + return NULL_TREE; + } + + arg = TREE_VALUE (arg); + if (TREE_CODE (arg) != STRING_CST) + { + error_at (DECL_SOURCE_LOCATION (decl), + "invalid argument of %qE attribute", name); + *no_add_attrs = true; + return NULL_TREE; + } + + const char *model = TREE_STRING_POINTER (arg); + if (strcmp (model, "normal") != 0 + && strcmp (model, "extreme") != 0) + { + error_at (DECL_SOURCE_LOCATION (decl), + "invalid argument of %qE attribute", name); + *no_add_attrs = true; + return NULL_TREE; + } + + if (lookup_attribute ("model", DECL_ATTRIBUTES (decl))) + { + error_at (DECL_SOURCE_LOCATION (decl), + "multiple %qE attribute", name); + *no_add_attrs = true; + return NULL_TREE; + } + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + return NULL_TREE; +} + +static const struct attribute_spec loongarch_attribute_table[] = +{ + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, + affects_type_identity, handler, exclude } */ + { "model", 1, 1, true, false, false, false, + loongarch_handle_model_attribute, NULL }, + /* The last attribute spec is set to be NULL. */ + {} +}; + +bool +loongarch_use_anchors_for_symbol_p (const_rtx symbol) +{ + tree decl = SYMBOL_REF_DECL (symbol); + + /* The section anchor optimization may break custom address model. */ + if (decl && lookup_attribute ("model", DECL_ATTRIBUTES (decl))) + return false; + + return default_use_anchors_for_symbol_p (symbol); +} + /* Initialize the GCC target structure. */ #undef TARGET_ASM_ALIGNED_HI_OP #define TARGET_ASM_ALIGNED_HI_OP "\t.half\t" @@ -6434,6 +6589,12 @@ loongarch_starting_frame_offset (void) #undef TARGET_HAVE_SPECULATION_SAFE_VALUE #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed +#undef TARGET_ATTRIBUTE_TABLE +#define TARGET_ATTRIBUTE_TABLE loongarch_attribute_table + +#undef TARGET_USE_ANCHORS_FOR_SYMBOL_P +#define TARGET_USE_ANCHORS_FOR_SYMBOL_P loongarch_use_anchors_for_symbol_p + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-loongarch.h" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 7fe7f8817cd..431811c7b26 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -7314,6 +7314,7 @@ attributes. * Blackfin Variable Attributes:: * H8/300 Variable Attributes:: * IA-64 Variable Attributes:: +* LoongArch Variable Attributes:: * M32R/D Variable Attributes:: * MeP Variable Attributes:: * Microsoft Windows Variable Attributes:: @@ -8098,6 +8099,21 @@ defined by shared libraries. @end table +@node LoongArch Variable Attributes +@subsection LoongArch Variable Attributes + +One attribute is currently defined for the LoongArch. + +@table @code +@item model("@var{name}") +@cindex @code{model} variable attribute, LoongArch +Use this attribute on the LoongArch to use a different code model for +addressing this variable, than the code model specified by the global +@option{-mcmodel} option. This attribute is mostly useful if a +@code{section} attribute and/or a linker script will locate this object +specially. +@end table + @node M32R/D Variable Attributes @subsection M32R/D Variable Attributes diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-1.c b/gcc/testsuite/gcc.target/loongarch/attr-model-1.c new file mode 100644 index 00000000000..916d715b98b --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-1.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs -mcmodel=normal -O2" } */ +/* { dg-final { scan-assembler-times "%pc64_hi12" 2 } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-2.c b/gcc/testsuite/gcc.target/loongarch/attr-model-2.c new file mode 100644 index 00000000000..a74c795ac3e --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-2.c @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs -mcmodel=extreme -O2" } */ +/* { dg-final { scan-assembler-times "%pc64_hi12" 3 } } */ + +#define ATTR_MODEL_TEST +#include "attr-model-test.c" diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-diag.c b/gcc/testsuite/gcc.target/loongarch/attr-model-diag.c new file mode 100644 index 00000000000..88beede74df --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-diag.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-mexplicit-relocs" } */ + +__thread int x __attribute__((model("extreme"))); /* { dg-error "attribute cannot be specified for thread-local variables" } */ +register int y __asm__("tp") __attribute__((model("extreme"))); /* { dg-error "attribute cannot be specified for register variables" } */ +int z __attribute__((model(114))); /* { dg-error "invalid argument" } */ +int t __attribute__((model("good"))); /* { dg-error "invalid argument" } */ diff --git a/gcc/testsuite/gcc.target/loongarch/attr-model-test.c b/gcc/testsuite/gcc.target/loongarch/attr-model-test.c new file mode 100644 index 00000000000..5b61a7af9c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/attr-model-test.c @@ -0,0 +1,25 @@ +#ifdef ATTR_MODEL_TEST +int x __attribute__((model("extreme"))); +int y __attribute__((model("normal"))); +int z; + +int +test(void) +{ + return x + y + z; +} + +/* The following will be used for kernel per-cpu storage implemention. */ + +register char *per_cpu_base __asm__("r21"); +static int counter __attribute__((section(".data..percpu"), model("extreme"))); + +void +inc_counter(void) +{ + int *ptr = (int *)(per_cpu_base + (long)&counter); + (*ptr)++; +} +#endif + +int dummy;