From patchwork Tue Jun 6 06:53:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jie Mei X-Patchwork-Id: 1790821 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=oss.cipunited.com header.i=@oss.cipunited.com header.a=rsa-sha256 header.s=feishu2303200042 header.b=mIAzrW8K; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Qb1RD0xLwz20WK for ; Tue, 6 Jun 2023 16:54:00 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 03CEC3857733 for ; Tue, 6 Jun 2023 06:53:58 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from s02.bc.larksuite.com (s02.bc.larksuite.com [209.127.230.20]) by sourceware.org (Postfix) with UTF8SMTPS id 6ACA0385841A for ; Tue, 6 Jun 2023 06:53:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 6ACA0385841A Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=oss.cipunited.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=oss.cipunited.com DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; s=feishu2303200042; d=oss.cipunited.com; t=1686034417; h=from:subject:mime-version:from:date:message-id:subject:to:cc: reply-to:content-type:mime-version:in-reply-to:message-id; bh=Ck3CbFIT7nWB9zoF0m53v17aAIKPRL9IokiYBgyZOds=; b=mIAzrW8KrgzyJ5M2XC7iRLrKVtT7o+tLdMWxfNlVpj59EKPsy83IU12I2sPzLthO0U+aCs j6RYMr5WHfemlpOzM8arXm8Gq5RtXB1TdLgrUFlcIVNH/Pe6JIxRlvRVAt0p9QohVcGBg7 pk+oy/So4ruvxeH4OdPHNTvWo82Z9JUqoThs6pYW3A90T0HkwL6TcJZsqE8jhw+wikH3sa RXWhm3o26lrLoESOX2Vy1oWdcYnJzcOp0L0Nca+xNyXLShyLB4WgG/pvHYWIB0HVbt1m+7 1zZn7Bd7iaw/lOg4zk+VD1NOQf/+fbLBeMMViSm/aQNqI1PhSBh6qe7r6j58jQ== To: Subject: [PATCH v3] MIPS16: Implement `code_readable` function attribute. Message-Id: <20230606065225.845953-1-jie.mei@oss.cipunited.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.40.1 Date: Tue, 06 Jun 2023 14:53:36 +0800 Cc: "YunQiang Su" From: "Jie Mei" X-Lms-Return-Path: X-Spam-Status: No, score=-13.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, GIT_PATCH_0, HTML_MESSAGE, HTML_NONELEMENT_30_40, KAM_SHORT, NO_DNS_FOR_FROM, SPF_HELO_NONE, SPF_NONE, 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-Content-Filtered-By: Mailman/MimeDel 2.1.29 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: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" From: Simon Dardis Support for __attribute__ ((code_readable)). Takes up to one argument of "yes", "no", "pcrel". This will change the code readability setting for just that function. If no argument is supplied, then the setting is 'yes'. gcc/ChangeLog: * config/mips/mips.cc (enum mips_code_readable_setting):New enmu. (mips_handle_code_readable_attr):New static function. (mips_get_code_readable_attr):New static enum function. (mips_set_current_function):Set the code_readable mode. (mips_option_override):Same as above. * doc/extend.texi:Document code_readable. gcc/testsuite/ChangeLog: * gcc.target/mips/code-readable-attr-1.c: New test. * gcc.target/mips/code-readable-attr-2.c: New test. * gcc.target/mips/code-readable-attr-3.c: New test. * gcc.target/mips/code-readable-attr-4.c: New test. * gcc.target/mips/code-readable-attr-5.c: New test. --- gcc/config/mips/mips.cc | 97 ++++++++++++++++++- gcc/doc/extend.texi | 17 ++++ .../gcc.target/mips/code-readable-attr-1.c | 51 ++++++++++ .../gcc.target/mips/code-readable-attr-2.c | 49 ++++++++++ .../gcc.target/mips/code-readable-attr-3.c | 50 ++++++++++ .../gcc.target/mips/code-readable-attr-4.c | 51 ++++++++++ .../gcc.target/mips/code-readable-attr-5.c | 5 + 7 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-1.c create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-2.c create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-3.c create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-4.c create mode 100644 gcc/testsuite/gcc.target/mips/code-readable-attr-5.c diff --git a/gcc/config/mips/mips.cc b/gcc/config/mips/mips.cc index ca822758b41..97f45e67529 100644 --- a/gcc/config/mips/mips.cc +++ b/gcc/config/mips/mips.cc @@ -498,6 +498,9 @@ static int mips_base_target_flags; /* The default compression mode. */ unsigned int mips_base_compression_flags; +/* The default code readable setting. */ +enum mips_code_readable_setting mips_base_code_readable; + /* The ambient values of other global variables. */ static int mips_base_schedule_insns; /* flag_schedule_insns */ static int mips_base_reorder_blocks_and_partition; /* flag_reorder... */ @@ -602,6 +605,7 @@ const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = { ALL_REGS, ALL_REGS, ALL_REGS, ALL_REGS }; +static tree mips_handle_code_readable_attr (tree *, tree, tree, int, bool *); static tree mips_handle_interrupt_attr (tree *, tree, tree, int, bool *); static tree mips_handle_use_shadow_register_set_attr (tree *, tree, tree, int, bool *); @@ -623,6 +627,8 @@ static const struct attribute_spec mips_attribute_table[] = { { "micromips", 0, 0, true, false, false, false, NULL, NULL }, { "nomicromips", 0, 0, true, false, false, false, NULL, NULL }, { "nocompression", 0, 0, true, false, false, false, NULL, NULL }, + { "code_readable", 0, 1, true, false, false, false, + mips_handle_code_readable_attr, NULL }, /* Allow functions to be specified as interrupt handlers */ { "interrupt", 0, 1, false, true, true, false, mips_handle_interrupt_attr, NULL }, @@ -1310,6 +1316,81 @@ mips_use_debug_exception_return_p (tree type) TYPE_ATTRIBUTES (type)) != NULL; } + +/* Verify the arguments to a code_readable attribute. */ + +static tree +mips_handle_code_readable_attr (tree *node ATTRIBUTE_UNUSED, tree name, + tree args, int flags ATTRIBUTE_UNUSED, + bool *no_add_attrs) +{ + if (!is_attribute_p ("code_readable", name) || args == NULL) + return NULL_TREE; + + if (TREE_CODE (TREE_VALUE (args)) != STRING_CST) + { + warning (OPT_Wattributes, + "%qE attribute requires a string argument", name); + *no_add_attrs = true; + } + else if (strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "no") != 0 + && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "pcrel") != 0 + && strcmp (TREE_STRING_POINTER (TREE_VALUE (args)), "yes") != 0) + { + warning (OPT_Wattributes, + "argument to %qE attribute is neither no, pcrel nor yes", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Determine the code_readable setting for a function if it has one. Set + *valid to true if we have a properly formed argument and + return the result. If there's no argument, return GCC's default. + Otherwise, leave valid false and return mips_base_code_readable. In + that case the result should be unused anyway. */ + +static enum mips_code_readable_setting +mips_get_code_readable_attr (tree decl) +{ + tree attr; + + if (decl == NULL) + return mips_base_code_readable; + + attr = lookup_attribute ("code_readable", DECL_ATTRIBUTES (decl)); + + if (attr != NULL) + { + if (TREE_VALUE (attr) != NULL_TREE) + { + const char * str; + + str = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (attr))); + if (strcmp (str, "no") == 0) + return CODE_READABLE_NO; + else if (strcmp (str, "pcrel") == 0) + return CODE_READABLE_PCREL; + else if (strcmp (str, "yes") == 0) + return CODE_READABLE_YES; + + /* mips_handle_code_readable_attr will have verified the + arguments are correct before adding the attribute. */ + gcc_unreachable (); + } + + /* Just like GCC's default -mcode-readable= setting, the + presence of the code_readable attribute implies that a + function can read data from the instruction stream by + default. */ + return CODE_READABLE_YES; + } + + return mips_base_code_readable; +} + + /* Return the set of compression modes that are explicitly required by the attributes in ATTRIBUTES. */ @@ -19905,12 +19986,25 @@ mips_set_compression_mode (unsigned int compression_mode) /* Implement TARGET_SET_CURRENT_FUNCTION. Decide whether the current function should use the MIPS16 or microMIPS ISA and switch modes - accordingly. */ + accordingly. Also set the current code_readable mode. */ static void mips_set_current_function (tree fndecl) { + enum mips_code_readable_setting old_code_readable = mips_code_readable; + mips_set_compression_mode (mips_get_compress_mode (fndecl)); + + mips_code_readable = mips_get_code_readable_attr (fndecl); + + /* Since the mips_code_readable setting has potentially changed, the + relocation tables must be reinitialized. Otherwise GCC will not + split symbols for functions that are code_readable ("no") when others + are code_readable ("yes") and ICE later on in places such as + mips_emit_move. Ditto for similar paired cases. It must be restored + to its previous state as well. */ + if (old_code_readable != mips_code_readable) + mips_init_relocs (); } /* Allocate a chunk of memory for per-function machine-dependent data. */ @@ -20042,6 +20136,7 @@ mips_option_override (void) were generating uncompressed code. */ mips_base_compression_flags = TARGET_COMPRESSION; target_flags &= ~TARGET_COMPRESSION; + mips_base_code_readable = mips_code_readable; /* -mno-float overrides -mhard-float and -msoft-float. */ if (TARGET_NO_FLOAT) diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 69b21a75e62..b48f5f55513 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5670,6 +5670,23 @@ command line (@pxref{MIPS Options}). This function attribute instructs the compiler to generate a hazard barrier return that clears all execution and instruction hazards while returning, instead of generating a normal return instruction. + +@item code_readable +@cindex @code{code_readable} function attribute, MIPS +For MIPS targets that support PC-relative addressing modes, this attribute +can be used to control how an object is addressed. The attribute takes +a single optional argument: + +@table @samp +@item no +The function should not read the instruction stream as data. +@item yes +The function can read the instruction stream as data. +@item pcrel +The function can read the instruction stream in a pc-relative mode. +@end table + +If there is no argument supplied, the default of @code{"yes"} applies. @end table @node MSP430 Function Attributes diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-1.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-1.c new file mode 100644 index 00000000000..4ccb27c8bde --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-1.c @@ -0,0 +1,51 @@ +/* { dg-options "(-mips16) -mgp32 addressing=absolute" } */ +/* { dg-skip-if ".half requires -O" { *-*-* } { "-O0" } { "" } } */ + +volatile int x1; +volatile int x2; +volatile int x3; +volatile int x4; +volatile int x5; +volatile int x6; +volatile int x7; +volatile int x8; +volatile int x9; +volatile int x10; +volatile int x11; + +MIPS16 __attribute__ ((code_readable)) int +foo (int i, volatile int *x) +{ + switch (i) + { + case 1: return x1 + x[0]; + case 2: return x2 + x[1]; + case 3: return x3 + x[2]; + case 4: return x4 + x[3]; + case 5: return x5 + x[4]; + case 6: return x6 + x[5]; + case 7: return x7 + x[6]; + case 8: return x8 + x[7]; + case 9: return x9 + x[8]; + case 10: return x10 + x[9]; + case 11: return x11 + x[10]; + default: return 0; + } +} + +extern int k[]; + +MIPS16 __attribute__ ((code_readable)) int * +bar (void) +{ + return k; +} + +/* { dg-final { scan-assembler "\tla\t" } } */ +/* { dg-final { scan-assembler "\t\\.half\t" } } */ +/* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */ +/* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */ + +/* { dg-final { scan-assembler "\t\\.word\tk\n" } } */ +/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */ +/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */ diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-2.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-2.c new file mode 100644 index 00000000000..c7dd5113359 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-2.c @@ -0,0 +1,49 @@ +/* { dg-options "(-mips16) -mgp32 addressing=absolute" } */ + +volatile int x1; +volatile int x2; +volatile int x3; +volatile int x4; +volatile int x5; +volatile int x6; +volatile int x7; +volatile int x8; +volatile int x9; +volatile int x10; +volatile int x11; + +MIPS16 __attribute__((code_readable ("pcrel"))) int +foo (int i, volatile int *x) +{ + switch (i) + { + case 1: return x1 + x[0]; + case 2: return x2 + x[1]; + case 3: return x3 + x[2]; + case 4: return x4 + x[3]; + case 5: return x5 + x[4]; + case 6: return x6 + x[5]; + case 7: return x7 + x[6]; + case 8: return x8 + x[7]; + case 9: return x9 + x[8]; + case 10: return x10 + x[9]; + case 11: return x11 + x[10]; + default: return 0; + } +} + +extern int k[]; + +MIPS16 __attribute__((code_readable ("pcrel"))) int * +bar (void) +{ + return k; +} + +/* { dg-final { scan-assembler-not "\tla\t" } } */ +/* { dg-final { scan-assembler-not "\t\\.half\t" } } */ +/* { dg-final { scan-assembler "\t\\.word\t\[^\n\]*L" } } */ + +/* { dg-final { scan-assembler "\t\\.word\tk\n" } } */ +/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */ +/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */ diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-3.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-3.c new file mode 100644 index 00000000000..99c13a901bc --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-3.c @@ -0,0 +1,50 @@ +/* { dg-options "(-mips16) -mgp32 addressing=absolute" } */ + +volatile int x1; +volatile int x2; +volatile int x3; +volatile int x4; +volatile int x5; +volatile int x6; +volatile int x7; +volatile int x8; +volatile int x9; +volatile int x10; +volatile int x11; + +MIPS16 __attribute__((code_readable ("no"))) int +foo (int i, volatile int *x) +{ + switch (i) + { + case 1: return x1 + x[0]; + case 2: return x2 + x[1]; + case 3: return x3 + x[2]; + case 4: return x4 + x[3]; + case 5: return x5 + x[4]; + case 6: return x6 + x[5]; + case 7: return x7 + x[6]; + case 8: return x8 + x[7]; + case 9: return x9 + x[8]; + case 10: return x10 + x[9]; + case 11: return x11 + x[10]; + default: return 0; + } +} + +extern int k[]; + +MIPS16 __attribute__((code_readable ("no"))) int * +bar (void) +{ + return k; +} + +/* { dg-final { scan-assembler-not "\tla\t" } } */ +/* { dg-final { scan-assembler-not "\t\\.half\t" } } */ +/* { dg-final { scan-assembler "%hi\\(\[^)\]*L" } } */ +/* { dg-final { scan-assembler "%lo\\(\[^)\]*L" } } */ + +/* { dg-final { scan-assembler-not "\t\\.word\tk\n" } } */ +/* { dg-final { scan-assembler "%hi\\(k\\)" } } */ +/* { dg-final { scan-assembler "%lo\\(k\\)" } } */ diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-4.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-4.c new file mode 100644 index 00000000000..4058ba13810 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-4.c @@ -0,0 +1,51 @@ +/* { dg-options "(-mips16) -mabi=eabi -mgp64" } */ +/* { dg-skip-if ".half requires -O" { *-*-* } { "-O0" } { "" } } */ + +volatile int x1; +volatile int x2; +volatile int x3; +volatile int x4; +volatile int x5; +volatile int x6; +volatile int x7; +volatile int x8; +volatile int x9; +volatile int x10; +volatile int x11; + +MIPS16 __attribute__((code_readable ("yes"))) int +foo (int i, volatile int *x) +{ + switch (i) + { + case 1: return x1 + x[0]; + case 2: return x2 + x[1]; + case 3: return x3 + x[2]; + case 4: return x4 + x[3]; + case 5: return x5 + x[4]; + case 6: return x6 + x[5]; + case 7: return x7 + x[6]; + case 8: return x8 + x[7]; + case 9: return x9 + x[8]; + case 10: return x10 + x[9]; + case 11: return x11 + x[10]; + default: return 0; + } +} + +extern int k[]; + +MIPS16 __attribute__((code_readable ("yes"))) int * +bar (void) +{ + return k; +} + +/* { dg-final { scan-assembler "\tdla\t" } } */ +/* { dg-final { scan-assembler "\t\\.half\t" } } */ +/* { dg-final { scan-assembler-not "%hi\\(\[^)\]*L" } } */ +/* { dg-final { scan-assembler-not "%lo\\(\[^)\]*L" } } */ + +/* { dg-final { scan-assembler "\t\\.dword\tk\n" } } */ +/* { dg-final { scan-assembler-not "%hi\\(k\\)" } } */ +/* { dg-final { scan-assembler-not "%lo\\(k\\)" } } */ diff --git a/gcc/testsuite/gcc.target/mips/code-readable-attr-5.c b/gcc/testsuite/gcc.target/mips/code-readable-attr-5.c new file mode 100644 index 00000000000..0a547a9acfc --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/code-readable-attr-5.c @@ -0,0 +1,5 @@ +/* { dg-options "(-mips16) isa_rev<=5" } */ + + __attribute__((code_readable ("magic"))) int foo () {} /* { dg-warning "argument to 'code_readable' attribute is neither no, pcrel nor yes" } */ + + __attribute__((code_readable (1))) int * bar () {} /* { dg-warning "'code_readable' attribute requires a string argument" } */