Index: config/avr/avr-arch.h
===================================================================
--- config/avr/avr-arch.h	(revision 241841)
+++ config/avr/avr-arch.h	(working copy)
@@ -157,7 +157,9 @@ enum avr_device_specific_features
   AVR_ISA_NONE,
   AVR_ISA_RMW     = 0x1, /* device has RMW instructions. */
   AVR_SHORT_SP    = 0x2, /* Stack Pointer has 8 bits width. */
-  AVR_ERRATA_SKIP = 0x4  /* device has a core erratum. */
+  AVR_ERRATA_SKIP = 0x4, /* device has a core erratum. */
+  AVR_ISA_LDS     = 0x8  /* whether LDS / STS is valid for all data in static
+                            storage.  Only useful for reduced Tiny.  */
 };
 
 /* Map architecture to its texinfo string.  */
Index: config/avr/avr-mcus.def
===================================================================
--- config/avr/avr-mcus.def	(revision 241841)
+++ config/avr/avr-mcus.def	(working copy)
@@ -341,11 +341,11 @@ AVR_MCU ("atxmega128a1u",    ARCH_AVRXME
 AVR_MCU ("atxmega128a4u",    ARCH_AVRXMEGA7, AVR_ISA_RMW,  "__AVR_ATxmega128A4U__",    0x2000, 0x0, 3)
 /* Tiny family */
 AVR_MCU ("avrtiny",          ARCH_AVRTINY, AVR_ISA_NONE, NULL,                     0x0040, 0x0, 1)
-AVR_MCU ("attiny4",          ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny4__",        0x0040, 0x0, 1)
-AVR_MCU ("attiny5",          ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny5__",        0x0040, 0x0, 1)
-AVR_MCU ("attiny9",          ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny9__",        0x0040, 0x0, 1) 
-AVR_MCU ("attiny10",         ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny10__",       0x0040, 0x0, 1)
-AVR_MCU ("attiny20",         ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny20__",       0x0040, 0x0, 1)
+AVR_MCU ("attiny4",          ARCH_AVRTINY, AVR_ISA_LDS,  "__AVR_ATtiny4__",        0x0040, 0x0, 1)
+AVR_MCU ("attiny5",          ARCH_AVRTINY, AVR_ISA_LDS,  "__AVR_ATtiny5__",        0x0040, 0x0, 1)
+AVR_MCU ("attiny9",          ARCH_AVRTINY, AVR_ISA_LDS,  "__AVR_ATtiny9__",        0x0040, 0x0, 1) 
+AVR_MCU ("attiny10",         ARCH_AVRTINY, AVR_ISA_LDS,  "__AVR_ATtiny10__",       0x0040, 0x0, 1)
+AVR_MCU ("attiny20",         ARCH_AVRTINY, AVR_ISA_LDS,  "__AVR_ATtiny20__",       0x0040, 0x0, 1)
 AVR_MCU ("attiny40",         ARCH_AVRTINY, AVR_ISA_NONE, "__AVR_ATtiny40__",       0x0040, 0x0, 1)
 /* Assembler only.  */
 AVR_MCU ("avr1",             ARCH_AVR1, AVR_ISA_NONE, NULL,                        0x0060, 0x0, 1)
Index: config/avr/avr.c
===================================================================
--- config/avr/avr.c	(revision 241841)
+++ config/avr/avr.c	(working copy)
@@ -10182,14 +10182,18 @@ avr_encode_section_info (tree decl, rtx
       && SYMBOL_REF_P (XEXP (rtl, 0)))
     {
       rtx sym = XEXP (rtl, 0);
+      bool progmem_p = -1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl));
 
-      if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
+      if (progmem_p)
         {
           // 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))
+          || (TARGET_ABSDATA
+              && !progmem_p
+              && !addr_attr)
           || (addr_attr
               // If addr_attr is non-null, it has an argument.  Peek into it.
               && TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (addr_attr))) < 0xc0))
@@ -10198,7 +10202,7 @@ avr_encode_section_info (tree decl, rtx
           SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_ABSDATA;
         }
 
-      if (-1 == avr_progmem_p (decl, DECL_ATTRIBUTES (decl))
+      if (progmem_p
           && avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl)))
         {
           error ("%q+D has incompatible attributes %qs and %qs",
Index: config/avr/avr.opt
===================================================================
--- config/avr/avr.opt	(revision 241841)
+++ config/avr/avr.opt	(working copy)
@@ -99,6 +99,10 @@ mfract-convert-truncate
 Target Report Mask(FRACT_CONV_TRUNC)
 Allow to use truncation instead of rounding towards zero for fractional fixed-point types.
 
+mabsdata
+Target Report Mask(ABSDATA)
+Assume that all data in static storage can be accessed by LDS / STS.  This option is only useful for reduced Tiny devices.
+
 nodevicelib
 Driver Target Report RejectNegative
 Do not link against the device-specific library lib<MCU>.a.
Index: config/avr/gen-avr-mmcu-specs.c
===================================================================
--- config/avr/gen-avr-mmcu-specs.c	(revision 241841)
+++ config/avr/gen-avr-mmcu-specs.c	(working copy)
@@ -130,6 +130,7 @@ for (arch_mcu = mcu; arch_mcu->macro; )
 
   FILE *f = fopen (name ,"w");
 
+  bool absdata = 0 != (mcu->dev_attribute & AVR_ISA_LDS);
   bool errata_skip = 0 != (mcu->dev_attribute & AVR_ERRATA_SKIP);
   bool rmw = 0 != (mcu->dev_attribute & AVR_ISA_RMW);
   bool sp8 = 0 != (mcu->dev_attribute & AVR_SHORT_SP);
@@ -189,6 +190,10 @@ bool is_arch = NULL == mcu->macro;
            ? "\t%{!mno-skip-bug: -mskip-bug}"
            : "\t%{!mskip-bug: -mno-skip-bug}");
 
+  fprintf (f, "*cc1_absdata:\n%s\n\n", absdata
+           ? "\t%{!mno-absdata: -mabsdata}"
+           : "\t%{mabsdata}");
+
   // avr-gcc specific specs for assembling / the assembler.
 
   fprintf (f, "*asm_arch:\n\t-mmcu=%s\n\n", arch->name);
Index: config/avr/specs.h
===================================================================
--- config/avr/specs.h	(revision 241841)
+++ config/avr/specs.h	(working copy)
@@ -34,7 +34,8 @@ along with GCC; see the file COPYING3.
 #define CC1_SPEC                                \
   "%(cc1_n_flash) "                             \
   "%(cc1_errata_skip) "                         \
-  "%(cc1_rmw) "
+  "%(cc1_rmw) "                                 \
+  "%(cc1_absdata) "
 
 #undef  CC1PLUS_SPEC
 #define CC1PLUS_SPEC                                    \
Index: doc/invoke.texi
===================================================================
--- doc/invoke.texi	(revision 241841)
+++ doc/invoke.texi	(working copy)
@@ -650,7 +650,8 @@ -remap -trigraphs  -undef  -U@var{macro}
 -mpure-code}
 
 @emph{AVR Options}
-@gccoptlist{-mmcu=@var{mcu} -maccumulate-args -mbranch-cost=@var{cost} @gol
+@gccoptlist{-mmcu=@var{mcu} -mabsdata -maccumulate-args @gol
+-mbranch-cost=@var{cost} @gol
 -mcall-prologues -mint8 -mn_flash=@var{size} -mno-interrupts @gol
 -mrelax -mrmw -mstrict-X -mtiny-stack -mfract-convert-truncate -nodevicelib @gol
 -Waddr-space-convert -Wmisspelled-isr}
@@ -15261,6 +15262,13 @@ GCC supports the following AVR devices a
 
 @include avr-mmcu.texi
 
+@item -mabsdata
+@opindex mabsdata
+
+Assume that all data in static stocage can be accessed by LDS / STS
+inctructions.  This option has only an effect on reduced Tiny devices like
+ATtiny40.
+
 @item -maccumulate-args
 @opindex maccumulate-args
 Accumulate outgoing function arguments and acquire/release the needed
Index: testsuite/gcc.target/avr/torture/tiny-absdata-2.c
===================================================================
--- testsuite/gcc.target/avr/torture/tiny-absdata-2.c	(nonexistent)
+++ testsuite/gcc.target/avr/torture/tiny-absdata-2.c	(working copy)
@@ -0,0 +1,85 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target avr_tiny } */
+/* { dg-options "-mabsdata" } */
+
+typedef struct
+{
+  char a, b, c;
+} abc_t;
+
+extern char varA;
+extern char varB;
+extern const char varC __attribute__((progmem));
+
+extern int arrayA[];
+extern int arrayB[];
+extern char arrayC[] __attribute__((address(0x80)));
+extern char arrayD[] __attribute__((address(0xc0)));
+
+extern abc_t abc;
+
+char get_1 (void)
+{
+  return varA;
+}
+
+int get_2 (void)
+{
+  return arrayA[3];
+}
+
+char get_3 (void)
+{
+  return abc.a + abc.b + abc.c;
+}
+
+char get_4 (void)
+{
+  return varC;
+}
+
+void put_1 (char b)
+{
+  varB = b;
+}
+
+void put_2 (int b)
+{
+  arrayB[3] = b;
+}
+
+void put_3 (void)
+{
+  abc.a = abc.b = abc.c = 0;
+}
+
+void put_4 (void)
+{
+  arrayC[0] = arrayC[1] = arrayC[2] = 0;
+}
+
+void put_5 (void)
+{
+  arrayD[0] = 0;
+}
+
+/* { dg-final { scan-assembler "lds r\[0-9\]+,varA" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,arrayA\\+6" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,arrayA\\+6\\+1" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,abc" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,abc\\+1" } } */
+/* { dg-final { scan-assembler "lds r\[0-9\]+,abc\\+2" } } */
+
+/* { dg-final { scan-assembler "sts varB," } } */
+/* { dg-final { scan-assembler "sts arrayB\\+6," } } */
+/* { dg-final { scan-assembler "sts arrayB\\+6\\+1," } } */
+/* { dg-final { scan-assembler "sts arrayC," } } */
+/* { dg-final { scan-assembler "sts arrayC\\+1," } } */
+/* { dg-final { scan-assembler "sts arrayC\\+2," } } */
+
+/* { dg-final { scan-assembler "sts abc," } } */
+/* { dg-final { scan-assembler "sts abc\\+1," } } */
+/* { dg-final { scan-assembler "sts abc\\+2," } } */
+
+/* { dg-final { scan-assembler-not "lds r\[0-9\]+,varC" } } */
+/* { dg-final { scan-assembler-not "sts arrayD," } } */
