Re: [patch,avr] Introduce absdata attribute to allow LDS /STS on Tiny

2016-10-14 Thread Denis Chertykov
2016-10-12 14:32 GMT+03:00 Georg-Johann Lay :
> This patch introduces a new variable attribute "absdata".
>
> Reduced Tiny cores have only a limited range of addresses 0x40..0xbf which
> can be handled by LDS / STS directly.  The attribute allows the user to
> assert that it is legitimate to use absolute addressing for such addresses
> and that there is no need for bulky load of address + indirect addressing.
>
> Allowed addresses actually range from 0x0 to 0xbf because IN / OUT can
> handle absolute addresses in the lower range 0x0..0x3f.
>
> Ok for trunk?
>

Approved.
Please apply.

> 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.
> (avr_address_cost) [AVR_TINY]: absdata addresses cost 2.
>
> gcc/testsuite/
> * lib/target-supports.exp (check_effective_target_avr_tiny): New
> proc.
> * gcc.target/avr/torture/tiny-absdata-1.c: New test.


[patch,avr] Introduce absdata attribute to allow LDS /STS on Tiny

2016-10-12 Thread Georg-Johann Lay

This patch introduces a new variable attribute "absdata".

Reduced Tiny cores have only a limited range of addresses 0x40..0xbf which can 
be handled by LDS / STS directly.  The attribute allows the user to assert that 
it is legitimate to use absolute addressing for such addresses and that there 
is no need for bulky load of address + indirect addressing.


Allowed addresses actually range from 0x0 to 0xbf because IN / OUT can handle 
absolute addresses in the lower range 0x0..0x3f.


Ok for trunk?

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.
(avr_address_cost) [AVR_TINY]: absdata addresses cost 2.

gcc/testsuite/
* lib/target-supports.exp (check_effective_target_avr_tiny): New proc.
* gcc.target/avr/torture/tiny-absdata-1.c: New test.
Index: doc/extend.texi
===
--- doc/extend.texi	(revision 240915)
+++ doc/extend.texi	(working copy)
@@ -5973,6 +5973,33 @@ 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 ATtiny40.
+
+@item
+You must make sure that respective data is located in the
+address range @code{0x40}@dots{}@code{0xbf} accessible by
+@code{LDS} and @code{STS}.  One way to achieve this as an
+appropriate linker description file.
+
+@item
+If the location does not fit the address range of @code{LDS}
+and @code{STS}, there is currently (Binutils 2.26) just an unspecific
+warning like
+@quotation
+@code{module.c:(.text+0x1c): warning: internal error: out of range error}
+@end quotation
+
+@end itemize
+
 @end table
 
 @node Blackfin Variable Attributes
Index: config/avr/avr.c
===
--- config/avr/avr.c	(revision 240966)
+++ config/avr/avr.c	(working copy)
@@ -84,6 +84,10 @@
 #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 "))"
@@ -1790,6 +1794,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
@@ -1874,8 +1900,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)
@@ -1917,8 +1942,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);
 }
@@ -9148,6 +9172,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