From patchwork Wed Aug 3 16:17:15 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Georg-Johann Lay X-Patchwork-Id: 655500 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3s4JBY1JCZz9t0X for ; Thu, 4 Aug 2016 02:17:40 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Wfa1c2+i; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=D+r9JsAoqcT1P/mzHsVbVOvTEz0Ol1PWkNtGWEAKCr9IeXdptH CNc1id98F62HDswMpxJveFa2Y3wf7dBOhEtAMZkCyiO0Ip7qpetFwjRSpxpL/2oW tX4ujd2tKvjZqABmvSXG+vyh/Y9s5HNxVwBjd8p9ygQMlWACZXMXud6JA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to:cc :from:subject:message-id:date:mime-version:content-type; s= default; bh=MOtuJKZUyV/aFm4JMY6ZfriaRjY=; b=Wfa1c2+iLUUF76LPc2Ma m85ICiepjacqahq6FC/AGrw9KC+a8KZbs1avL46UUin9HX1yvdeXePg7XOJQCq6q y2MzVqqJ9Gm+JVb4eUqktzQN87QJPQ4TiNL9188HovruMeaSmcEXZKqyGuwr66fO DYThEN4IB16ytWHbej/UjsY= Received: (qmail 63478 invoked by alias); 3 Aug 2016 16:17:33 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 63469 invoked by uid 89); 3 Aug 2016 16:17:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.4 required=5.0 tests=AWL, BAYES_00, KAM_ASCII_DIVIDERS, KAM_STOCKGEN, RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=DECL_ATTRIBUTES, decl_attributes, tree_static, TREE_STATIC X-HELO: mo4-p00-ob.smtp.rzone.de Received: from mo4-p00-ob.smtp.rzone.de (HELO mo4-p00-ob.smtp.rzone.de) (81.169.146.220) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Wed, 03 Aug 2016 16:17:22 +0000 X-RZG-AUTH: :LXoWVUeid/7A29J/hMvvT3ol15ykJcYwTPLBCxG2PwtgsgUwIw== X-RZG-CLASS-ID: mo00 Received: from [192.168.0.143] (ip5f581faf.dynamic.kabel-deutschland.de [95.88.31.175]) by smtp.strato.de (RZmta 38.13 DYNA|AUTH) with ESMTPSA id n0a2fes73GHFoXm (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA (curve secp521r1 with 521 ECDH bits, eq. 15360 bits RSA)) (Client did not present a certificate); Wed, 3 Aug 2016 18:17:15 +0200 (CEST) To: gcc-patches Cc: Denis Chertykov , Senthil Kumar Selvaraj , Pitchumani Sivanupandi From: Georg-Johann Lay Subject: [avr, RFC, patch] Add var attribute "absdata" to support LDS / STS on AVR_TINY. Message-ID: <9680f386-48a4-9080-77db-e8dc93cdaa63@gjlay.de> Date: Wed, 3 Aug 2016 18:17:15 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 X-IsSubscribed: yes This is a proposal to support LDS / STS instructions on AVR_TINY. Currently the fact that the compile won't generate LDS / STS instructions is a major source of code bloat. The patch adds a new variable attribute so that the user can assert that address range of respective static-storage data will be in the range of LDS / STS (0x40...0xbf). There is currently no support in Binutils, and IMO support it in Binutils would be kind of overkill... Such support could implement new sections like .zdata, .zrodata, .zbss in the linker script which would be located before .data, .rodata, .bss. The compiler would put absdata objects into one of the z-sections, but we would have to supply extended startup-code because bss data is no more in one contiguous chunk of memory; same for [ro]data. More thoughts on how to get better support for LDS / STS? Johann gcc/ * doc/extend.texi (AVR Variable Attributes) [absdata]: Document it. * config/avr/avr.c (AVR_SYMBOL_FLAG_TINY_ABSDATA): New macro. (avr_address_tiny_absdata_p): New static function. (avr_legitimate_address_p, avr_legitimize_address) [AVR_TINY]: Use it to determine validity of constant addresses. (avr_attribute_table) [absdata]: New variable attribute... (avr_handle_absdata_attribute): ...and handler. (avr_decl_absdata_p): New static function. (avr_encode_section_info) [AVR_TINY]: Use it to add flag AVR_SYMBOL_FLAG_TINY_ABSDATA to respective symbols_refs. Index: doc/extend.texi =================================================================== --- doc/extend.texi (revision 238983) +++ doc/extend.texi (working copy) @@ -5957,6 +5957,25 @@ memory-mapped peripherals that may lie o volatile int porta __attribute__((address (0x600))); @end smallexample +@item absdata +@cindex @code{absdata} variable attribute, AVR +Variables in static storage and with the @code{absdata} attribute can +be accessed by the @code{LDS} and @code{STS} instructions which take +absolute addresses. + +@itemize @bullet +@item +This attribute is only supported for the reduced AVR Tiny core +like @code{ATtiny40}. + +@item +There is currently no Binutils support for this attribute and the user has +to make sure that respective data is located into an address range that +can actually be handled by @code{LDS} and @code{STS}. +This applies to addresses in the range @code{0x40}@dots{}@code{0xbf}. + +@end itemize + @end table @node Blackfin Variable Attributes Index: config/avr/avr.c =================================================================== --- config/avr/avr.c (revision 238983) +++ config/avr/avr.c (working copy) @@ -81,9 +81,13 @@ / SYMBOL_FLAG_MACH_DEP) /* (AVR_TINY only): Symbol has attribute progmem */ -#define AVR_SYMBOL_FLAG_TINY_PM \ +#define AVR_SYMBOL_FLAG_TINY_PM \ (SYMBOL_FLAG_MACH_DEP << 7) +/* (AVR_TINY only): Symbol has attribute absdata */ +#define AVR_SYMBOL_FLAG_TINY_ABSDATA \ + (SYMBOL_FLAG_MACH_DEP << 8) + #define TINY_ADIW(REG1, REG2, I) \ "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \ "sbci " #REG2 ",hi8(-(" #I "))" @@ -1802,6 +1806,28 @@ avr_mode_dependent_address_p (const_rtx } +/* Return true if rtx X is a CONST_INT, CONST or SYMBOL_REF + address with the `absdata' variable attribute, i.e. respective + data can be read / written by LDS / STS instruction. + This is used only for AVR_TINY. */ + +static bool +avr_address_tiny_absdata_p (rtx x, machine_mode mode) +{ + if (CONST == GET_CODE (x)) + x = XEXP (XEXP (x, 0), 0); + + if (SYMBOL_REF_P (x)) + return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_ABSDATA; + + if (CONST_INT_P (x) + && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode))) + return true; + + return false; +} + + /* Helper function for `avr_legitimate_address_p'. */ static inline bool @@ -1886,8 +1912,7 @@ avr_legitimate_address_p (machine_mode m /* avrtiny's load / store instructions only cover addresses 0..0xbf: IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf. */ - ok = (CONST_INT_P (x) - && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode))); + ok = avr_address_tiny_absdata_p (x, mode); } if (avr_log.legitimate_address_p) @@ -1929,8 +1954,7 @@ avr_legitimize_address (rtx x, rtx oldx, if (AVR_TINY) { if (CONSTANT_ADDRESS_P (x) - && !(CONST_INT_P (x) - && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)))) + && ! avr_address_tiny_absdata_p (x, mode)) { x = force_reg (Pmode, x); } @@ -9124,6 +9148,32 @@ avr_handle_fntype_attribute (tree *node, } static tree +avr_handle_absdata_attribute (tree *node, tree name, tree /* args */, + int /* flags */, bool *no_add) +{ + location_t loc = DECL_SOURCE_LOCATION (*node); + + if (AVR_TINY) + { + if (TREE_CODE (*node) != VAR_DECL + || (!TREE_STATIC (*node) && !DECL_EXTERNAL (*node))) + { + warning_at (loc, OPT_Wattributes, "%qE attribute only applies to" + " variables in static storage", name); + *no_add = true; + } + } + else + { + warning_at (loc, OPT_Wattributes, "%qE attribute only supported" + " for reduced Tiny cores", name); + *no_add = true; + } + + return NULL_TREE; +} + +static tree avr_handle_addr_attribute (tree *node, tree name, tree args, int flags ATTRIBUTE_UNUSED, bool *no_add) { @@ -9230,6 +9280,8 @@ avr_attribute_table[] = false }, { "address", 1, 1, false, false, false, avr_handle_addr_attribute, false }, + { "absdata", 0, 0, true, false, false, avr_handle_absdata_attribute, + false }, { NULL, 0, 0, false, false, false, NULL, false } }; @@ -9314,6 +9366,17 @@ avr_progmem_p (tree decl, tree attribute } +/* Return true if DECL has attribute `absdata' set. This function should + only be used for AVR_TINY. */ + +static bool +avr_decl_absdata_p (tree decl, tree attributes) +{ + return (TREE_CODE (decl) == VAR_DECL + && NULL_TREE != lookup_attribute ("absdata", attributes)); +} + + /* Scan type TYP for pointer references to address space ASn. Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting the AS are also declared to be CONST. @@ -9738,14 +9801,29 @@ avr_encode_section_info (tree decl, rtx if (AVR_TINY && decl && VAR_DECL == TREE_CODE (decl) - && -1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) && MEM_P (rtl) && SYMBOL_REF_P (XEXP (rtl, 0))) { - /* Tag symbols for later addition of 0x4000 (AVR_TINY_PM_OFFSET). */ - rtx sym = XEXP (rtl, 0); - SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM; + + if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl))) + { + // Tag symbols for later addition of 0x4000 (AVR_TINY_PM_OFFSET). + SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM; + } + + if (avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl))) + { + // May be accessed by LDS / STS. + SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_ABSDATA; + } + + if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) + && avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl))) + { + error ("%q+D has incompatible attributes %qs and %qs", + decl, "progmem", "absdata"); + } } }