From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 55729 invoked by alias); 2 Nov 2017 12:34:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 55713 invoked by uid 89); 2 Nov 2017 12:34:50 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-23.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,KAM_STOCKGEN autolearn=ham version=3.3.2 spammy= X-HELO: eggs.gnu.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (208.118.235.92) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 02 Nov 2017 12:34:47 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eAEhm-0003tQ-6N for gcc-patches@gcc.gnu.org; Thu, 02 Nov 2017 08:34:45 -0400 Received: from us01smtprelay-2.synopsys.com ([198.182.47.9]:35831 helo=smtprelay.synopsys.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eAEhl-0003ss-Tj for gcc-patches@gcc.gnu.org; Thu, 02 Nov 2017 08:34:42 -0400 Received: from mailhost.synopsys.com (mailhost3.synopsys.com [10.12.238.238]) by smtprelay.synopsys.com (Postfix) with ESMTP id 7C1B024E203D; Thu, 2 Nov 2017 05:34:39 -0700 (PDT) Received: from mailhost.synopsys.com (localhost [127.0.0.1]) by mailhost.synopsys.com (Postfix) with ESMTP id 629ABB20; Thu, 2 Nov 2017 05:34:39 -0700 (PDT) Received: from US01WEHTC2.internal.synopsys.com (us01wehtc2-vip.internal.synopsys.com [10.12.239.238]) by mailhost.synopsys.com (Postfix) with ESMTP id 51CE7B1E; Thu, 2 Nov 2017 05:34:39 -0700 (PDT) Received: from IN01WEHTCB.internal.synopsys.com (10.144.199.106) by US01WEHTC2.internal.synopsys.com (10.12.239.237) with Microsoft SMTP Server (TLS) id 14.3.266.1; Thu, 2 Nov 2017 05:34:33 -0700 Received: from IN01WEHTCA.internal.synopsys.com (10.144.199.103) by IN01WEHTCB.internal.synopsys.com (10.144.199.105) with Microsoft SMTP Server (TLS) id 14.3.266.1; Thu, 2 Nov 2017 18:04:32 +0530 Received: from nl20droid1.internal.synopsys.com (10.100.24.228) by IN01WEHTCA.internal.synopsys.com (10.144.199.243) with Microsoft SMTP Server (TLS) id 14.3.266.1; Thu, 2 Nov 2017 18:04:31 +0530 From: Claudiu Zissulescu To: CC: , , Subject: [PATCH 6/6] [ARC] Add 'aux' variable attribute. Date: Thu, 02 Nov 2017 12:34:00 -0000 Message-ID: <1509625835-22344-7-git-send-email-claziss@synopsys.com> In-Reply-To: <1509625835-22344-1-git-send-email-claziss@synopsys.com> References: <1509625835-22344-1-git-send-email-claziss@synopsys.com> MIME-Version: 1.0 Content-Type: text/plain X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 198.182.47.9 X-SW-Source: 2017-11/txt/msg00081.txt.bz2 From: claziss The 'aux' variable attribute is used to directly access the auxiliary register space from C. gcc/ 2017-07-25 Claudiu Zissulescu * config/arc/arc.c (arc_handle_aux_attribute): New function. (arc_attribute_table): Add 'aux' attribute. (arc_in_small_data_p): Consider aux like variables. (arc_is_aux_reg_p): New function. (arc_asm_output_aligned_decl_local): Ignore 'aux' like variables. (arc_get_aux_arg): New function. (prepare_move_operands): Handle aux-register access. (arc_handle_aux_attribute): New function. * doc/extend.texi (ARC Variable attributes): Add subsection. testsuite/ 2017-07-25 Claudiu Zissulescu * gcc.target/arc/taux-1.c: New test. * gcc.target/arc/taux-2.c: Likewise. --- gcc/config/arc/arc.c | 160 +++++++++++++++++++++++++++++++++- gcc/doc/extend.texi | 13 +++ gcc/testsuite/gcc.target/arc/taux-1.c | 38 ++++++++ gcc/testsuite/gcc.target/arc/taux-2.c | 15 ++++ 4 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/arc/taux-1.c create mode 100644 gcc/testsuite/gcc.target/arc/taux-2.c diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index a397cbd..33f68ef 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -223,6 +223,7 @@ static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *); static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *); static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *); static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *); +static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *); /* Initialized arc_attribute_table to NULL since arc doesnot have any machine specific supported attributes. */ @@ -257,6 +258,8 @@ const struct attribute_spec arc_attribute_table[] = /* Bypass caches using .di flag. */ { "uncached", 0, 0, false, true, false, arc_handle_uncached_attribute, false }, + /* Declare a variable as aux. */ + { "aux", 0, 1, true, false, false, arc_handle_aux_attribute, false }, { NULL, 0, 0, false, false, false, NULL, false } }; static int arc_comp_type_attributes (const_tree, const_tree); @@ -8071,6 +8074,11 @@ arc_in_small_data_p (const_tree decl) if (lookup_attribute ("uncached", attr)) return false; + /* and for aux regs. */ + attr = DECL_ATTRIBUTES (decl); + if (lookup_attribute ("aux", attr)) + return false; + if (DECL_SECTION_NAME (decl) != 0) { const char *name = DECL_SECTION_NAME (decl); @@ -8238,6 +8246,35 @@ compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p) return false; } +/* Return TRUE if PAT is accessing an aux-reg. */ + +static bool +arc_is_aux_reg_p (rtx pat) +{ + tree attrs = NULL_TREE; + tree addr; + + if (!MEM_P (pat)) + return false; + + /* Get the memory attributes. */ + addr = MEM_EXPR (pat); + if (!addr) + return false; + + /* Get the attributes. */ + if (TREE_CODE (addr) == VAR_DECL) + attrs = DECL_ATTRIBUTES (addr); + else if (TREE_CODE (addr) == MEM_REF) + attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0))); + else + return false; + + if (lookup_attribute ("aux", attrs)) + return true; + return false; +} + /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */ void @@ -8246,7 +8283,14 @@ arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name, unsigned HOST_WIDE_INT align, unsigned HOST_WIDE_INT globalize_p) { - int in_small_data = arc_in_small_data_p (decl); + int in_small_data = arc_in_small_data_p (decl); + rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl); + + /* Don't output aux-reg symbols. */ + if (mem != NULL_RTX && MEM_P (mem) + && SYMBOL_REF_P (XEXP (mem, 0)) + && arc_is_aux_reg_p (mem)) + return; if (in_small_data) switch_to_section (get_named_section (NULL, ".sbss", 0)); @@ -8586,12 +8630,80 @@ arc_expand_movmem (rtx *operands) return true; } +static bool +arc_get_aux_arg (rtx pat, int *auxr) +{ + tree attr, addr = MEM_EXPR (pat); + if (TREE_CODE (addr) != VAR_DECL) + return false; + + attr = DECL_ATTRIBUTES (addr); + if (lookup_attribute ("aux", attr)) + { + tree arg = TREE_VALUE (attr); + if (arg) + { + *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg)); + return true; + } + } + + return false; +} + /* Prepare operands for move in MODE. Return true iff the move has been emitted. */ bool prepare_move_operands (rtx *operands, machine_mode mode) { + /* First handle aux attribute. */ + if (mode == SImode + && (MEM_P (operands[0]) || MEM_P (operands[1]))) + { + rtx tmp; + int auxr = 0; + if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0])) + { + /* Save operation. */ + if (arc_get_aux_arg (operands[0], &auxr)) + { + tmp = gen_reg_rtx (SImode); + emit_move_insn (tmp, GEN_INT (auxr)); + } + else + { + tmp = XEXP (operands[0], 0); + } + + operands[1] = force_reg (SImode, operands[1]); + emit_insn (gen_rtx_UNSPEC_VOLATILE + (VOIDmode, gen_rtvec (2, operands[1], tmp), + VUNSPEC_ARC_SR)); + return true; + } + if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1])) + { + if (arc_get_aux_arg (operands[1], &auxr)) + { + tmp = gen_reg_rtx (SImode); + emit_move_insn (tmp, GEN_INT (auxr)); + } + else + { + tmp = XEXP (operands[1], 0); + gcc_assert (GET_CODE (tmp) == SYMBOL_REF); + } + /* Load operation. */ + gcc_assert (REG_P (operands[0])); + emit_insn (gen_rtx_SET (operands[0], + gen_rtx_UNSPEC_VOLATILE + (SImode, gen_rtvec (1, tmp), + VUNSPEC_ARC_LR))); + return true; + } + } + /* We used to do this only for MODE_INT Modes, but addresses to floating point variables may well be in the small data section. */ if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode)) @@ -11127,6 +11239,52 @@ arc_is_uncached_mem_p (rtx pat) return false; } +/* Handle aux attribute. The auxiliary registers are addressed using + special instructions lr and sr. The attribute 'aux' indicates if a + variable refers to the aux-regs and what is the register number + desired. */ + +static tree +arc_handle_aux_attribute (tree *node, + tree name, tree args, int, + bool *no_add_attrs) +{ + /* Isn't it better to use address spaces for the aux-regs? */ + if (DECL_P (*node)) + { + if (TREE_CODE (*node) != VAR_DECL) + { + error ("%qE attribute only applies to variables", name); + *no_add_attrs = true; + } + else if (args) + { + if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR) + TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0); + tree arg = TREE_VALUE (args); + if (TREE_CODE (arg) != INTEGER_CST) + { + warning (0, "%qE attribute allows only an integer " + "constant argument", name); + *no_add_attrs = true; + } + /* FIXME! add range check. TREE_INT_CST_LOW (arg) */ + } + + if (TREE_CODE (*node) == VAR_DECL) + { + tree fntype = TREE_TYPE (*node); + if (fntype && TREE_CODE (fntype) == POINTER_TYPE) + { + tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE, + TYPE_ATTRIBUTES (fntype)); + TYPE_ATTRIBUTES (fntype) = attrs; + } + } + } + return NULL_TREE; +} + /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use anchors for small data: the GP register acts as an anchor in that case. We also don't want to use them for PC-relative accesses, diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 0f8ba05..1f6ef4e 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5803,6 +5803,7 @@ attributes. @menu * Common Variable Attributes:: +* ARC Variable Attributes:: * AVR Variable Attributes:: * Blackfin Variable Attributes:: * H8/300 Variable Attributes:: @@ -6165,6 +6166,18 @@ The @code{weak} attribute is described in @end table +@node ARC Variable Attributes +@subsection ARC Variable Attributes + +@table @code +@item aux +@cindex @code{aux} variable attribute, ARC +The @code{aux} attribute is used to directly access the ARC's +auxiliary register space from C. The auxilirary register number is +given via attribute argument. + +@end table + @node AVR Variable Attributes @subsection AVR Variable Attributes diff --git a/gcc/testsuite/gcc.target/arc/taux-1.c b/gcc/testsuite/gcc.target/arc/taux-1.c new file mode 100644 index 0000000..a2b7778 --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/taux-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 */ + + +#define __aux() __attribute__((aux)) + +__aux() int *a_ptr; +extern __aux() int a_var; + +/* Generates: + mov r0, @a_var + sr 10,[r0] +*/ +void foo (void) +{ + a_var = 10; +} + +/* Generates: + mov r0, @a_ptr + sr a_var,[r0] +*/ +void foo1 (void) +{ + a_ptr = &a_var; +} + +/* Generates: + lr %r1,[a_ptr] + sr 10,[%r1] +*/ +void foo2 (void) +{ + *a_ptr = 10; +} + +/* { dg-final { scan-assembler-times "sr" 3 } } */ +/* { dg-final { scan-assembler-times "lr" 1 } } */ diff --git a/gcc/testsuite/gcc.target/arc/taux-2.c b/gcc/testsuite/gcc.target/arc/taux-2.c new file mode 100644 index 0000000..5644bcd --- /dev/null +++ b/gcc/testsuite/gcc.target/arc/taux-2.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 */ + +#define __aux(r) __attribute__((aux(r))) +static volatile __aux(0x1000) int var; + +int foo (void) +{ + var++; +} + +/* { dg-final { scan-assembler-times "sr" 1 } } */ +/* { dg-final { scan-assembler-times "lr" 1 } } */ +/* { dg-final { scan-assembler "4096" } } */ +/* { dg-final { scan-assembler-not "\\.type\tvar, @object" } } */ -- 1.9.1