public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
@ 2014-06-14 19:04 Barney Stratford
  2014-06-22 10:05 ` Barney Stratford
  2014-06-24  8:27 ` S, Pitchumani
  0 siblings, 2 replies; 5+ messages in thread
From: Barney Stratford @ 2014-06-14 19:04 UTC (permalink / raw)
  To: binutils

[-- Attachment #1: Type: text/plain, Size: 750 bytes --]

I’ve recently been working on getting the assembler and linker to work with the ATtiny40 family of microcontrollers. I’ve also added some functionality to the avr assembler in general. As this may be useful to others, I’m attaching my patches against the current git head. Can someone review and commit them please?

1_avrtiny10.patch contains the basic avrtiny10 code, including a linker reloc for the 16-bit version of the lds and sts instructions.

2_avr_io_relocs.patch allows you to refer to the I/O registers by symbol name.

3_avr_reg_name.patch allows you to refer to r26-r31 by name as /[xyz][hl]?/. It also fixes a bug that would prevent you from using a symbol whose name begins with ‘r’ to refer to a register.

Cheers,
Barney.

[-- Attachment #2: 1_avrtiny10.patch --]
[-- Type: application/octet-stream, Size: 47732 bytes --]

diff --git a/bfd/archures.c b/bfd/archures.c
index 9b47504..1b0ee4a 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -410,6 +410,7 @@ DESCRIPTION
 .#define bfd_mach_avr5		5
 .#define bfd_mach_avr51		51
 .#define bfd_mach_avr6		6
+.#define bfd_mach_avrtiny10 100
 .#define bfd_mach_avrxmega1 101
 .#define bfd_mach_avrxmega2 102
 .#define bfd_mach_avrxmega3 103
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d9056ce..63a4a13 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2195,6 +2195,7 @@ enum bfd_architecture
 #define bfd_mach_avr5          5
 #define bfd_mach_avr51         51
 #define bfd_mach_avr6          6
+#define bfd_mach_avrtiny10 100
 #define bfd_mach_avrxmega1 101
 #define bfd_mach_avrxmega2 102
 #define bfd_mach_avrxmega3 103
@@ -4475,6 +4476,10 @@ value.  */
   BFD_RELOC_AVR_DIFF16,
   BFD_RELOC_AVR_DIFF32,
 
+/* This is a 7 bit reloc for the AVR that stores a SRAM address for 
+the sts and lds instructions  */
+  BFD_RELOC_AVR_LDS_STS_16,
+
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
   BFD_RELOC_RL78_NEG16,
diff --git a/bfd/cpu-avr.c b/bfd/cpu-avr.c
index 060c9a2..faf5d73 100644
--- a/bfd/cpu-avr.c
+++ b/bfd/cpu-avr.c
@@ -135,23 +135,26 @@ static const bfd_arch_info_type arch_info_struct[] =
   /* 3-Byte PC.  */
   N (22, bfd_mach_avr6, "avr:6", FALSE, & arch_info_struct[10]),
 
+  /* attiny 10 */
+  N (16, bfd_mach_avrtiny10, "avr:100", FALSE, & arch_info_struct[11]),
+  
   /* Xmega 1 */
-  N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[11]),
+  N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[12]),
 
   /* Xmega 2 */
-  N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[12]),
+  N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[13]),
 
   /* Xmega 3 */
-  N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[13]),
+  N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[14]),
 
   /* Xmega 4 */
-  N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[14]),
+  N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[15]),
 
   /* Xmega 5 */
-  N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[15]),
+  N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[16]),
 
   /* Xmega 6 */
-  N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[16]),
+  N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[17]),
 
   /* Xmega 7 */
   N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL)
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index b46a44c..635b88d 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -604,7 +604,20 @@ static reloc_howto_type elf_avr_howto_table[] =
      FALSE,         /* partial_inplace */
      0,             /* src_mask */
      0xffffffff,    /* dst_mask */ 
-     FALSE)         /* pcrel_offset */
+     FALSE),        /* pcrel_offset */
+   HOWTO (R_AVR_LDS_STS_16,		/* type */
+     0,			/* rightshift */
+     0,			/* size (0 = byte, 1 = short, 2 = long) */
+     7,			/* bitsize */
+     FALSE,			/* pc_relative */
+     0,			/* bitpos */
+     complain_overflow_dont,/* complain_on_overflow */
+     bfd_elf_generic_reloc,	/* special_function */
+     "R_AVR_LDS_STS_16",	/* name */
+     FALSE,			/* partial_inplace */
+     0xffffff,		/* src_mask */
+     0xffffff,		/* dst_mask */
+     FALSE)		/* pcrel_offset */
 };
 
 /* Map BFD reloc types to AVR ELF reloc types.  */
@@ -649,7 +662,8 @@ static const struct avr_reloc_map avr_reloc_map[] =
   { BFD_RELOC_AVR_8_HLO,            R_AVR_8_HLO8 },
   { BFD_RELOC_AVR_DIFF8,            R_AVR_DIFF8 },
   { BFD_RELOC_AVR_DIFF16,           R_AVR_DIFF16 },
-  { BFD_RELOC_AVR_DIFF32,           R_AVR_DIFF32 }
+  { BFD_RELOC_AVR_DIFF32,           R_AVR_DIFF32 },
+  { BFD_RELOC_AVR_LDS_STS_16,       R_AVR_LDS_STS_16}
 };
 
 /* Meant to be filled one day with the wrap around address for the
@@ -1215,7 +1229,7 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
         }
 
       if (srel & 1)
-	return bfd_reloc_outofrange;
+        return bfd_reloc_outofrange;
       srel = srel >> 1;
       bfd_put_16 (input_bfd, (bfd_vma) srel &0x00ffff, contents);
       break;
@@ -1227,6 +1241,17 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       r = bfd_reloc_ok;
       break;
 
+    case R_AVR_LDS_STS_16:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if ((srel & 0xffff) < 0x40 || (srel & 0xffff)  > 0x139)
+        return bfd_reloc_outofrange;
+      x = bfd_get_16 (input_bfd, contents);
+      x = (x & 0xf8f0) | ((srel & 0x40) << 2) | ((srel & 0x30) << 5) |
+              (srel & 0x0f);
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+
     default:
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 				    contents, rel->r_offset,
@@ -1439,6 +1464,10 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
     case bfd_mach_avrxmega7:
       val = E_AVR_MACH_XMEGA7;
       break;
+
+    case bfd_mach_avrtiny10:
+      val = E_AVR_MACH_AVRTINY10;
+      break;
     }
 
   elf_elfheader (abfd)->e_machine = EM_AVR;
@@ -1529,6 +1558,10 @@ elf32_avr_object_p (bfd *abfd)
 	case E_AVR_MACH_XMEGA7:
 	  e_set = bfd_mach_avrxmega7;
 	  break;
+
+    case bfd_mach_avrtiny10:
+      e_set = E_AVR_MACH_AVRTINY10;
+      break;
 	}
     }
   return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 3bb3726..9452d12 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2041,6 +2041,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AVR_DIFF8",
   "BFD_RELOC_AVR_DIFF16",
   "BFD_RELOC_AVR_DIFF32",
+  "BFD_RELOC_AVR_LDS_STS_16",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 7f46c58..d7ccef2 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -4790,6 +4790,11 @@ ENUMDOC
   second symbol so the linker can determine whether to adjust the field
   value.
 ENUM
+  BFD_RELOC_AVR_LDS_STS_16
+ENUMDOC
+  This is a 7 bit reloc for the AVR that stores a SRAM address for
+  the sts and lds instructions
+ENUM
   BFD_RELOC_RL78_NEG8
 ENUMX
   BFD_RELOC_RL78_NEG16
diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c
index e4bc59c..826e0be 100644
--- a/gas/config/tc-avr.c
+++ b/gas/config/tc-avr.c
@@ -33,7 +33,7 @@ struct avr_opcodes_s
   char *        constraints;
   char *        opcode;
   int           insn_size;		/* In words.  */
-  int           isa;
+  long          isa;
   unsigned int  bin_opcode;
 };
 
@@ -54,7 +54,7 @@ const char *md_shortopts = "m:";
 struct mcu_type_s
 {
   char *name;
-  int isa;
+  long isa;
   int mach;
 };
 
@@ -89,6 +89,7 @@ static struct mcu_type_s mcu_types[] =
   {"avrxmega5",  AVR_ISA_XMEGA,   bfd_mach_avrxmega5},
   {"avrxmega6",  AVR_ISA_XMEGA,   bfd_mach_avrxmega6},
   {"avrxmega7",  AVR_ISA_XMEGA,   bfd_mach_avrxmega7},
+  {"avrtiny10",  AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
   {"at90s1200",  AVR_ISA_1200,    bfd_mach_avr1},
   {"attiny11",   AVR_ISA_AVR1,    bfd_mach_avr1},
   {"attiny12",   AVR_ISA_AVR1,    bfd_mach_avr1},
@@ -323,6 +324,12 @@ static struct mcu_type_s mcu_types[] =
   {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
   {"atxmega128a1u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
   {"atxmega128a4u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
+  {"attiny4",      AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
+  {"attiny5",      AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
+  {"attiny9",      AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
+  {"attiny10",     AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
+  {"attiny20",     AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
+  {"attiny40",     AVR_ISA_AVRTINY10, bfd_mach_avrtiny10},
   {NULL, 0, 0}
 };
 
@@ -513,6 +520,7 @@ md_show_usage (FILE *stream)
 	"                   avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n"
 	"                   avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n"
 	"                   avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n"
+	"                   avrtiny10 - tiny devices with 16 gp registers\n"
 	"                   or immediate microcontroller name.\n"));
   fprintf (stream,
       _("  -mall-opcodes    accept all AVR opcodes, even if not supported by MCU\n"
@@ -855,29 +863,44 @@ avr_operand (struct avr_opcodes_s *opcode,
     case 'a':
     case 'v':
       if (*str == 'r' || *str == 'R')
-	{
-	  char r_name[20];
+        {
+          char r_name[20];
 
-	  str = extract_word (str, r_name, sizeof (r_name));
-	  op_mask = 0xff;
-	  if (ISDIGIT (r_name[1]))
-	    {
-	      if (r_name[2] == '\0')
-		op_mask = r_name[1] - '0';
-	      else if (r_name[1] != '0'
-		       && ISDIGIT (r_name[2])
-		       && r_name[3] == '\0')
-		op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
-	    }
-	}
+          str = extract_word (str, r_name, sizeof (r_name));
+          op_mask = 0xff;
+          if (ISDIGIT (r_name[1]))
+            {
+              if (r_name[2] == '\0')
+                op_mask = r_name[1] - '0';
+              else if (r_name[1] != '0'
+                       && ISDIGIT (r_name[2])
+                       && r_name[3] == '\0')
+                op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
+            }
+        }
       else
-	{
-	  op_mask = avr_get_constant (str, 31);
-	  str = input_line_pointer;
-	}
-
-      if (op_mask <= 31)
-	{
+        {
+          op_mask = avr_get_constant (str, 31);
+          str = input_line_pointer;
+        }
+
+      if (avr_mcu->isa & AVR_ISA_FEW_REGS)
+        {
+          if (op_mask < 16 || op_mask >= 32)
+            {
+              as_bad (_("register name or number from 16 to 31 required"));
+              break;
+            }
+        }
+      else
+        {
+          if (op_mask >= 32)
+            {
+              as_bad (_("register name or number from 0 to 31 required"));
+              break;
+            }
+        }
+      
 	  switch (*op)
 	    {
 	    case 'a':
@@ -905,9 +928,6 @@ avr_operand (struct avr_opcodes_s *opcode,
 	      break;
 	    }
 	  break;
-	}
-      as_bad (_("register name or number from 0 to 31 required"));
-      break;
 
     case 'e':
       {
@@ -1086,6 +1106,12 @@ avr_operand (struct avr_opcodes_s *opcode,
 	op_mask |= (x << 4);
       }
       break;
+    
+    case 'm':
+      str = parse_exp (str, &op_expr);
+      fix_new_exp (frag_now, where, opcode->insn_size * 2,
+		     &op_expr, FALSE, BFD_RELOC_AVR_LDS_STS_16);
+	  break;
 
     case '?':
       break;
@@ -1512,6 +1538,14 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
           *where = 0xff & (value >> 16);
           break;
 
+    case BFD_RELOC_AVR_LDS_STS_16:
+	  if ((value < 64) || (value > 191))
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("operand out of range: %ld"), value);
+      bfd_putl16 ((bfd_vma) insn | ((value & 0x40) << 2) | ((value & 0x30) << 5) |
+              (value & 0x0f), where);
+	  break;
+
         default:
 	  as_fatal (_("line %d: unknown relocation type: 0x%x"),
 		    fixP->fx_line, fixP->fx_r_type);
@@ -1602,10 +1636,13 @@ md_assemble (char *str)
 
   /* Special case for opcodes with optional operands (lpm, elpm) -
      version with operands exists in avr_opcodes[] in the next entry.  */
-
   if (*str && *opcode->constraints == '?')
     ++opcode;
 
+  /* Special case for opcodes STS and LDS that come in 16-bit and 32-bit versions */
+  if (*str && (opcode->isa & AVR_ISA_BIGRAM) && !(avr_mcu->isa & AVR_ISA_BIGRAM))
+    ++opcode;
+ 
   if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)
     as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);
 
diff --git a/include/elf/avr.h b/include/elf/avr.h
index 06a7f13..b81371d 100644
--- a/include/elf/avr.h
+++ b/include/elf/avr.h
@@ -40,6 +40,7 @@
 #define E_AVR_MACH_AVR5     5
 #define E_AVR_MACH_AVR51   51
 #define E_AVR_MACH_AVR6     6 
+#define E_AVR_MACH_AVRTINY10 100
 #define E_AVR_MACH_XMEGA1 101
 #define E_AVR_MACH_XMEGA2 102
 #define E_AVR_MACH_XMEGA3 103
@@ -50,16 +51,16 @@
 
 /* Relocations.  */
 START_RELOC_NUMBERS (elf_avr_reloc_type)
-     RELOC_NUMBER (R_AVR_NONE,			0)
-     RELOC_NUMBER (R_AVR_32,			1)
-     RELOC_NUMBER (R_AVR_7_PCREL,		2)
-     RELOC_NUMBER (R_AVR_13_PCREL,		3)
-     RELOC_NUMBER (R_AVR_16, 			4)
-     RELOC_NUMBER (R_AVR_16_PM, 		5)
-     RELOC_NUMBER (R_AVR_LO8_LDI,		6)
-     RELOC_NUMBER (R_AVR_HI8_LDI,		7)
-     RELOC_NUMBER (R_AVR_HH8_LDI,		8)
-     RELOC_NUMBER (R_AVR_LO8_LDI_NEG,		9)
+     RELOC_NUMBER (R_AVR_NONE,                  0)
+     RELOC_NUMBER (R_AVR_32,                    1)
+     RELOC_NUMBER (R_AVR_7_PCREL,               2)
+     RELOC_NUMBER (R_AVR_13_PCREL,              3)
+     RELOC_NUMBER (R_AVR_16,                    4)
+     RELOC_NUMBER (R_AVR_16_PM,                 5)
+     RELOC_NUMBER (R_AVR_LO8_LDI,               6)
+     RELOC_NUMBER (R_AVR_HI8_LDI,               7)
+     RELOC_NUMBER (R_AVR_HH8_LDI,               8)
+     RELOC_NUMBER (R_AVR_LO8_LDI_NEG,           9)
      RELOC_NUMBER (R_AVR_HI8_LDI_NEG,	       10)
      RELOC_NUMBER (R_AVR_HH8_LDI_NEG,	       11)
      RELOC_NUMBER (R_AVR_LO8_LDI_PM,	       12)
@@ -68,7 +69,7 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
      RELOC_NUMBER (R_AVR_LO8_LDI_PM_NEG,       15)
      RELOC_NUMBER (R_AVR_HI8_LDI_PM_NEG,       16)
      RELOC_NUMBER (R_AVR_HH8_LDI_PM_NEG,       17)
-     RELOC_NUMBER (R_AVR_CALL,		       18)
+     RELOC_NUMBER (R_AVR_CALL,                 18)
      RELOC_NUMBER (R_AVR_LDI,                  19)
      RELOC_NUMBER (R_AVR_6,                    20)
      RELOC_NUMBER (R_AVR_6_ADIW,               21)
@@ -76,13 +77,14 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
      RELOC_NUMBER (R_AVR_MS8_LDI_NEG,          23)
      RELOC_NUMBER (R_AVR_LO8_LDI_GS,	       24)
      RELOC_NUMBER (R_AVR_HI8_LDI_GS,	       25)
-     RELOC_NUMBER (R_AVR_8, 		       26)
+     RELOC_NUMBER (R_AVR_8,                    26)
      RELOC_NUMBER (R_AVR_8_LO8,                27)
      RELOC_NUMBER (R_AVR_8_HI8,                28)
      RELOC_NUMBER (R_AVR_8_HLO8,               29)
      RELOC_NUMBER (R_AVR_DIFF8,                30)
      RELOC_NUMBER (R_AVR_DIFF16,               31)
      RELOC_NUMBER (R_AVR_DIFF32,               32)
+     RELOC_NUMBER (R_AVR_LDS_STS_16,           33)
 END_RELOC_NUMBERS (R_AVR_max)
 
 #endif /* _ELF_AVR_H */
diff --git a/include/opcode/avr.h b/include/opcode/avr.h
index e33f46d..f723f0f 100644
--- a/include/opcode/avr.h
+++ b/include/opcode/avr.h
@@ -18,25 +18,27 @@
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#define AVR_ISA_1200  0x0001 /* In the beginning there was ...  */
-#define AVR_ISA_LPM   0x0002 /* device has LPM */
-#define AVR_ISA_LPMX  0x0004 /* device has LPM Rd,Z[+] */
-#define AVR_ISA_SRAM  0x0008 /* device has SRAM (LD, ST, PUSH, POP, ...) */
-#define AVR_ISA_MEGA  0x0020 /* device has >8K program memory (JMP and CALL
+#define AVR_ISA_1200     0x00001 /* In the beginning there was ...  */
+#define AVR_ISA_LPM      0x00002 /* device has LPM */
+#define AVR_ISA_LPMX     0x00004 /* device has LPM Rd,Z[+] */
+#define AVR_ISA_SRAM     0x00008 /* device has SRAM (LD, ST, PUSH, POP, ...) */
+#define AVR_ISA_MEGA     0x00020 /* device has >8K program memory (JMP and CALL
 				supported, no 8K wrap on RJMP and RCALL) */
-#define AVR_ISA_MUL   0x0040 /* device has new core (MUL, FMUL, ...) */
-#define AVR_ISA_ELPM  0x0080 /* device has >64K program memory (ELPM) */
-#define AVR_ISA_ELPMX 0x0100 /* device has ELPM Rd,Z[+] */
-#define AVR_ISA_SPM   0x0200 /* device can program itself */
-#define AVR_ISA_BRK   0x0400 /* device has BREAK (on-chip debug) */
-#define AVR_ISA_EIND  0x0800 /* device has >128K program memory (none yet) */
-#define AVR_ISA_MOVW  0x1000 /* device has MOVW */
-#define AVR_ISA_SPMX  0x2000 /* device has SPM Z[+] */
-#define AVR_ISA_DES   0x4000 /* device has DES */
-#define AVR_ISA_RMW   0x8000 /* device has RMW instructions XCH,LAC,LAS,LAT */
+#define AVR_ISA_MUL      0x00040 /* device has new core (MUL, FMUL, ...) */
+#define AVR_ISA_ELPM     0x00080 /* device has >64K program memory (ELPM) */
+#define AVR_ISA_ELPMX    0x00100 /* device has ELPM Rd,Z[+] */
+#define AVR_ISA_SPM      0x00200 /* device can program itself */
+#define AVR_ISA_BRK      0x00400 /* device has BREAK (on-chip debug) */
+#define AVR_ISA_EIND     0x00800 /* device has >128K program memory (none yet) */
+#define AVR_ISA_MOVW     0x01000 /* device has MOVW */
+#define AVR_ISA_SPMX     0x02000 /* device has SPM Z[+] */
+#define AVR_ISA_DES      0x04000 /* device has DES */
+#define AVR_ISA_RMW      0x08000 /* device has RMW instructions XCH,LAC,LAS,LAT */
+#define AVR_ISA_BIGRAM   0x10000 /* device has 32-bit STS and LDS */
+#define AVR_ISA_FEW_REGS 0x20000 /* device has only r16 - r31 */
 
 #define AVR_ISA_TINY1 (AVR_ISA_1200 | AVR_ISA_LPM)
-#define AVR_ISA_2xxx  (AVR_ISA_TINY1 | AVR_ISA_SRAM)
+#define AVR_ISA_2xxx  (AVR_ISA_TINY1 | AVR_ISA_SRAM | AVR_ISA_BIGRAM)
 /* For the attiny26 which is missing LPM Rd,Z+.  */
 #define AVR_ISA_2xxe  (AVR_ISA_2xxx | AVR_ISA_LPMX)
 #define AVR_ISA_RF401 (AVR_ISA_2xxx | AVR_ISA_MOVW | AVR_ISA_LPMX)
@@ -71,6 +73,8 @@
                         AVR_ISA_SRAM | AVR_ISA_MEGA | AVR_ISA_MUL | \
                         AVR_ISA_ELPM | AVR_ISA_ELPMX | AVR_ISA_SPM | \
                         AVR_ISA_BRK | AVR_ISA_EIND | AVR_ISA_MOVW)
+#define AVR_ISA_AVRTINY10 (AVR_ISA_1200 | AVR_ISA_BRK | AVR_ISA_SRAM | \
+                           AVR_ISA_FEW_REGS)
 
 #define REGISTER_P(x) ((x) == 'r'		\
 		       || (x) == 'd'		\
@@ -104,6 +108,7 @@
    b - base pointer register and displacement ([YZ]+disp)
    z - Z pointer register (for [e]lpm Rd,Z[+])
    M - immediate value from 0 to 255
+   m - immediate value from 64 to 192
    n - immediate value from 0 to 255 ( n = ~M ). Relocation impossible
    s - immediate value from 0 to 7
    P - Port address value from 0 to 63. (in, out)
@@ -138,163 +143,165 @@
    "11111xxxxxxx1xxx" (1024) 0xf[8-9a-f][0-9a-f][8-9a-f]
  */
 
-AVR_INSN (clc,  "",    "1001010010001000", 1, AVR_ISA_1200, 0x9488)
-AVR_INSN (clh,  "",    "1001010011011000", 1, AVR_ISA_1200, 0x94d8)
-AVR_INSN (cli,  "",    "1001010011111000", 1, AVR_ISA_1200, 0x94f8)
-AVR_INSN (cln,  "",    "1001010010101000", 1, AVR_ISA_1200, 0x94a8)
-AVR_INSN (cls,  "",    "1001010011001000", 1, AVR_ISA_1200, 0x94c8)
-AVR_INSN (clt,  "",    "1001010011101000", 1, AVR_ISA_1200, 0x94e8)
-AVR_INSN (clv,  "",    "1001010010111000", 1, AVR_ISA_1200, 0x94b8)
-AVR_INSN (clz,  "",    "1001010010011000", 1, AVR_ISA_1200, 0x9498)
-
-AVR_INSN (sec,  "",    "1001010000001000", 1, AVR_ISA_1200, 0x9408)
-AVR_INSN (seh,  "",    "1001010001011000", 1, AVR_ISA_1200, 0x9458)
-AVR_INSN (sei,  "",    "1001010001111000", 1, AVR_ISA_1200, 0x9478)
-AVR_INSN (sen,  "",    "1001010000101000", 1, AVR_ISA_1200, 0x9428)
-AVR_INSN (ses,  "",    "1001010001001000", 1, AVR_ISA_1200, 0x9448)
-AVR_INSN (set,  "",    "1001010001101000", 1, AVR_ISA_1200, 0x9468)
-AVR_INSN (sev,  "",    "1001010000111000", 1, AVR_ISA_1200, 0x9438)
-AVR_INSN (sez,  "",    "1001010000011000", 1, AVR_ISA_1200, 0x9418)
+AVR_INSN (clc,    "",    "1001010010001000", 1, AVR_ISA_1200,   0x9488)
+AVR_INSN (clh,    "",    "1001010011011000", 1, AVR_ISA_1200,   0x94d8)
+AVR_INSN (cli,    "",    "1001010011111000", 1, AVR_ISA_1200,   0x94f8)
+AVR_INSN (cln,    "",    "1001010010101000", 1, AVR_ISA_1200,   0x94a8)
+AVR_INSN (cls,    "",    "1001010011001000", 1, AVR_ISA_1200,   0x94c8)
+AVR_INSN (clt,    "",    "1001010011101000", 1, AVR_ISA_1200,   0x94e8)
+AVR_INSN (clv,    "",    "1001010010111000", 1, AVR_ISA_1200,   0x94b8)
+AVR_INSN (clz,    "",    "1001010010011000", 1, AVR_ISA_1200,   0x9498)
+
+AVR_INSN (sec,    "",    "1001010000001000", 1, AVR_ISA_1200,   0x9408)
+AVR_INSN (seh,    "",    "1001010001011000", 1, AVR_ISA_1200,   0x9458)
+AVR_INSN (sei,    "",    "1001010001111000", 1, AVR_ISA_1200,   0x9478)
+AVR_INSN (sen,    "",    "1001010000101000", 1, AVR_ISA_1200,   0x9428)
+AVR_INSN (ses,    "",    "1001010001001000", 1, AVR_ISA_1200,   0x9448)
+AVR_INSN (set,    "",    "1001010001101000", 1, AVR_ISA_1200,   0x9468)
+AVR_INSN (sev,    "",    "1001010000111000", 1, AVR_ISA_1200,   0x9438)
+AVR_INSN (sez,    "",    "1001010000011000", 1, AVR_ISA_1200,   0x9418)
 
    /* Same as {cl,se}[chinstvz] above.  */
-AVR_INSN (bclr, "S",   "100101001SSS1000", 1, AVR_ISA_1200, 0x9488)
-AVR_INSN (bset, "S",   "100101000SSS1000", 1, AVR_ISA_1200, 0x9408)
-
-AVR_INSN (icall,"",    "1001010100001001", 1, AVR_ISA_2xxx, 0x9509)
-AVR_INSN (ijmp, "",    "1001010000001001", 1, AVR_ISA_2xxx, 0x9409)
-
-AVR_INSN (lpm,  "?",   "1001010111001000", 1, AVR_ISA_TINY1,0x95c8)
-AVR_INSN (lpm,  "r,z", "1001000ddddd010+", 1, AVR_ISA_LPMX, 0x9004)
-AVR_INSN (elpm, "?",   "1001010111011000", 1, AVR_ISA_ELPM, 0x95d8)
-AVR_INSN (elpm, "r,z", "1001000ddddd011+", 1, AVR_ISA_ELPMX,0x9006)
-
-AVR_INSN (nop,  "",    "0000000000000000", 1, AVR_ISA_1200, 0x0000)
-AVR_INSN (ret,  "",    "1001010100001000", 1, AVR_ISA_1200, 0x9508)
-AVR_INSN (reti, "",    "1001010100011000", 1, AVR_ISA_1200, 0x9518)
-AVR_INSN (sleep,"",    "1001010110001000", 1, AVR_ISA_1200, 0x9588)
-AVR_INSN (break,"",    "1001010110011000", 1, AVR_ISA_BRK,  0x9598)
-AVR_INSN (wdr,  "",    "1001010110101000", 1, AVR_ISA_1200, 0x95a8)
-AVR_INSN (spm,  "?",   "1001010111101000", 1, AVR_ISA_SPM,  0x95e8)
-AVR_INSN (spm,  "z",   "10010101111+1000", 1, AVR_ISA_SPMX, 0x95e8)
-
-AVR_INSN (adc,  "r,r", "000111rdddddrrrr", 1, AVR_ISA_1200, 0x1c00)
-AVR_INSN (add,  "r,r", "000011rdddddrrrr", 1, AVR_ISA_1200, 0x0c00)
-AVR_INSN (and,  "r,r", "001000rdddddrrrr", 1, AVR_ISA_1200, 0x2000)
-AVR_INSN (cp,   "r,r", "000101rdddddrrrr", 1, AVR_ISA_1200, 0x1400)
-AVR_INSN (cpc,  "r,r", "000001rdddddrrrr", 1, AVR_ISA_1200, 0x0400)
-AVR_INSN (cpse, "r,r", "000100rdddddrrrr", 1, AVR_ISA_1200, 0x1000)
-AVR_INSN (eor,  "r,r", "001001rdddddrrrr", 1, AVR_ISA_1200, 0x2400)
-AVR_INSN (mov,  "r,r", "001011rdddddrrrr", 1, AVR_ISA_1200, 0x2c00)
-AVR_INSN (mul,  "r,r", "100111rdddddrrrr", 1, AVR_ISA_MUL,  0x9c00)
-AVR_INSN (or,   "r,r", "001010rdddddrrrr", 1, AVR_ISA_1200, 0x2800)
-AVR_INSN (sbc,  "r,r", "000010rdddddrrrr", 1, AVR_ISA_1200, 0x0800)
-AVR_INSN (sub,  "r,r", "000110rdddddrrrr", 1, AVR_ISA_1200, 0x1800)
+AVR_INSN (bclr,   "S",   "100101001SSS1000", 1, AVR_ISA_1200,   0x9488)
+AVR_INSN (bset,   "S",   "100101000SSS1000", 1, AVR_ISA_1200,   0x9408)
+
+AVR_INSN (icall,  "",    "1001010100001001", 1, AVR_ISA_SRAM,   0x9509)
+AVR_INSN (ijmp,   "",    "1001010000001001", 1, AVR_ISA_SRAM,   0x9409)
+
+AVR_INSN (lpm,    "?",   "1001010111001000", 1, AVR_ISA_TINY1,  0x95c8)
+AVR_INSN (lpm,    "r,z", "1001000ddddd010+", 1, AVR_ISA_LPMX,   0x9004)
+AVR_INSN (elpm,   "?",   "1001010111011000", 1, AVR_ISA_ELPM,   0x95d8)
+AVR_INSN (elpm,   "r,z", "1001000ddddd011+", 1, AVR_ISA_ELPMX,  0x9006)
+
+AVR_INSN (nop,    "",    "0000000000000000", 1, AVR_ISA_1200,   0x0000)
+AVR_INSN (ret,    "",    "1001010100001000", 1, AVR_ISA_1200,   0x9508)
+AVR_INSN (reti,   "",    "1001010100011000", 1, AVR_ISA_1200,   0x9518)
+AVR_INSN (sleep,  "",    "1001010110001000", 1, AVR_ISA_1200,   0x9588)
+AVR_INSN (break,  "",    "1001010110011000", 1, AVR_ISA_BRK,    0x9598)
+AVR_INSN (wdr,    "",    "1001010110101000", 1, AVR_ISA_1200,   0x95a8)
+AVR_INSN (spm,    "?",   "1001010111101000", 1, AVR_ISA_SPM,    0x95e8)
+AVR_INSN (spm,    "z",   "10010101111+1000", 1, AVR_ISA_SPMX,   0x95e8)
+
+AVR_INSN (adc,    "r,r", "000111rdddddrrrr", 1, AVR_ISA_1200,   0x1c00)
+AVR_INSN (add,    "r,r", "000011rdddddrrrr", 1, AVR_ISA_1200,   0x0c00)
+AVR_INSN (and,    "r,r", "001000rdddddrrrr", 1, AVR_ISA_1200,   0x2000)
+AVR_INSN (cp,     "r,r", "000101rdddddrrrr", 1, AVR_ISA_1200,   0x1400)
+AVR_INSN (cpc,    "r,r", "000001rdddddrrrr", 1, AVR_ISA_1200,   0x0400)
+AVR_INSN (cpse,   "r,r", "000100rdddddrrrr", 1, AVR_ISA_1200,   0x1000)
+AVR_INSN (eor,    "r,r", "001001rdddddrrrr", 1, AVR_ISA_1200,   0x2400)
+AVR_INSN (mov,    "r,r", "001011rdddddrrrr", 1, AVR_ISA_1200,   0x2c00)
+AVR_INSN (mul,    "r,r", "100111rdddddrrrr", 1, AVR_ISA_MUL,    0x9c00)
+AVR_INSN (or,     "r,r", "001010rdddddrrrr", 1, AVR_ISA_1200,   0x2800)
+AVR_INSN (sbc,    "r,r", "000010rdddddrrrr", 1, AVR_ISA_1200,   0x0800)
+AVR_INSN (sub,    "r,r", "000110rdddddrrrr", 1, AVR_ISA_1200,   0x1800)
 
    /* Shorthand for {eor,add,adc,and} r,r above.  */
-AVR_INSN (clr,  "r=r", "001001rdddddrrrr", 1, AVR_ISA_1200, 0x2400)
-AVR_INSN (lsl,  "r=r", "000011rdddddrrrr", 1, AVR_ISA_1200, 0x0c00)
-AVR_INSN (rol,  "r=r", "000111rdddddrrrr", 1, AVR_ISA_1200, 0x1c00)
-AVR_INSN (tst,  "r=r", "001000rdddddrrrr", 1, AVR_ISA_1200, 0x2000)
+AVR_INSN (clr,    "r=r", "001001rdddddrrrr", 1, AVR_ISA_1200,   0x2400)
+AVR_INSN (lsl,    "r=r", "000011rdddddrrrr", 1, AVR_ISA_1200,   0x0c00)
+AVR_INSN (rol,    "r=r", "000111rdddddrrrr", 1, AVR_ISA_1200,   0x1c00)
+AVR_INSN (tst,    "r=r", "001000rdddddrrrr", 1, AVR_ISA_1200,   0x2000)
 
-AVR_INSN (andi, "d,M", "0111KKKKddddKKKK", 1, AVR_ISA_1200, 0x7000)
+AVR_INSN (andi,   "d,M", "0111KKKKddddKKKK", 1, AVR_ISA_1200,   0x7000)
   /*XXX special case*/
-AVR_INSN (cbr,  "d,n", "0111KKKKddddKKKK", 1, AVR_ISA_1200, 0x7000)
-
-AVR_INSN (ldi,  "d,M", "1110KKKKddddKKKK", 1, AVR_ISA_1200, 0xe000)
-AVR_INSN (ser,  "d",   "11101111dddd1111", 1, AVR_ISA_1200, 0xef0f)
-
-AVR_INSN (ori,  "d,M", "0110KKKKddddKKKK", 1, AVR_ISA_1200, 0x6000)
-AVR_INSN (sbr,  "d,M", "0110KKKKddddKKKK", 1, AVR_ISA_1200, 0x6000)
-
-AVR_INSN (cpi,  "d,M", "0011KKKKddddKKKK", 1, AVR_ISA_1200, 0x3000)
-AVR_INSN (sbci, "d,M", "0100KKKKddddKKKK", 1, AVR_ISA_1200, 0x4000)
-AVR_INSN (subi, "d,M", "0101KKKKddddKKKK", 1, AVR_ISA_1200, 0x5000)
-
-AVR_INSN (sbrc, "r,s", "1111110rrrrr0sss", 1, AVR_ISA_1200, 0xfc00)
-AVR_INSN (sbrs, "r,s", "1111111rrrrr0sss", 1, AVR_ISA_1200, 0xfe00)
-AVR_INSN (bld,  "r,s", "1111100ddddd0sss", 1, AVR_ISA_1200, 0xf800)
-AVR_INSN (bst,  "r,s", "1111101ddddd0sss", 1, AVR_ISA_1200, 0xfa00)
-
-AVR_INSN (in,   "r,P", "10110PPdddddPPPP", 1, AVR_ISA_1200, 0xb000)
-AVR_INSN (out,  "P,r", "10111PPrrrrrPPPP", 1, AVR_ISA_1200, 0xb800)
-
-AVR_INSN (adiw, "w,K", "10010110KKddKKKK", 1, AVR_ISA_2xxx, 0x9600)
-AVR_INSN (sbiw, "w,K", "10010111KKddKKKK", 1, AVR_ISA_2xxx, 0x9700)
-
-AVR_INSN (cbi,  "p,s", "10011000pppppsss", 1, AVR_ISA_1200, 0x9800)
-AVR_INSN (sbi,  "p,s", "10011010pppppsss", 1, AVR_ISA_1200, 0x9a00)
-AVR_INSN (sbic, "p,s", "10011001pppppsss", 1, AVR_ISA_1200, 0x9900)
-AVR_INSN (sbis, "p,s", "10011011pppppsss", 1, AVR_ISA_1200, 0x9b00)
-
-AVR_INSN (brcc, "l",   "111101lllllll000", 1, AVR_ISA_1200, 0xf400)
-AVR_INSN (brcs, "l",   "111100lllllll000", 1, AVR_ISA_1200, 0xf000)
-AVR_INSN (breq, "l",   "111100lllllll001", 1, AVR_ISA_1200, 0xf001)
-AVR_INSN (brge, "l",   "111101lllllll100", 1, AVR_ISA_1200, 0xf404)
-AVR_INSN (brhc, "l",   "111101lllllll101", 1, AVR_ISA_1200, 0xf405)
-AVR_INSN (brhs, "l",   "111100lllllll101", 1, AVR_ISA_1200, 0xf005)
-AVR_INSN (brid, "l",   "111101lllllll111", 1, AVR_ISA_1200, 0xf407)
-AVR_INSN (brie, "l",   "111100lllllll111", 1, AVR_ISA_1200, 0xf007)
-AVR_INSN (brlo, "l",   "111100lllllll000", 1, AVR_ISA_1200, 0xf000)
-AVR_INSN (brlt, "l",   "111100lllllll100", 1, AVR_ISA_1200, 0xf004)
-AVR_INSN (brmi, "l",   "111100lllllll010", 1, AVR_ISA_1200, 0xf002)
-AVR_INSN (brne, "l",   "111101lllllll001", 1, AVR_ISA_1200, 0xf401)
-AVR_INSN (brpl, "l",   "111101lllllll010", 1, AVR_ISA_1200, 0xf402)
-AVR_INSN (brsh, "l",   "111101lllllll000", 1, AVR_ISA_1200, 0xf400)
-AVR_INSN (brtc, "l",   "111101lllllll110", 1, AVR_ISA_1200, 0xf406)
-AVR_INSN (brts, "l",   "111100lllllll110", 1, AVR_ISA_1200, 0xf006)
-AVR_INSN (brvc, "l",   "111101lllllll011", 1, AVR_ISA_1200, 0xf403)
-AVR_INSN (brvs, "l",   "111100lllllll011", 1, AVR_ISA_1200, 0xf003)
+AVR_INSN (cbr,    "d,n", "0111KKKKddddKKKK", 1, AVR_ISA_1200,   0x7000)
+
+AVR_INSN (ldi,    "d,M", "1110KKKKddddKKKK", 1, AVR_ISA_1200,   0xe000)
+AVR_INSN (ser,    "d",   "11101111dddd1111", 1, AVR_ISA_1200,   0xef0f)
+
+AVR_INSN (ori,    "d,M", "0110KKKKddddKKKK", 1, AVR_ISA_1200,   0x6000)
+AVR_INSN (sbr,    "d,M", "0110KKKKddddKKKK", 1, AVR_ISA_1200,   0x6000)
+
+AVR_INSN (cpi,    "d,M", "0011KKKKddddKKKK", 1, AVR_ISA_1200,   0x3000)
+AVR_INSN (sbci,   "d,M", "0100KKKKddddKKKK", 1, AVR_ISA_1200,   0x4000)
+AVR_INSN (subi,   "d,M", "0101KKKKddddKKKK", 1, AVR_ISA_1200,   0x5000)
+
+AVR_INSN (sbrc,   "r,s", "1111110rrrrr0sss", 1, AVR_ISA_1200,   0xfc00)
+AVR_INSN (sbrs,   "r,s", "1111111rrrrr0sss", 1, AVR_ISA_1200,   0xfe00)
+AVR_INSN (bld,    "r,s", "1111100ddddd0sss", 1, AVR_ISA_1200,   0xf800)
+AVR_INSN (bst,    "r,s", "1111101ddddd0sss", 1, AVR_ISA_1200,   0xfa00)
+
+AVR_INSN (in,     "r,P", "10110PPdddddPPPP", 1, AVR_ISA_1200,   0xb000)
+AVR_INSN (out,    "P,r", "10111PPrrrrrPPPP", 1, AVR_ISA_1200,   0xb800)
+
+AVR_INSN (adiw,   "w,K", "10010110KKddKKKK", 1, AVR_ISA_2xxx,   0x9600)
+AVR_INSN (sbiw,   "w,K", "10010111KKddKKKK", 1, AVR_ISA_2xxx,   0x9700)
+
+AVR_INSN (cbi,    "p,s", "10011000pppppsss", 1, AVR_ISA_1200,   0x9800)
+AVR_INSN (sbi,    "p,s", "10011010pppppsss", 1, AVR_ISA_1200,   0x9a00)
+AVR_INSN (sbic,   "p,s", "10011001pppppsss", 1, AVR_ISA_1200,   0x9900)
+AVR_INSN (sbis,   "p,s", "10011011pppppsss", 1, AVR_ISA_1200,   0x9b00)
+
+AVR_INSN (brcc,   "l",   "111101lllllll000", 1, AVR_ISA_1200,   0xf400)
+AVR_INSN (brcs,   "l",   "111100lllllll000", 1, AVR_ISA_1200,   0xf000)
+AVR_INSN (breq,   "l",   "111100lllllll001", 1, AVR_ISA_1200,   0xf001)
+AVR_INSN (brge,   "l",   "111101lllllll100", 1, AVR_ISA_1200,   0xf404)
+AVR_INSN (brhc,   "l",   "111101lllllll101", 1, AVR_ISA_1200,   0xf405)
+AVR_INSN (brhs,   "l",   "111100lllllll101", 1, AVR_ISA_1200,   0xf005)
+AVR_INSN (brid,   "l",   "111101lllllll111", 1, AVR_ISA_1200,   0xf407)
+AVR_INSN (brie,   "l",   "111100lllllll111", 1, AVR_ISA_1200,   0xf007)
+AVR_INSN (brlo,   "l",   "111100lllllll000", 1, AVR_ISA_1200,   0xf000)
+AVR_INSN (brlt,   "l",   "111100lllllll100", 1, AVR_ISA_1200,   0xf004)
+AVR_INSN (brmi,   "l",   "111100lllllll010", 1, AVR_ISA_1200,   0xf002)
+AVR_INSN (brne,   "l",   "111101lllllll001", 1, AVR_ISA_1200,   0xf401)
+AVR_INSN (brpl,   "l",   "111101lllllll010", 1, AVR_ISA_1200,   0xf402)
+AVR_INSN (brsh,   "l",   "111101lllllll000", 1, AVR_ISA_1200,   0xf400)
+AVR_INSN (brtc,   "l",   "111101lllllll110", 1, AVR_ISA_1200,   0xf406)
+AVR_INSN (brts,   "l",   "111100lllllll110", 1, AVR_ISA_1200,   0xf006)
+AVR_INSN (brvc,   "l",   "111101lllllll011", 1, AVR_ISA_1200,   0xf403)
+AVR_INSN (brvs,   "l",   "111100lllllll011", 1, AVR_ISA_1200,   0xf003)
 
    /* Same as br?? above.  */
-AVR_INSN (brbc, "s,l", "111101lllllllsss", 1, AVR_ISA_1200, 0xf400)
-AVR_INSN (brbs, "s,l", "111100lllllllsss", 1, AVR_ISA_1200, 0xf000)
-
-AVR_INSN (rcall, "L",  "1101LLLLLLLLLLLL", 1, AVR_ISA_1200, 0xd000)
-AVR_INSN (rjmp,  "L",  "1100LLLLLLLLLLLL", 1, AVR_ISA_1200, 0xc000)
-
-AVR_INSN (call, "h",   "1001010hhhhh111h", 2, AVR_ISA_MEGA, 0x940e)
-AVR_INSN (jmp,  "h",   "1001010hhhhh110h", 2, AVR_ISA_MEGA, 0x940c)
-
-AVR_INSN (asr,  "r",   "1001010rrrrr0101", 1, AVR_ISA_1200, 0x9405)
-AVR_INSN (com,  "r",   "1001010rrrrr0000", 1, AVR_ISA_1200, 0x9400)
-AVR_INSN (dec,  "r",   "1001010rrrrr1010", 1, AVR_ISA_1200, 0x940a)
-AVR_INSN (inc,  "r",   "1001010rrrrr0011", 1, AVR_ISA_1200, 0x9403)
-AVR_INSN (lsr,  "r",   "1001010rrrrr0110", 1, AVR_ISA_1200, 0x9406)
-AVR_INSN (neg,  "r",   "1001010rrrrr0001", 1, AVR_ISA_1200, 0x9401)
-AVR_INSN (pop,  "r",   "1001000rrrrr1111", 1, AVR_ISA_2xxx, 0x900f)
-AVR_INSN (push, "r",   "1001001rrrrr1111", 1, AVR_ISA_2xxx, 0x920f)
-AVR_INSN (ror,  "r",   "1001010rrrrr0111", 1, AVR_ISA_1200, 0x9407)
-AVR_INSN (swap, "r",   "1001010rrrrr0010", 1, AVR_ISA_1200, 0x9402)
+AVR_INSN (brbc,   "s,l", "111101lllllllsss", 1, AVR_ISA_1200,   0xf400)
+AVR_INSN (brbs,   "s,l", "111100lllllllsss", 1, AVR_ISA_1200,   0xf000)
+
+AVR_INSN (rcall,  "L",   "1101LLLLLLLLLLLL", 1, AVR_ISA_1200,   0xd000)
+AVR_INSN (rjmp,   "L",   "1100LLLLLLLLLLLL", 1, AVR_ISA_1200,   0xc000)
+
+AVR_INSN (call,   "h",   "1001010hhhhh111h", 2, AVR_ISA_MEGA,   0x940e)
+AVR_INSN (jmp,    "h",   "1001010hhhhh110h", 2, AVR_ISA_MEGA,   0x940c)
+
+AVR_INSN (asr,    "r",   "1001010rrrrr0101", 1, AVR_ISA_1200,   0x9405)
+AVR_INSN (com,    "r",   "1001010rrrrr0000", 1, AVR_ISA_1200,   0x9400)
+AVR_INSN (dec,    "r",   "1001010rrrrr1010", 1, AVR_ISA_1200,   0x940a)
+AVR_INSN (inc,    "r",   "1001010rrrrr0011", 1, AVR_ISA_1200,   0x9403)
+AVR_INSN (lsr,    "r",   "1001010rrrrr0110", 1, AVR_ISA_1200,   0x9406)
+AVR_INSN (neg,    "r",   "1001010rrrrr0001", 1, AVR_ISA_1200,   0x9401)
+AVR_INSN (pop,    "r",   "1001000rrrrr1111", 1, AVR_ISA_SRAM,   0x900f)
+AVR_INSN (push,   "r",   "1001001rrrrr1111", 1, AVR_ISA_SRAM,   0x920f)
+AVR_INSN (ror,    "r",   "1001010rrrrr0111", 1, AVR_ISA_1200,   0x9407)
+AVR_INSN (swap,   "r",   "1001010rrrrr0010", 1, AVR_ISA_1200,   0x9402)
 
    /* Atomic memory operations for XMEGA.  List before `sts'.  */
-AVR_INSN (xch,  "z,r",   "1001001rrrrr0100", 1, AVR_ISA_RMW, 0x9204)
-AVR_INSN (las,  "z,r",   "1001001rrrrr0101", 1, AVR_ISA_RMW, 0x9205)
-AVR_INSN (lac,  "z,r",   "1001001rrrrr0110", 1, AVR_ISA_RMW, 0x9206)
-AVR_INSN (lat,  "z,r",   "1001001rrrrr0111", 1, AVR_ISA_RMW, 0x9207)
+AVR_INSN (xch,    "z,r", "1001001rrrrr0100", 1, AVR_ISA_RMW,    0x9204)
+AVR_INSN (las,    "z,r", "1001001rrrrr0101", 1, AVR_ISA_RMW,    0x9205)
+AVR_INSN (lac,    "z,r", "1001001rrrrr0110", 1, AVR_ISA_RMW,    0x9206)
+AVR_INSN (lat,    "z,r", "1001001rrrrr0111", 1, AVR_ISA_RMW,    0x9207)
 
    /* Known to be decoded as `nop' by the old core.  */
-AVR_INSN (movw, "v,v", "00000001ddddrrrr", 1, AVR_ISA_MOVW, 0x0100)
-AVR_INSN (muls, "d,d", "00000010ddddrrrr", 1, AVR_ISA_MUL,  0x0200)
-AVR_INSN (mulsu,"a,a", "000000110ddd0rrr", 1, AVR_ISA_MUL,  0x0300)
-AVR_INSN (fmul, "a,a", "000000110ddd1rrr", 1, AVR_ISA_MUL,  0x0308)
-AVR_INSN (fmuls,"a,a", "000000111ddd0rrr", 1, AVR_ISA_MUL,  0x0380)
-AVR_INSN (fmulsu,"a,a","000000111ddd1rrr", 1, AVR_ISA_MUL,  0x0388)
-
-AVR_INSN (sts,  "i,r", "1001001ddddd0000", 2, AVR_ISA_2xxx, 0x9200)
-AVR_INSN (lds,  "r,i", "1001000ddddd0000", 2, AVR_ISA_2xxx, 0x9000)
+AVR_INSN (movw,   "v,v", "00000001ddddrrrr", 1, AVR_ISA_MOVW,   0x0100)
+AVR_INSN (muls,   "d,d", "00000010ddddrrrr", 1, AVR_ISA_MUL,    0x0200)
+AVR_INSN (mulsu,  "a,a", "000000110ddd0rrr", 1, AVR_ISA_MUL,    0x0300)
+AVR_INSN (fmul,   "a,a", "000000110ddd1rrr", 1, AVR_ISA_MUL,    0x0308)
+AVR_INSN (fmuls,  "a,a", "000000111ddd0rrr", 1, AVR_ISA_MUL,    0x0380)
+AVR_INSN (fmulsu, "a,a", "000000111ddd1rrr", 1, AVR_ISA_MUL,    0x0388)
+
+AVR_INSN (sts,    "i,r", "1001001ddddd0000", 2, AVR_ISA_BIGRAM, 0x9200)
+AVR_INSN (sts,    "m,d", "10101KKKddddKKKK", 1, AVR_ISA_SRAM,   0xa800)
+AVR_INSN (lds,    "r,i", "1001000ddddd0000", 2, AVR_ISA_BIGRAM, 0x9000)
+AVR_INSN (lds,    "d,m", "10100KKKddddKKKK", 1, AVR_ISA_SRAM,   0xa000)
 
    /* Special case for b+0, `e' must be next entry after `b',
       b={Y=1,Z=0}, ee={X=11,Y=10,Z=00}, !=1 if -e or e+ or X.  */
-AVR_INSN (ldd,  "r,b", "10o0oo0dddddbooo", 1, AVR_ISA_2xxx, 0x8000)
-AVR_INSN (ld,   "r,e", "100!000dddddee-+", 1, AVR_ISA_1200, 0x8000)
-AVR_INSN (std,  "b,r", "10o0oo1rrrrrbooo", 1, AVR_ISA_2xxx, 0x8200)
-AVR_INSN (st,   "e,r", "100!001rrrrree-+", 1, AVR_ISA_1200, 0x8200)
+AVR_INSN (ldd,    "r,b", "10o0oo0dddddbooo", 1, AVR_ISA_2xxx,   0x8000)
+AVR_INSN (ld,     "r,e", "100!000dddddee-+", 1, AVR_ISA_1200,   0x8000)
+AVR_INSN (std,    "b,r", "10o0oo1rrrrrbooo", 1, AVR_ISA_2xxx,   0x8200)
+AVR_INSN (st,     "e,r", "100!001rrrrree-+", 1, AVR_ISA_1200,   0x8200)
 
    /* These are for devices that don't exist yet
       (>128K program memory, PC = EIND:Z).  */
-AVR_INSN (eicall, "",  "1001010100011001", 1, AVR_ISA_EIND, 0x9519)
-AVR_INSN (eijmp, "",   "1001010000011001", 1, AVR_ISA_EIND, 0x9419)
+AVR_INSN (eicall, "",   "1001010100011001", 1, AVR_ISA_EIND,    0x9519)
+AVR_INSN (eijmp,  "",   "1001010000011001", 1, AVR_ISA_EIND,    0x9419)
 
 /* DES instruction for encryption and decryption */
-AVR_INSN (des,  "E",   "10010100EEEE1011", 1, AVR_ISA_DES,  0x940B)
+AVR_INSN (des,    "E",  "10010100EEEE1011", 1, AVR_ISA_DES,     0x940B)
 
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 66795b3..ff54fa8 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -192,6 +192,7 @@ ALL_EMULATION_SOURCES = \
 	eavrxmega5.c \
 	eavrxmega6.c \
 	eavrxmega7.c \
+	eavrtiny10.c \
 	ecoff_i860.c \
 	ecoff_sparc.c \
 	ecrisaout.c \
@@ -840,6 +841,10 @@ eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \
   $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \
   ${GEN_DEPENDS}
 
+eavrtiny10.c: $(srcdir)/emulparams/avrtiny10.sh \
+  $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avrtiny10.sc \
+  ${GEN_DEPENDS}
+
 ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS}
 
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 6a534ca..e4ac505 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -499,6 +499,7 @@ ALL_EMULATION_SOURCES = \
 	eavrxmega5.c \
 	eavrxmega6.c \
 	eavrxmega7.c \
+	eavrtiny10.c \
 	ecoff_i860.c \
 	ecoff_sparc.c \
 	ecrisaout.c \
@@ -1090,6 +1091,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega5.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega6.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega7.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny10.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecoff_i860.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecoff_sparc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecrisaout.Po@am__quote@
@@ -2277,6 +2279,10 @@ eavrxmega6.c: $(srcdir)/emulparams/avrxmega6.sh \
 eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \
   $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \
   ${GEN_DEPENDS}
+  
+eavrtiny10.c: $(srcdir)/emulparams/avrtiny10.sh \
+  $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \
+  ${GEN_DEPENDS}
 
 ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS}
diff --git a/ld/configure.tgt b/ld/configure.tgt
index 0eb743d..5ab0c16 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -138,7 +138,7 @@ arm*-*-uclinux*)	targ_emul=armelf_linux
 arm-*-vxworks)		targ_emul=armelf_vxworks ;;
 arm*-*-conix*)		targ_emul=armelf ;;
 avr-*-*)		targ_emul=avr2
-			targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7"
+			targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny10"
 			;;
 bfin-*-elf)		targ_emul=elf32bfin;
 			targ_extra_emuls="elf32bfinfd"
diff --git a/ld/emulparams/avrtiny10.sh b/ld/emulparams/avrtiny10.sh
new file mode 100644
index 0000000..0a41e2d
--- /dev/null
+++ b/ld/emulparams/avrtiny10.sh
@@ -0,0 +1,13 @@
+ARCH=avr:100
+MACHINE=
+SCRIPT_NAME=avrtiny10
+OUTPUT_FORMAT="elf32-avr"
+MAXPAGESIZE=1
+EMBEDDED=yes
+TEMPLATE_NAME=elf32
+
+TEXT_ORIGIN=0x0
+TEXT_LENGTH=4K
+DATA_ORIGIN=0x0800040
+DATA_LENGTH=0x1F
+EXTRA_EM_FILE=avrelf
diff --git a/ld/scripttempl/avrtiny10.sc b/ld/scripttempl/avrtiny10.sc
new file mode 100644
index 0000000..2175b0a
--- /dev/null
+++ b/ld/scripttempl/avrtiny10.sc
@@ -0,0 +1,240 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+MEMORY
+{
+  text   (rx)   : ORIGIN = $TEXT_ORIGIN, LENGTH = $TEXT_LENGTH
+  data   (rw!x) : ORIGIN = $DATA_ORIGIN, LENGTH = $DATA_LENGTH
+  lock      (rw!x) : ORIGIN = 0x3F00, LENGTH = 2
+  signature (rw!x) : ORIGIN = 0x3FC0, LENGTH = 4
+/* REVISIT: fuse(rw!x) : */
+}
+
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  ${TEXT_DYNAMIC+${DYNAMIC}}
+  .hash        ${RELOCATING-0} : { *(.hash)		}
+  .dynsym      ${RELOCATING-0} : { *(.dynsym)		}
+  .dynstr      ${RELOCATING-0} : { *(.dynstr)		}
+  .gnu.version ${RELOCATING-0} : { *(.gnu.version)	}
+  .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d)	}
+  .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r)	}
+
+  .rel.init    ${RELOCATING-0} : { *(.rel.init)		}
+  .rela.init   ${RELOCATING-0} : { *(.rela.init)	}
+  .rel.text    ${RELOCATING-0} :
+    {
+      *(.rel.text)
+      ${RELOCATING+*(.rel.text.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.t*)}
+    }
+  .rela.text   ${RELOCATING-0} :
+    {
+      *(.rela.text)
+      ${RELOCATING+*(.rela.text.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.t*)}
+    }
+  .rel.fini    ${RELOCATING-0} : { *(.rel.fini)		}
+  .rela.fini   ${RELOCATING-0} : { *(.rela.fini)	}
+  .rel.rodata  ${RELOCATING-0} :
+    {
+      *(.rel.rodata)
+      ${RELOCATING+*(.rel.rodata.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.r*)}
+    }
+  .rela.rodata ${RELOCATING-0} :
+    {
+      *(.rela.rodata)
+      ${RELOCATING+*(.rela.rodata.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.r*)}
+    }
+  .rel.data    ${RELOCATING-0} :
+    {
+      *(.rel.data)
+      ${RELOCATING+*(.rel.data.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.d*)}
+    }
+  .rela.data   ${RELOCATING-0} :
+    {
+      *(.rela.data)
+      ${RELOCATING+*(.rela.data.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.d*)}
+    }
+  .rel.ctors   ${RELOCATING-0} : { *(.rel.ctors)	}
+  .rela.ctors  ${RELOCATING-0} : { *(.rela.ctors)	}
+  .rel.dtors   ${RELOCATING-0} : { *(.rel.dtors)	}
+  .rela.dtors  ${RELOCATING-0} : { *(.rela.dtors)	}
+  .rel.got     ${RELOCATING-0} : { *(.rel.got)		}
+  .rela.got    ${RELOCATING-0} : { *(.rela.got)		}
+  .rel.bss     ${RELOCATING-0} : { *(.rel.bss)		}
+  .rela.bss    ${RELOCATING-0} : { *(.rela.bss)		}
+  .rel.plt     ${RELOCATING-0} : { *(.rel.plt)		}
+  .rela.plt    ${RELOCATING-0} : { *(.rela.plt)		}
+
+  /* Internal text space or external memory.  */
+  .text ${RELOCATING-0} : ${RELOCATING+ AT (0x0)}
+  {
+    *(.vectors)
+    KEEP(*(.vectors))
+
+    /* For data that needs to reside in the lower 64k of progmem.  */
+    *(.progmem.gcc*)
+    *(.progmem*)
+    ${RELOCATING+. = ALIGN(2);}
+
+    ${CONSTRUCTING+ __trampolines_start = . ; }
+    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
+    *(.trampolines)
+    *(.trampolines*)
+    ${CONSTRUCTING+ __trampolines_end = . ; }
+
+    /* For future tablejump instruction arrays for 3 byte pc devices.
+       We don't relax jump/call instructions within these sections.  */
+    *(.jumptables) 
+    *(.jumptables*) 
+
+    /* For code that needs to reside in the lower 128k progmem.  */
+    *(.lowtext)
+    *(.lowtext*)
+
+    ${CONSTRUCTING+ __ctors_start = . ; }
+    ${CONSTRUCTING+ *(.ctors) }
+    ${CONSTRUCTING+ __ctors_end = . ; }
+    ${CONSTRUCTING+ __dtors_start = . ; }
+    ${CONSTRUCTING+ *(.dtors) }
+    ${CONSTRUCTING+ __dtors_end = . ; }
+    KEEP(SORT(*)(.ctors))
+    KEEP(SORT(*)(.dtors))
+
+    /* From this point on, we don't bother about wether the insns are
+       below or above the 16 bits boundary.  */
+    *(.init0)  /* Start here after reset.  */
+    KEEP (*(.init0))
+    *(.init1)
+    KEEP (*(.init1))
+    *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */
+    KEEP (*(.init2))
+    *(.init3)
+    KEEP (*(.init3))
+    *(.init4)  /* Initialize data and BSS.  */
+    KEEP (*(.init4))
+    *(.init5)
+    KEEP (*(.init5))
+    *(.init6)  /* C++ constructors.  */
+    KEEP (*(.init6))
+    *(.init7)
+    KEEP (*(.init7))
+    *(.init8)
+    KEEP (*(.init8))
+    *(.init9)  /* Call main().  */
+    KEEP (*(.init9))
+    *(.text)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.text.*)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.fini9)  /* _exit() starts here.  */
+    KEEP (*(.fini9))
+    *(.fini8)
+    KEEP (*(.fini8))
+    *(.fini7)
+    KEEP (*(.fini7))
+    *(.fini6)  /* C++ destructors.  */
+    KEEP (*(.fini6))
+    *(.fini5)
+    KEEP (*(.fini5))
+    *(.fini4)
+    KEEP (*(.fini4))
+    *(.fini3)
+    KEEP (*(.fini3))
+    *(.fini2)
+    KEEP (*(.fini2))
+    *(.fini1)
+    KEEP (*(.fini1))
+    *(.fini0)  /* Infinite loop after program termination.  */
+    KEEP (*(.fini0))
+    ${RELOCATING+ _etext = . ; }
+  } ${RELOCATING+ > text}
+
+  .data	${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
+  {
+    ${RELOCATING+ PROVIDE (__data_start = .) ; }
+    *(.data)
+    *(.data*)
+    *(.rodata)  /* We need to include .rodata here if gcc is used */
+    *(.rodata*) /* with -fdata-sections.  */
+    *(.gnu.linkonce.d*)
+    ${RELOCATING+. = ALIGN(2);}
+    ${RELOCATING+ _edata = . ; }
+    ${RELOCATING+ PROVIDE (__data_end = .) ; }
+  } ${RELOCATING+ > data}
+
+  .bss ${RELOCATING-0} :${RELOCATING+ AT (ADDR (.bss))}
+  {
+    ${RELOCATING+ PROVIDE (__bss_start = .) ; }
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+    ${RELOCATING+ PROVIDE (__bss_end = .) ; }
+  } ${RELOCATING+ > data}
+
+  ${RELOCATING+ __data_load_start = LOADADDR(.data); }
+  ${RELOCATING+ __data_load_end = __data_load_start + SIZEOF(.data); }
+
+  /* Global data not cleared after reset.  */
+  .noinit ${RELOCATING-0}:
+  {
+    ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
+    *(.noinit*)
+    ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
+    ${RELOCATING+ _end = . ;  }
+    ${RELOCATING+ PROVIDE (__heap_start = .) ; }
+  } ${RELOCATING+ > data}
+
+  .lock ${RELOCATING-0}:
+  {
+    KEEP(*(.lock*))
+  } ${RELOCATING+ > lock}
+
+  .signature ${RELOCATING-0}:
+  {
+    KEEP(*(.signature*))
+  } ${RELOCATING+ > signature}
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+ 
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+}
+EOF
+
diff --git a/opcodes/avr-dis.c b/opcodes/avr-dis.c
index 9a8ae33..737c9ea 100644
--- a/opcodes/avr-dis.c
+++ b/opcodes/avr-dis.c
@@ -32,7 +32,7 @@ struct avr_opcodes_s
   char *constraints;
   char *opcode;
   int insn_size;		/* In words.  */
-  int isa;
+  long isa;
   unsigned int bin_opcode;
 };
 
@@ -191,6 +191,13 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
       sprintf (buf, "0x%02X", ((insn & 0xf00) >> 4) | (insn & 0xf));
       sprintf (comment, "%d", ((insn & 0xf00) >> 4) | (insn & 0xf));
       break;
+    
+    case 'm':
+      sprintf (buf, "0x%02X", ((~insn & 0x100) >> 1) | ((insn & 0x100) >> 2) | 
+                               ((insn & 0x600) >> 5) | (insn & 0xf));
+      sprintf (comment, "%d", ((~insn & 0x100) >> 1) | ((insn & 0x100) >> 2) | 
+                               ((insn & 0x600) >> 5) | (insn & 0xf));
+      break;
 
     case 'n':
       sprintf (buf, "??");

[-- Attachment #3: 2_avr_io_relocs.patch --]
[-- Type: application/octet-stream, Size: 6494 bytes --]

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 63a4a13..bc6787f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -4480,6 +4480,14 @@ value.  */
 the sts and lds instructions  */
   BFD_RELOC_AVR_LDS_STS_16,
 
+/* This is a 6 bit reloc for the AVR that stores an I/O register
+number for the IN and OUT instructions  */
+  BFD_RELOC_AVR_PORT6,
+
+/* This is a 5 bit reloc for the AVR that stores an I/O register
+number for the SBIC, SBIS, SBI and CBI instructions  */
+  BFD_RELOC_AVR_PORT5,
+
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
   BFD_RELOC_RL78_NEG16,
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index 635b88d..f3962f2 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -617,7 +617,33 @@ static reloc_howto_type elf_avr_howto_table[] =
      FALSE,			/* partial_inplace */
      0xffffff,		/* src_mask */
      0xffffff,		/* dst_mask */
-     FALSE)		/* pcrel_offset */
+     FALSE),		/* pcrel_offset */
+   HOWTO (R_AVR_PORT6,		/* type */
+     0,			/* rightshift */
+     0,			/* size (0 = byte, 1 = short, 2 = long) */
+     6,			/* bitsize */
+     FALSE,			/* pc_relative */
+     0,			/* bitpos */
+     complain_overflow_dont,/* complain_on_overflow */
+     bfd_elf_generic_reloc,	/* special_function */
+     "R_AVR_PORT6",	/* name */
+     FALSE,			/* partial_inplace */
+     0xffffff,		/* src_mask */
+     0xffffff,		/* dst_mask */
+     FALSE),		/* pcrel_offset */
+   HOWTO (R_AVR_PORT5,		/* type */
+     0,			/* rightshift */
+     0,			/* size (0 = byte, 1 = short, 2 = long) */
+     5,			/* bitsize */
+     FALSE,			/* pc_relative */
+     0,			/* bitpos */
+     complain_overflow_dont,/* complain_on_overflow */
+     bfd_elf_generic_reloc,	/* special_function */
+     "R_AVR_PORT5",	/* name */
+     FALSE,			/* partial_inplace */
+     0xffffff,		/* src_mask */
+     0xffffff,		/* dst_mask */
+     FALSE) 		/* pcrel_offset */
 };
 
 /* Map BFD reloc types to AVR ELF reloc types.  */
@@ -663,7 +689,9 @@ static const struct avr_reloc_map avr_reloc_map[] =
   { BFD_RELOC_AVR_DIFF8,            R_AVR_DIFF8 },
   { BFD_RELOC_AVR_DIFF16,           R_AVR_DIFF16 },
   { BFD_RELOC_AVR_DIFF32,           R_AVR_DIFF32 },
-  { BFD_RELOC_AVR_LDS_STS_16,       R_AVR_LDS_STS_16}
+  { BFD_RELOC_AVR_LDS_STS_16,       R_AVR_LDS_STS_16},
+  { BFD_RELOC_AVR_PORT6,            R_AVR_PORT6},
+  { BFD_RELOC_AVR_PORT5,            R_AVR_PORT5}
 };
 
 /* Meant to be filled one day with the wrap around address for the
@@ -1252,6 +1280,26 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       bfd_put_16 (input_bfd, x, contents);
       break;
 
+    case R_AVR_PORT6:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if ((srel & 0xffff) > 0x3f)
+        return bfd_reloc_outofrange;
+      x = bfd_get_16 (input_bfd, contents);
+      x = (x & 0xf9f0) | ((srel & 0x30) << 5) | (srel & 0x0f);
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+
+    case R_AVR_PORT5:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if ((srel & 0xffff) > 0x1f)
+        return bfd_reloc_outofrange;
+      x = bfd_get_16 (input_bfd, contents);
+      x = (x & 0xff07) | ((srel & 0x1f) << 3);
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+
     default:
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 				    contents, rel->r_offset,
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 9452d12..3cca8c9 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2042,6 +2042,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AVR_DIFF16",
   "BFD_RELOC_AVR_DIFF32",
   "BFD_RELOC_AVR_LDS_STS_16",
+  "BFD_RELOC_AVR_PORT6",
+  "BFD_RELOC_AVR_PORT5",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index d7ccef2..3f847d5 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -4795,6 +4795,16 @@ ENUMDOC
   This is a 7 bit reloc for the AVR that stores a SRAM address for
   the sts and lds instructions
 ENUM
+  BFD_RELOC_AVR_PORT6
+ENUMDOC
+  This is a 6 bit reloc for the AVR that stores an I/O register
+  number for the IN and OUT instructions
+ENUM
+  BFD_RELOC_AVR_PORT5
+ENUMDOC
+  This is a 5 bit reloc for the AVR that stores an I/O register
+  number for the SBIC, SBIS, SBI and CBI instructions
+ENUM
   BFD_RELOC_RL78_NEG8
 ENUMX
   BFD_RELOC_RL78_NEG16
diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c
index 826e0be..8f6d0ec 100644
--- a/gas/config/tc-avr.c
+++ b/gas/config/tc-avr.c
@@ -1078,23 +1078,15 @@ avr_operand (struct avr_opcodes_s *opcode,
       break;
 
     case 'P':
-      {
-	unsigned int x;
-
-	x = avr_get_constant (str, 63);
-	str = input_line_pointer;
-	op_mask |= (x & 0xf) | ((x & 0x30) << 5);
-      }
+      str = parse_exp (str, &op_expr);
+      fix_new_exp (frag_now, where, opcode->insn_size * 2,
+		     &op_expr, FALSE, BFD_RELOC_AVR_PORT6);
       break;
 
     case 'p':
-      {
-	unsigned int x;
-
-	x = avr_get_constant (str, 31);
-	str = input_line_pointer;
-	op_mask |= x << 3;
-      }
+      str = parse_exp (str, &op_expr);
+      fix_new_exp (frag_now, where, opcode->insn_size * 2,
+		     &op_expr, FALSE, BFD_RELOC_AVR_PORT5);
       break;
 
     case 'E':
@@ -1550,6 +1542,20 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
 	  as_fatal (_("line %d: unknown relocation type: 0x%x"),
 		    fixP->fx_line, fixP->fx_r_type);
 	  break;
+	  
+    case BFD_RELOC_AVR_PORT6:
+	  if (value > 63)
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("operand out of range: %ld"), value);
+      bfd_putl16 ((bfd_vma) insn | ((value & 0x30) << 5) | (value & 0x0f), where);
+	  break;
+
+    case BFD_RELOC_AVR_PORT5:
+	  if (value > 31)
+	    as_bad_where (fixP->fx_file, fixP->fx_line,
+			  _("operand out of range: %ld"), value);
+      bfd_putl16 ((bfd_vma) insn | ((value & 0x1f) << 3), where);
+	  break;
 	}
     }
   else
diff --git a/include/elf/avr.h b/include/elf/avr.h
index b81371d..d991826 100644
--- a/include/elf/avr.h
+++ b/include/elf/avr.h
@@ -85,6 +85,8 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
      RELOC_NUMBER (R_AVR_DIFF16,               31)
      RELOC_NUMBER (R_AVR_DIFF32,               32)
      RELOC_NUMBER (R_AVR_LDS_STS_16,           33)
+     RELOC_NUMBER (R_AVR_PORT6,                34)
+     RELOC_NUMBER (R_AVR_PORT5,                35)
 END_RELOC_NUMBERS (R_AVR_max)
 
 #endif /* _ELF_AVR_H */

[-- Attachment #4: 3_avr_reg_name.patch --]
[-- Type: application/octet-stream, Size: 2458 bytes --]

diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c
index 8f6d0ec..6e6f0d0 100644
--- a/gas/config/tc-avr.c
+++ b/gas/config/tc-avr.c
@@ -862,28 +862,40 @@ avr_operand (struct avr_opcodes_s *opcode,
     case 'r':
     case 'a':
     case 'v':
-      if (*str == 'r' || *str == 'R')
-        {
-          char r_name[20];
-
-          str = extract_word (str, r_name, sizeof (r_name));
-          op_mask = 0xff;
-          if (ISDIGIT (r_name[1]))
-            {
-              if (r_name[2] == '\0')
-                op_mask = r_name[1] - '0';
-              else if (r_name[1] != '0'
-                       && ISDIGIT (r_name[2])
-                       && r_name[3] == '\0')
-                op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
-            }
-        }
-      else
-        {
-          op_mask = avr_get_constant (str, 31);
-          str = input_line_pointer;
-        }
-
+      {
+        char * old_str = str;
+        char *lower;
+        char r_name[20];
+        
+        str = extract_word (str, r_name, sizeof (r_name));
+        for (lower = r_name; *lower; ++lower)
+ 	      {
+	        if (*lower >= 'A' && *lower <= 'Z')
+	          *lower += 'a' - 'A';
+          }
+        if (r_name[0] == 'r' && ISDIGIT (r_name[1]) && r_name[2] == 0)
+          /* Single-digit register number, ie r0-r9 */
+          op_mask = r_name[1] - '0';
+        else if (r_name[0] == 'r' && ISDIGIT (r_name[1]) &&
+          ISDIGIT (r_name[2]) && r_name[3] == 0)
+          /* Double-digit register number, ie r10 - r32 */
+          op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
+        else if (r_name[0] >= 'x' && r_name[0] <= 'z' &&
+          (r_name[1] == 'l' || r_name[1] == 'h') && r_name[2] == 0)
+          /* registers r26-r31 referred to by name, ie xl, xh, yl, yh, zl, zh */
+          op_mask = (r_name[0] - 'x') * 2 + (r_name[1] == 'h') + 26;
+        else if ((*op == 'v' || *op == 'w') &&
+          r_name[0] >= 'x' && r_name[0] <= 'z' && r_name[1] == 0)
+          /* For the movw and addiw instructions, refer to registers x, y and z by name */
+          op_mask = (r_name[0] - 'x') * 2 + 26;
+        else
+          {
+            /* Numeric or symbolic constant register number */
+            op_mask = avr_get_constant (old_str, 31);
+            str = input_line_pointer;
+          }
+       }
+ 	  
       if (avr_mcu->isa & AVR_ISA_FEW_REGS)
         {
           if (op_mask < 16 || op_mask >= 32)

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
  2014-06-14 19:04 [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers Barney Stratford
@ 2014-06-22 10:05 ` Barney Stratford
  2014-06-24  8:27 ` S, Pitchumani
  1 sibling, 0 replies; 5+ messages in thread
From: Barney Stratford @ 2014-06-22 10:05 UTC (permalink / raw)
  To: binutils

Hi. Did anyone get a chance to look at these patches? I’ve not seen a response to my last message. Are there any changes I need to make to get them accepted?

Cheers,
Barney.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
  2014-06-14 19:04 [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers Barney Stratford
  2014-06-22 10:05 ` Barney Stratford
@ 2014-06-24  8:27 ` S, Pitchumani
  2014-06-30 13:17   ` S, Pitchumani
  1 sibling, 1 reply; 5+ messages in thread
From: S, Pitchumani @ 2014-06-24  8:27 UTC (permalink / raw)
  To: Barney Stratford; +Cc: binutils, Denis Chertykov

> -----Original Message-----
> From: binutils-owner@sourceware.org [mailto:binutils-owner@sourceware.org]
> On Behalf Of Barney Stratford
> Sent: Sunday, June 15, 2014 12:35 AM
> To: binutils@sourceware.org
> Subject: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
> 
> I've recently been working on getting the assembler and linker to work
> with the ATtiny40 family of microcontrollers. I've also added some
> functionality to the avr assembler in general. As this may be useful to
> others, I'm attaching my patches against the current git head. Can someone
> review and commit them please?
> 
> 1_avrtiny10.patch contains the basic avrtiny10 code, including a linker
> reloc for the 16-bit version of the lds and sts instructions.
> 
> 2_avr_io_relocs.patch allows you to refer to the I/O registers by symbol
> name.
> 
> 3_avr_reg_name.patch allows you to refer to r26-r31 by name as
> /[xyz][hl]?/. It also fixes a bug that would prevent you from using a
> symbol whose name begins with 'r' to refer to a register.

Hi,

I looked at your patches. Atmel distributed binutils also have tiny
architecture support. Though both are similar, there are some differences
such as architecture name, id, LDS16 reloc size, memory access range (0xbf) etc.

I can check all the differences and we can sync to avoid conflicts.

Regards,
Pitchumani

^ permalink raw reply	[flat|nested] 5+ messages in thread

* RE: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
  2014-06-24  8:27 ` S, Pitchumani
@ 2014-06-30 13:17   ` S, Pitchumani
  2014-07-01  9:25     ` Nicholas Clifton
  0 siblings, 1 reply; 5+ messages in thread
From: S, Pitchumani @ 2014-06-30 13:17 UTC (permalink / raw)
  To: binutils, Denis Chertykov, Barney Stratford

[-- Attachment #1: Type: text/plain, Size: 4940 bytes --]

S, Pitchumani, Tuesday, June 24, 2014 1:57 PM
> To: Barney Stratford
> Cc: binutils@sourceware.org; Denis Chertykov
> Subject: RE: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
> 
> > -----Original Message-----
> > From: binutils-owner@sourceware.org [mailto:binutils-
> owner@sourceware.org]
> > On Behalf Of Barney Stratford
> > Sent: Sunday, June 15, 2014 12:35 AM
> > To: binutils@sourceware.org
> > Subject: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
> >
> > I've recently been working on getting the assembler and linker to work
> > with the ATtiny40 family of microcontrollers. I've also added some
> > functionality to the avr assembler in general. As this may be useful to
> > others, I'm attaching my patches against the current git head. Can
> someone
> > review and commit them please?
> >
> > 1_avrtiny10.patch contains the basic avrtiny10 code, including a linker
> > reloc for the 16-bit version of the lds and sts instructions.
> >
> > 2_avr_io_relocs.patch allows you to refer to the I/O registers by symbol
> > name.
> >
> > 3_avr_reg_name.patch allows you to refer to r26-r31 by name as
> > /[xyz][hl]?/. It also fixes a bug that would prevent you from using a
> > symbol whose name begins with 'r' to refer to a register.
> 
> Hi,
> 
> I looked at your patches. Atmel distributed binutils also have tiny
> architecture support. Though both are similar, there are some differences
> such as architecture name, id, LDS16 reloc size, memory access range
> (0xbf) etc.
> 
> I can check all the differences and we can sync to avoid conflicts.

Hi,

I have merged the tiny support patch of Barney Startford and Atmel.
Updated patch is attached. Please review.

If OK, could someone commit please?

Regards,
Pitchumani


bfd/ChangeLog

2014-06-30  Barney Stratford  <barney_stratford@fastmail.fm>
            Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
            Pitchumani Sivanupandi <pitchumani.s@atmel.com>
            Soundararajan <Sounderarajan.D@atmel.com>

    * archures.c: add avrtiny architecture for avr target.
	* bfd-in2.h: Regenerate.
	* cpu-avr.c (arch_info_struct): add avrtiny arch info.
	* elf32-avr.c (elf_avr_howto_table): new relocation R_AVR_LDS_STS_16
	added for 16 bit LDS/STS instruction of avrtiny arch.
	(avr_reloc_map): reloc R_AVR_LDS_STS_16 is mapped to 
	BFD_RELOC_AVR_LDS_STS_16.
	(bfd_elf_avr_final_write_processing): select machine number avrtiny arch.
	(elf32_avr_object_p): set machine number for avrtiny arch.
	* libbfd.h: Regenerate.
	* reloc.c: Add documentation for BFD_RELOC_AVR_LDS_STS_16 reloc.

gas/ChangeLog

2014-06-30  Barney Stratford  <barney_stratford@fastmail.fm>
            Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
            Pitchumani Sivanupandi <pitchumani.s@atmel.com>
            Soundararajan <Sounderarajan.D@atmel.com>

    * config/tc-avr.c (mcu_types): Add avrtiny arch.
	Add avrtiny arch devices attiny4, attiny5, attiny9, attiny10, attiny20
	and attiny40.
	(md_show_usage): Add avrtiny arch in usage message.
	(avr_operand): validate and issue error for invalid register for avrtiny.
	add new reloc exp for 16 bit lds/sts instruction.
	(md_apply_fix): check 16 bit lds/sts operand for out of range and encode.
	(md_assemble): check ISA for arch and issue diagnostic.

ChangeLog

2014-06-30  Barney Stratford  <barney_stratford@fastmail.fm>
            Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
            Pitchumani Sivanupandi <pitchumani.s@atmel.com>
            Soundararajan <Sounderarajan.D@atmel.com>

	* include/elf/avr.h (E_AVR_MACH_AVRTINY): define avrtiny machine number.
	(R_AVR_LDS_STS_16): define 16 bit lds/sts reloc number.
	* include/opcode/avr.h (AVR_ISA_TINY): define avrtiny specific ISA.
	(AVR_ISA_2xxxa): define ISA without LPM.
	(AVR_ISA_AVRTINY): define avrtiny arch ISA.
	Add doc for contraint used in 16 bit lds/sts.
	Adjust ISA group for icall, ijmp, pop and push.
	Add 16 bit lds/sts encoding and update 32 bit lds/sts constraints.
	* opcodes/avr-dis.c (avr_operand): Handle constraint j for 16 bit lds/sts.
	(print_insn_avr): do not select opcode if insn ISA is avrtiny and machine
	is not avrtiny.

ld/ChangeLog

2014-06-30  Barney Stratford  <barney_stratford@fastmail.fm>
            Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
            Pitchumani Sivanupandi <pitchumani.s@atmel.com>
            Soundararajan <Sounderarajan.D@atmel.com>

	* Makefile.am (ALL_EMULATION_SOURCES): add avrtiny emulation source.
	(eavrtiny.c): add rules for avrtiny emulation source.
	* Makefile.in: Regenerate.
	* configure.tgt: Add avrtiny to avr target emulations.
	* scripttempl/avrtiny.sc: New file.
	linker script template for avrtiny arch.
	* emulparams/avrtiny.sh: New file.
	emulation parameters for avrtiny arch.


[-- Attachment #2: avrtiny-support.patch --]
[-- Type: application/octet-stream, Size: 29082 bytes --]

diff --git a/bfd/archures.c b/bfd/archures.c
index 9b47504..44c9199 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -410,6 +410,7 @@ DESCRIPTION
 .#define bfd_mach_avr5		5
 .#define bfd_mach_avr51		51
 .#define bfd_mach_avr6		6
+.#define bfd_mach_avrtiny   100
 .#define bfd_mach_avrxmega1 101
 .#define bfd_mach_avrxmega2 102
 .#define bfd_mach_avrxmega3 103
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d9056ce..2cc581c 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2195,6 +2195,7 @@ enum bfd_architecture
 #define bfd_mach_avr5          5
 #define bfd_mach_avr51         51
 #define bfd_mach_avr6          6
+#define bfd_mach_avrtiny   100
 #define bfd_mach_avrxmega1 101
 #define bfd_mach_avrxmega2 102
 #define bfd_mach_avrxmega3 103
@@ -4475,6 +4476,10 @@ value.  */
   BFD_RELOC_AVR_DIFF16,
   BFD_RELOC_AVR_DIFF32,
 
+/* This is a 7 bit reloc for the AVR that stores SRAM address for 16bit
+lds and sts instructions supported only tiny core  */
+  BFD_RELOC_AVR_LDS_STS_16,
+
 /* Renesas RL78 Relocations.  */
   BFD_RELOC_RL78_NEG8,
   BFD_RELOC_RL78_NEG16,
diff --git a/bfd/cpu-avr.c b/bfd/cpu-avr.c
index 060c9a2..60a0f46 100644
--- a/bfd/cpu-avr.c
+++ b/bfd/cpu-avr.c
@@ -135,24 +135,27 @@ static const bfd_arch_info_type arch_info_struct[] =
   /* 3-Byte PC.  */
   N (22, bfd_mach_avr6, "avr:6", FALSE, & arch_info_struct[10]),
 
+  /* Tiny core (AVR Tiny) */
+  N (16, bfd_mach_avrtiny, "avr:100", FALSE, & arch_info_struct[11]),
+
   /* Xmega 1 */
-  N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[11]),
+  N (24, bfd_mach_avrxmega1, "avr:101", FALSE, & arch_info_struct[12]),
 
   /* Xmega 2 */
-  N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[12]),
-
+  N (24, bfd_mach_avrxmega2, "avr:102", FALSE, & arch_info_struct[13]),
+  
   /* Xmega 3 */
-  N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[13]),
-
+  N (24, bfd_mach_avrxmega3, "avr:103", FALSE, & arch_info_struct[14]),
+  
   /* Xmega 4 */
-  N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[14]),
-
+  N (24, bfd_mach_avrxmega4, "avr:104", FALSE, & arch_info_struct[15]),
+  
   /* Xmega 5 */
-  N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[15]),
-
+  N (24, bfd_mach_avrxmega5, "avr:105", FALSE, & arch_info_struct[16]),
+  
   /* Xmega 6 */
-  N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[16]),
-
+  N (24, bfd_mach_avrxmega6, "avr:106", FALSE, & arch_info_struct[17]),
+  
   /* Xmega 7 */
   N (24, bfd_mach_avrxmega7, "avr:107", FALSE, NULL)
 
diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c
index b46a44c..a2de076 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -604,7 +604,21 @@ static reloc_howto_type elf_avr_howto_table[] =
      FALSE,         /* partial_inplace */
      0,             /* src_mask */
      0xffffffff,    /* dst_mask */ 
-     FALSE)         /* pcrel_offset */
+     FALSE),        /* pcrel_offset */
+  /* 7 bit immediate for LDS/STS in Tiny core */
+  HOWTO (R_AVR_LDS_STS_16,  /* type */
+     0,                     /* rightshift */
+     1,                     /* size (0 = byte, 1 = short, 2 = long) */
+     7,                     /* bitsize */
+     FALSE,                 /* pc_relative */
+     0,                     /* bitpos */
+     complain_overflow_dont,/* complain_on_overflow */
+     bfd_elf_generic_reloc, /* special_function */
+     "R_AVR_LDS_STS_16",    /* name */
+     FALSE,                 /* partial_inplace */
+     0xffff,                /* src_mask */
+     0xffff,                /* dst_mask */
+     FALSE)                 /* pcrel_offset */
 };
 
 /* Map BFD reloc types to AVR ELF reloc types.  */
@@ -649,7 +663,8 @@ static const struct avr_reloc_map avr_reloc_map[] =
   { BFD_RELOC_AVR_8_HLO,            R_AVR_8_HLO8 },
   { BFD_RELOC_AVR_DIFF8,            R_AVR_DIFF8 },
   { BFD_RELOC_AVR_DIFF16,           R_AVR_DIFF16 },
-  { BFD_RELOC_AVR_DIFF32,           R_AVR_DIFF32 }
+  { BFD_RELOC_AVR_DIFF32,           R_AVR_DIFF32 },
+  { BFD_RELOC_AVR_LDS_STS_16,       R_AVR_LDS_STS_16}
 };
 
 /* Meant to be filled one day with the wrap around address for the
@@ -1227,6 +1242,17 @@ avr_final_link_relocate (reloc_howto_type *                 howto,
       r = bfd_reloc_ok;
       break;
 
+   case R_AVR_LDS_STS_16:
+      contents += rel->r_offset;
+      srel = (bfd_signed_vma) relocation + rel->r_addend;
+      if ((srel & 0xFFFF) < 0x40 || (srel & 0xFFFF) > 0xbf)
+        return bfd_reloc_outofrange;
+      srel = srel & 0x7f;
+      x = bfd_get_16 (input_bfd, contents);
+      x |= (srel & 0x0f) | ((srel & 0x30) << 5) | ((srel & 0x40) << 2);
+      bfd_put_16 (input_bfd, x, contents);
+      break;
+ 
     default:
       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 				    contents, rel->r_offset,
@@ -1439,6 +1465,10 @@ bfd_elf_avr_final_write_processing (bfd *abfd,
     case bfd_mach_avrxmega7:
       val = E_AVR_MACH_XMEGA7;
       break;
+
+   case bfd_mach_avrtiny:
+      val = E_AVR_MACH_AVRTINY;
+      break;
     }
 
   elf_elfheader (abfd)->e_machine = EM_AVR;
@@ -1529,6 +1559,10 @@ elf32_avr_object_p (bfd *abfd)
 	case E_AVR_MACH_XMEGA7:
 	  e_set = bfd_mach_avrxmega7;
 	  break;
+
+    case E_AVR_MACH_AVRTINY:
+      e_set = bfd_mach_avrtiny;
+      break;
 	}
     }
   return bfd_default_set_arch_mach (abfd, bfd_arch_avr,
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 3bb3726..9452d12 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2041,6 +2041,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AVR_DIFF8",
   "BFD_RELOC_AVR_DIFF16",
   "BFD_RELOC_AVR_DIFF32",
+  "BFD_RELOC_AVR_LDS_STS_16",
   "BFD_RELOC_RL78_NEG8",
   "BFD_RELOC_RL78_NEG16",
   "BFD_RELOC_RL78_NEG24",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 7f46c58..2b4bfde 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -4790,6 +4790,11 @@ ENUMDOC
   second symbol so the linker can determine whether to adjust the field
   value.
 ENUM
+  BFD_RELOC_AVR_LDS_STS_16
+ENUMDOC
+  This is a 7 bit reloc for the AVR that stores SRAM address for 16bit
+  lds and sts instructions supported only tiny core
+ENUM
   BFD_RELOC_RL78_NEG8
 ENUMX
   BFD_RELOC_RL78_NEG16
diff --git a/gas/config/tc-avr.c b/gas/config/tc-avr.c
index e4bc59c..af473f7 100644
--- a/gas/config/tc-avr.c
+++ b/gas/config/tc-avr.c
@@ -89,6 +89,7 @@ static struct mcu_type_s mcu_types[] =
   {"avrxmega5",  AVR_ISA_XMEGA,   bfd_mach_avrxmega5},
   {"avrxmega6",  AVR_ISA_XMEGA,   bfd_mach_avrxmega6},
   {"avrxmega7",  AVR_ISA_XMEGA,   bfd_mach_avrxmega7},
+  {"avrtiny",    AVR_ISA_AVRTINY, bfd_mach_avrtiny},
   {"at90s1200",  AVR_ISA_1200,    bfd_mach_avr1},
   {"attiny11",   AVR_ISA_AVR1,    bfd_mach_avr1},
   {"attiny12",   AVR_ISA_AVR1,    bfd_mach_avr1},
@@ -323,6 +324,12 @@ static struct mcu_type_s mcu_types[] =
   {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
   {"atxmega128a1u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
   {"atxmega128a4u", AVR_ISA_XMEGAU, bfd_mach_avrxmega7},
+  {"attiny4",      AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+  {"attiny5",      AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+  {"attiny9",      AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+  {"attiny10",     AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+  {"attiny20",     AVR_ISA_AVRTINY, bfd_mach_avrtiny},
+  {"attiny40",     AVR_ISA_AVRTINY, bfd_mach_avrtiny},
   {NULL, 0, 0}
 };
 
@@ -513,7 +520,7 @@ md_show_usage (FILE *stream)
 	"                   avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM\n"
 	"                   avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM\n"
 	"                   avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM\n"
-	"                   or immediate microcontroller name.\n"));
+	"                   avrtiny   - AVR Tiny core with 16 gp registers\n"));
   fprintf (stream,
       _("  -mall-opcodes    accept all AVR opcodes, even if not supported by MCU\n"
 	"  -mno-skip-bug    disable warnings for skipping two-word instructions\n"
@@ -855,29 +862,41 @@ avr_operand (struct avr_opcodes_s *opcode,
     case 'a':
     case 'v':
       if (*str == 'r' || *str == 'R')
-	{
-	  char r_name[20];
+        {
+          char r_name[20];
 
-	  str = extract_word (str, r_name, sizeof (r_name));
-	  op_mask = 0xff;
-	  if (ISDIGIT (r_name[1]))
-	    {
-	      if (r_name[2] == '\0')
-		op_mask = r_name[1] - '0';
-	      else if (r_name[1] != '0'
-		       && ISDIGIT (r_name[2])
-		       && r_name[3] == '\0')
-		op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
-	    }
-	}
+          str = extract_word (str, r_name, sizeof (r_name));
+          op_mask = 0xff;
+          if (ISDIGIT (r_name[1]))
+            {
+              if (r_name[2] == '\0')
+                op_mask = r_name[1] - '0';
+              else if (r_name[1] != '0'
+                       && ISDIGIT (r_name[2])
+                       && r_name[3] == '\0')
+                op_mask = (r_name[1] - '0') * 10 + r_name[2] - '0';
+            }
+        }
       else
-	{
-	  op_mask = avr_get_constant (str, 31);
-	  str = input_line_pointer;
-	}
+        {
+          op_mask = avr_get_constant (str, 31);
+          str = input_line_pointer;
+        }
+
+      if (avr_mcu->mach == bfd_mach_avrtiny)
+        {
+          if (op_mask < 16 || op_mask > 31)
+            {
+              as_bad (_("register name or number from 16 to 31 required"));
+              break;
+            }
+        }
+      else if (op_mask > 31)
+        {
+          as_bad (_("register name or number from 0 to 31 required"));
+          break;
+        }
 
-      if (op_mask <= 31)
-	{
 	  switch (*op)
 	    {
 	    case 'a':
@@ -905,9 +924,6 @@ avr_operand (struct avr_opcodes_s *opcode,
 	      break;
 	    }
 	  break;
-	}
-      as_bad (_("register name or number from 0 to 31 required"));
-      break;
 
     case 'e':
       {
@@ -1014,6 +1030,12 @@ avr_operand (struct avr_opcodes_s *opcode,
 		   &op_expr, FALSE, BFD_RELOC_16);
       break;
 
+    case 'j':
+      str = parse_exp (str, &op_expr);
+      fix_new_exp (frag_now, where, opcode->insn_size * 2,
+           &op_expr, FALSE, BFD_RELOC_AVR_LDS_STS_16);
+      break;
+
     case 'M':
       {
 	bfd_reloc_code_real_type r_type;
@@ -1415,6 +1437,15 @@ md_apply_fix (fixS *fixP, valueT * valP, segT seg)
 	  bfd_putl16 ((bfd_vma) insn | LDI_IMMEDIATE (value), where);
 	  break;
 
+    case BFD_RELOC_AVR_LDS_STS_16:
+      if ((value < 0x40) || (value > 0xBF))
+        as_warn_where (fixP->fx_file, fixP->fx_line,
+                       _("operand out of range: 0x%lx"),
+                       (unsigned long)value);
+      insn |= ((value & 0xF) | ((value & 0x30) << 5) | ((value & 0x40) <<2));
+      bfd_putl16 ((bfd_vma) insn, where);
+      break;
+
 	case BFD_RELOC_AVR_6:
 	  if ((value > 63) || (value < 0))
 	    as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -1594,6 +1625,28 @@ md_assemble (char *str)
 
   opcode = (struct avr_opcodes_s *) hash_find (avr_hash, op);
 
+  if (opcode && !avr_opt.all_opcodes)
+    {
+      /* Check if the instruction's ISA bit is ON in the ISA bits of the part 
+         specified by the user. If not look for other instructions specifica-
+         -tions with same mnemonic who's ISA bits matches. 
+
+         This requires include/opcode/avr.h to have the instructions with
+         same mnenomic to be specified in sequence. */
+
+      while ((opcode->isa & avr_mcu->isa) != opcode->isa)
+        {
+          opcode++;
+     
+          if (opcode->name && strcmp(op, opcode->name))
+            {
+              as_bad (_("illegal opcode %s for mcu %s"), 
+                      opcode->name, avr_mcu->name);
+              return;
+            }
+        }
+    } 
+
   if (opcode == NULL)
     {
       as_bad (_("unknown opcode `%s'"), op);
@@ -1606,9 +1659,6 @@ md_assemble (char *str)
   if (*str && *opcode->constraints == '?')
     ++opcode;
 
-  if (!avr_opt.all_opcodes && (opcode->isa & avr_mcu->isa) != opcode->isa)
-    as_bad (_("illegal opcode %s for mcu %s"), opcode->name, avr_mcu->name);
-
   dwarf2_emit_insn (0);
 
   /* We used to set input_line_pointer to the result of get_operands,
diff --git a/include/elf/avr.h b/include/elf/avr.h
index 06a7f13..0f3ed03 100644
--- a/include/elf/avr.h
+++ b/include/elf/avr.h
@@ -40,13 +40,14 @@
 #define E_AVR_MACH_AVR5     5
 #define E_AVR_MACH_AVR51   51
 #define E_AVR_MACH_AVR6     6 
-#define E_AVR_MACH_XMEGA1 101
-#define E_AVR_MACH_XMEGA2 102
-#define E_AVR_MACH_XMEGA3 103
-#define E_AVR_MACH_XMEGA4 104
-#define E_AVR_MACH_XMEGA5 105
-#define E_AVR_MACH_XMEGA6 106
-#define E_AVR_MACH_XMEGA7 107
+#define E_AVR_MACH_AVRTINY 100
+#define E_AVR_MACH_XMEGA1  101
+#define E_AVR_MACH_XMEGA2  102
+#define E_AVR_MACH_XMEGA3  103
+#define E_AVR_MACH_XMEGA4  104
+#define E_AVR_MACH_XMEGA5  105
+#define E_AVR_MACH_XMEGA6  106
+#define E_AVR_MACH_XMEGA7  107
 
 /* Relocations.  */
 START_RELOC_NUMBERS (elf_avr_reloc_type)
@@ -83,6 +84,7 @@ START_RELOC_NUMBERS (elf_avr_reloc_type)
      RELOC_NUMBER (R_AVR_DIFF8,                30)
      RELOC_NUMBER (R_AVR_DIFF16,               31)
      RELOC_NUMBER (R_AVR_DIFF32,               32)
+     RELOC_NUMBER (R_AVR_LDS_STS_16,           33)
 END_RELOC_NUMBERS (R_AVR_max)
 
 #endif /* _ELF_AVR_H */
diff --git a/include/opcode/avr.h b/include/opcode/avr.h
index e33f46d..e393eff 100644
--- a/include/opcode/avr.h
+++ b/include/opcode/avr.h
@@ -22,6 +22,7 @@
 #define AVR_ISA_LPM   0x0002 /* device has LPM */
 #define AVR_ISA_LPMX  0x0004 /* device has LPM Rd,Z[+] */
 #define AVR_ISA_SRAM  0x0008 /* device has SRAM (LD, ST, PUSH, POP, ...) */
+#define AVR_ISA_TINY  0x0010 /* device has Tiny core specific encodings */
 #define AVR_ISA_MEGA  0x0020 /* device has >8K program memory (JMP and CALL
 				supported, no 8K wrap on RJMP and RCALL) */
 #define AVR_ISA_MUL   0x0040 /* device has new core (MUL, FMUL, ...) */
@@ -37,6 +38,7 @@
 
 #define AVR_ISA_TINY1 (AVR_ISA_1200 | AVR_ISA_LPM)
 #define AVR_ISA_2xxx  (AVR_ISA_TINY1 | AVR_ISA_SRAM)
+#define AVR_ISA_2xxxa (AVR_ISA_1200 | AVR_ISA_SRAM)
 /* For the attiny26 which is missing LPM Rd,Z+.  */
 #define AVR_ISA_2xxe  (AVR_ISA_2xxx | AVR_ISA_LPMX)
 #define AVR_ISA_RF401 (AVR_ISA_2xxx | AVR_ISA_MOVW | AVR_ISA_LPMX)
@@ -72,6 +74,9 @@
                         AVR_ISA_ELPM | AVR_ISA_ELPMX | AVR_ISA_SPM | \
                         AVR_ISA_BRK | AVR_ISA_EIND | AVR_ISA_MOVW)
 
+#define AVR_ISA_AVRTINY (AVR_ISA_1200 | AVR_ISA_BRK | AVR_ISA_SRAM | \
+                         AVR_ISA_TINY)
+
 #define REGISTER_P(x) ((x) == 'r'		\
 		       || (x) == 'd'		\
 		       || (x) == 'w'		\
@@ -110,6 +115,7 @@
    p - Port address value from 0 to 31. (cbi, sbi, sbic, sbis)
    K - immediate value from 0 to 63 (used in `adiw', `sbiw')
    i - immediate value
+   j - 7 bit immediate value from 0x40 to 0xBF (for 16-bit 'lds'/'sts')
    l - signed pc relative offset from -64 to 63
    L - signed pc relative offset from -2048 to 2047
    h - absolute code address (call, jmp)
@@ -160,8 +166,8 @@ AVR_INSN (sez,  "",    "1001010000011000", 1, AVR_ISA_1200, 0x9418)
 AVR_INSN (bclr, "S",   "100101001SSS1000", 1, AVR_ISA_1200, 0x9488)
 AVR_INSN (bset, "S",   "100101000SSS1000", 1, AVR_ISA_1200, 0x9408)
 
-AVR_INSN (icall,"",    "1001010100001001", 1, AVR_ISA_2xxx, 0x9509)
-AVR_INSN (ijmp, "",    "1001010000001001", 1, AVR_ISA_2xxx, 0x9409)
+AVR_INSN (icall,"",    "1001010100001001", 1, AVR_ISA_2xxxa,0x9509)
+AVR_INSN (ijmp, "",    "1001010000001001", 1, AVR_ISA_2xxxa,0x9409)
 
 AVR_INSN (lpm,  "?",   "1001010111001000", 1, AVR_ISA_TINY1,0x95c8)
 AVR_INSN (lpm,  "r,z", "1001000ddddd010+", 1, AVR_ISA_LPMX, 0x9004)
@@ -261,8 +267,8 @@ AVR_INSN (dec,  "r",   "1001010rrrrr1010", 1, AVR_ISA_1200, 0x940a)
 AVR_INSN (inc,  "r",   "1001010rrrrr0011", 1, AVR_ISA_1200, 0x9403)
 AVR_INSN (lsr,  "r",   "1001010rrrrr0110", 1, AVR_ISA_1200, 0x9406)
 AVR_INSN (neg,  "r",   "1001010rrrrr0001", 1, AVR_ISA_1200, 0x9401)
-AVR_INSN (pop,  "r",   "1001000rrrrr1111", 1, AVR_ISA_2xxx, 0x900f)
-AVR_INSN (push, "r",   "1001001rrrrr1111", 1, AVR_ISA_2xxx, 0x920f)
+AVR_INSN (pop,  "r",   "1001000rrrrr1111", 1, AVR_ISA_2xxxa,0x900f)
+AVR_INSN (push, "r",   "1001001rrrrr1111", 1, AVR_ISA_2xxxa,0x920f)
 AVR_INSN (ror,  "r",   "1001010rrrrr0111", 1, AVR_ISA_1200, 0x9407)
 AVR_INSN (swap, "r",   "1001010rrrrr0010", 1, AVR_ISA_1200, 0x9402)
 
@@ -280,8 +286,10 @@ AVR_INSN (fmul, "a,a", "000000110ddd1rrr", 1, AVR_ISA_MUL,  0x0308)
 AVR_INSN (fmuls,"a,a", "000000111ddd0rrr", 1, AVR_ISA_MUL,  0x0380)
 AVR_INSN (fmulsu,"a,a","000000111ddd1rrr", 1, AVR_ISA_MUL,  0x0388)
 
-AVR_INSN (sts,  "i,r", "1001001ddddd0000", 2, AVR_ISA_2xxx, 0x9200)
-AVR_INSN (lds,  "r,i", "1001000ddddd0000", 2, AVR_ISA_2xxx, 0x9000)
+AVR_INSN (sts, "j,d", "10101kkkddddkkkk", 1, AVR_ISA_TINY, 0xA800)
+AVR_INSN (sts, "i,r", "1001001ddddd0000", 2, AVR_ISA_2xxx, 0x9200)
+AVR_INSN (lds, "d,j", "10100kkkddddkkkk", 1, AVR_ISA_TINY, 0xA000)
+AVR_INSN (lds, "r,i", "1001000ddddd0000", 2, AVR_ISA_2xxx, 0x9000)
 
    /* Special case for b+0, `e' must be next entry after `b',
       b={Y=1,Z=0}, ee={X=11,Y=10,Z=00}, !=1 if -e or e+ or X.  */
diff --git a/ld/Makefile.am b/ld/Makefile.am
index 24560a0..2bb2cac 100644
--- a/ld/Makefile.am
+++ b/ld/Makefile.am
@@ -193,6 +193,7 @@ ALL_EMULATION_SOURCES = \
 	eavrxmega5.c \
 	eavrxmega6.c \
 	eavrxmega7.c \
+	eavrtiny.c   \
 	ecoff_i860.c \
 	ecoff_sparc.c \
 	ecrisaout.c \
@@ -848,6 +849,10 @@ eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \
   $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \
   ${GEN_DEPENDS}
 
+eavrtiny.c: $(srcdir)/emulparams/avrtiny.sh \
+  $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avrtiny.sc \
+  ${GEN_DEPENDS}
+
 ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS}
 
diff --git a/ld/Makefile.in b/ld/Makefile.in
index 377fbd8..dc4b61e 100644
--- a/ld/Makefile.in
+++ b/ld/Makefile.in
@@ -500,6 +500,7 @@ ALL_EMULATION_SOURCES = \
 	eavrxmega5.c \
 	eavrxmega6.c \
 	eavrxmega7.c \
+	eavrtiny.c   \
 	ecoff_i860.c \
 	ecoff_sparc.c \
 	ecrisaout.c \
@@ -1087,6 +1088,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr5.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr51.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavr6.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrtiny.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega1.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega2.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eavrxmega3.Po@am__quote@
@@ -2287,6 +2289,10 @@ eavrxmega7.c: $(srcdir)/emulparams/avrxmega7.sh \
   $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avr.sc \
   ${GEN_DEPENDS}
 
+eavrtiny.c: $(srcdir)/emulparams/avrtiny.sh \
+  $(srcdir)/emultempl/avrelf.em $(ELF_DEPS) $(srcdir)/scripttempl/avrtiny.sc \
+  ${GEN_DEPENDS}
+
 ecoff_i860.c: $(srcdir)/emulparams/coff_i860.sh \
   $(srcdir)/emultempl/generic.em $(srcdir)/scripttempl/i860coff.sc ${GEN_DEPENDS}
 
diff --git a/ld/configure.tgt b/ld/configure.tgt
index a230207..e74e9be 100644
--- a/ld/configure.tgt
+++ b/ld/configure.tgt
@@ -140,7 +140,7 @@ arm*-*-uclinux*)	targ_emul=armelf_linux
 arm-*-vxworks)		targ_emul=armelf_vxworks ;;
 arm*-*-conix*)		targ_emul=armelf ;;
 avr-*-*)		targ_emul=avr2
-			targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7"
+			targ_extra_emuls="avr1 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega1 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny"
 			;;
 bfin-*-elf)		targ_emul=elf32bfin;
 			targ_extra_emuls="elf32bfinfd"
diff --git a/ld/emulparams/avrtiny.sh b/ld/emulparams/avrtiny.sh
new file mode 100644
index 0000000..b4ed14b
--- /dev/null
+++ b/ld/emulparams/avrtiny.sh
@@ -0,0 +1,13 @@
+ARCH=avr:100
+MACHINE=
+SCRIPT_NAME=avrtiny
+OUTPUT_FORMAT="elf32-avr"
+MAXPAGESIZE=1
+EMBEDDED=yes
+TEMPLATE_NAME=elf32
+
+TEXT_ORIGIN=0x0
+TEXT_LENGTH=4K
+DATA_ORIGIN=0x0800040
+DATA_LENGTH=0x100
+EXTRA_EM_FILE=avrelf
diff --git a/ld/scripttempl/avrtiny.sc b/ld/scripttempl/avrtiny.sc
new file mode 100644
index 0000000..b3a49d1
--- /dev/null
+++ b/ld/scripttempl/avrtiny.sc
@@ -0,0 +1,250 @@
+cat <<EOF
+OUTPUT_FORMAT("${OUTPUT_FORMAT}","${OUTPUT_FORMAT}","${OUTPUT_FORMAT}")
+OUTPUT_ARCH(${ARCH})
+
+MEMORY
+{
+  text   (rx)   : ORIGIN = $TEXT_ORIGIN, LENGTH = $TEXT_LENGTH
+  data   (rw!x) : ORIGIN = $DATA_ORIGIN, LENGTH = $DATA_LENGTH
+
+  /* Provide offsets for config, lock and signature to match
+     production file format. Ignore offsets in datasheet.  */
+
+  config    (rw!x) : ORIGIN = 0x820000, LENGTH = 2
+  lock      (rw!x) : ORIGIN = 0x830000, LENGTH = 2
+  signature (rw!x) : ORIGIN = 0x840000, LENGTH = 4
+}
+
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  ${TEXT_DYNAMIC+${DYNAMIC}}
+  .hash        ${RELOCATING-0} : { *(.hash)		}
+  .dynsym      ${RELOCATING-0} : { *(.dynsym)		}
+  .dynstr      ${RELOCATING-0} : { *(.dynstr)		}
+  .gnu.version ${RELOCATING-0} : { *(.gnu.version)	}
+  .gnu.version_d ${RELOCATING-0} : { *(.gnu.version_d)	}
+  .gnu.version_r ${RELOCATING-0} : { *(.gnu.version_r)	}
+
+  .rel.init    ${RELOCATING-0} : { *(.rel.init)	}
+  .rela.init   ${RELOCATING-0} : { *(.rela.init)	}
+  .rel.text    ${RELOCATING-0} :
+    {
+      *(.rel.text)
+      ${RELOCATING+*(.rel.text.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.t*)}
+    }
+  .rela.text   ${RELOCATING-0} :
+    {
+      *(.rela.text)
+      ${RELOCATING+*(.rela.text.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.t*)}
+    }
+  .rel.fini    ${RELOCATING-0} : { *(.rel.fini)	}
+  .rela.fini   ${RELOCATING-0} : { *(.rela.fini)	}
+  .rel.rodata  ${RELOCATING-0} :
+    {
+      *(.rel.rodata)
+      ${RELOCATING+*(.rel.rodata.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.r*)}
+    }
+  .rela.rodata ${RELOCATING-0} :
+    {
+      *(.rela.rodata)
+      ${RELOCATING+*(.rela.rodata.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.r*)}
+    }
+  .rel.data    ${RELOCATING-0} :
+    {
+      *(.rel.data)
+      ${RELOCATING+*(.rel.data.*)}
+      ${RELOCATING+*(.rel.gnu.linkonce.d*)}
+    }
+  .rela.data   ${RELOCATING-0} :
+    {
+      *(.rela.data)
+      ${RELOCATING+*(.rela.data.*)}
+      ${RELOCATING+*(.rela.gnu.linkonce.d*)}
+    }
+  .rel.ctors   ${RELOCATING-0} : { *(.rel.ctors)	}
+  .rela.ctors  ${RELOCATING-0} : { *(.rela.ctors)	}
+  .rel.dtors   ${RELOCATING-0} : { *(.rel.dtors)	}
+  .rela.dtors  ${RELOCATING-0} : { *(.rela.dtors)	}
+  .rel.got     ${RELOCATING-0} : { *(.rel.got)		}
+  .rela.got    ${RELOCATING-0} : { *(.rela.got)	}
+  .rel.bss     ${RELOCATING-0} : { *(.rel.bss)		}
+  .rela.bss    ${RELOCATING-0} : { *(.rela.bss)	}
+  .rel.plt     ${RELOCATING-0} : { *(.rel.plt)		}
+  .rela.plt    ${RELOCATING-0} : { *(.rela.plt)	}
+
+  /* Internal text space or external memory.  */
+  .text ${RELOCATING-0} : ${RELOCATING+ AT (0x0)}
+  {
+    *(.vectors)
+    KEEP(*(.vectors))
+
+    /* For data that needs to reside in the lower 64k of progmem.  */
+    *(.progmem.gcc*)
+    *(.progmem*)
+    ${RELOCATING+. = ALIGN(2);}
+
+    ${CONSTRUCTING+ __trampolines_start = . ; }
+    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
+    *(.trampolines)
+    *(.trampolines*)
+    ${CONSTRUCTING+ __trampolines_end = . ; }
+
+    /* For future tablejump instruction arrays for 3 byte pc devices.
+       We don't relax jump/call instructions within these sections.  */
+    *(.jumptables) 
+    *(.jumptables*) 
+
+    /* For code that needs to reside in the lower 128k progmem.  */
+    *(.lowtext)
+    *(.lowtext*)
+
+    ${CONSTRUCTING+ __ctors_start = . ; }
+    ${CONSTRUCTING+ *(.ctors) }
+    ${CONSTRUCTING+ __ctors_end = . ; }
+    ${CONSTRUCTING+ __dtors_start = . ; }
+    ${CONSTRUCTING+ *(.dtors) }
+    ${CONSTRUCTING+ __dtors_end = . ; }
+    KEEP(SORT(*)(.ctors))
+    KEEP(SORT(*)(.dtors))
+
+    /* From this point on, we don't bother about wether the insns are
+       below or above the 16 bits boundary.  */
+    *(.init0)  /* Start here after reset.  */
+    KEEP (*(.init0))
+    *(.init1)
+    KEEP (*(.init1))
+    *(.init2)  /* Clear __zero_reg__, set up stack pointer.  */
+    KEEP (*(.init2))
+    *(.init3)
+    KEEP (*(.init3))
+    *(.init4)  /* Initialize data and BSS.  */
+    KEEP (*(.init4))
+    *(.init5)
+    KEEP (*(.init5))
+    *(.init6)  /* C++ constructors.  */
+    KEEP (*(.init6))
+    *(.init7)
+    KEEP (*(.init7))
+    *(.init8)
+    KEEP (*(.init8))
+    *(.init9)  /* Call main().  */
+    KEEP (*(.init9))
+    *(.text)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.text.*)
+    ${RELOCATING+. = ALIGN(2);}
+    *(.fini9)  /* _exit() starts here.  */
+    KEEP (*(.fini9))
+    *(.fini8)
+    KEEP (*(.fini8))
+    *(.fini7)
+    KEEP (*(.fini7))
+    *(.fini6)  /* C++ destructors.  */
+    KEEP (*(.fini6))
+    *(.fini5)
+    KEEP (*(.fini5))
+    *(.fini4)
+    KEEP (*(.fini4))
+    *(.fini3)
+    KEEP (*(.fini3))
+    *(.fini2)
+    KEEP (*(.fini2))
+    *(.fini1)
+    KEEP (*(.fini1))
+    *(.fini0)  /* Infinite loop after program termination.  */
+    KEEP (*(.fini0))
+    ${RELOCATING+ _etext = . ; }
+  } ${RELOCATING+ > text}
+
+  .data	${RELOCATING-0} : ${RELOCATING+AT (ADDR (.text) + SIZEOF (.text))}
+  {
+    ${RELOCATING+ PROVIDE (__data_start = .) ; }
+    *(.data)
+    KEEP (*(.data))
+    *(.data*)
+    *(.rodata)  /* We need to include .rodata here if gcc is used */
+    *(.rodata*) /* with -fdata-sections.  */
+    *(.gnu.linkonce.d*)
+    ${RELOCATING+. = ALIGN(2);}
+    ${RELOCATING+ _edata = . ; }
+    ${RELOCATING+ PROVIDE (__data_end = .) ; }
+  } ${RELOCATING+ > data}
+
+  .bss ${RELOCATING-0} :${RELOCATING+ AT (ADDR (.bss))}
+  {
+    ${RELOCATING+ PROVIDE (__bss_start = .) ; }
+    *(.bss)
+    *(.bss*)
+    *(COMMON)
+    ${RELOCATING+ PROVIDE (__bss_end = .) ; }
+  } ${RELOCATING+ > data}
+
+  ${RELOCATING+ __data_load_start = LOADADDR(.data); }
+  ${RELOCATING+ __data_load_end = __data_load_start + SIZEOF(.data); }
+
+  /* Global data not cleared after reset.  */
+  .noinit ${RELOCATING-0}:
+  {
+    ${RELOCATING+ PROVIDE (__noinit_start = .) ; }
+    *(.noinit*)
+    ${RELOCATING+ PROVIDE (__noinit_end = .) ; }
+    ${RELOCATING+ _end = . ;  }
+    ${RELOCATING+ PROVIDE (__heap_start = .) ; }
+  } ${RELOCATING+ > data}
+
+  .lock ${RELOCATING-0}:
+  {
+    KEEP(*(.lock*))
+  } ${RELOCATING+ > lock}
+
+  .signature ${RELOCATING-0}:
+  {
+    KEEP(*(.signature*))
+  } ${RELOCATING+ > signature}
+
+  .config ${RELOCATING-0}:
+  {
+    KEEP(*(.config*))
+  } ${RELOCATING+ > config}
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+ 
+  /* DWARF debug sections.
+     Symbols in the DWARF debugging sections are relative to the beginning
+     of the section so we begin them at 0.  */
+
+  /* DWARF 1 */
+  .debug          0 : { *(.debug) }
+  .line           0 : { *(.line) }
+
+  /* GNU DWARF 1 extensions */
+  .debug_srcinfo  0 : { *(.debug_srcinfo) }
+  .debug_sfnames  0 : { *(.debug_sfnames) }
+
+  /* DWARF 1.1 and DWARF 2 */
+  .debug_aranges  0 : { *(.debug_aranges) }
+  .debug_pubnames 0 : { *(.debug_pubnames) }
+
+  /* DWARF 2 */
+  .debug_info     0 : { *(.debug_info) *(.gnu.linkonce.wi.*) }
+  .debug_abbrev   0 : { *(.debug_abbrev) }
+  .debug_line     0 : { *(.debug_line) }
+  .debug_frame    0 : { *(.debug_frame) }
+  .debug_str      0 : { *(.debug_str) }
+  .debug_loc      0 : { *(.debug_loc) }
+  .debug_macinfo  0 : { *(.debug_macinfo) }
+}
+EOF
+
diff --git a/opcodes/avr-dis.c b/opcodes/avr-dis.c
index 9a8ae33..78c9948 100644
--- a/opcodes/avr-dis.c
+++ b/opcodes/avr-dis.c
@@ -186,6 +186,17 @@ avr_operand (unsigned int insn, unsigned int insn2, unsigned int pc, int constra
     case 'i':
       sprintf (buf, "0x%04X", insn2);
       break;
+
+    case 'j':
+      {
+        unsigned int val = ((insn & 0xf) | ((insn & 0x600) >> 5)
+                                         | ((insn & 0x100) >> 2));
+        if (val > 0 && !(insn & 0x100))
+          val |= 0x80;
+        sprintf (buf, "0x%02x", val);
+        sprintf (buf, "%d", val);
+      }
+      break;
       
     case 'M':
       sprintf (buf, "0x%02X", ((insn & 0xf00) >> 4) | (insn & 0xf));
@@ -329,8 +340,12 @@ print_insn_avr (bfd_vma addr, disassemble_info *info)
   for (opcode = avr_opcodes, maskptr = avr_bin_masks;
        opcode->name;
        opcode++, maskptr++)
-    if ((insn & *maskptr) == opcode->bin_opcode)
-      break;
+    {
+      if ((opcode->isa == AVR_ISA_TINY) && (info->mach != bfd_mach_avrtiny))
+        continue;
+      if ((insn & *maskptr) == opcode->bin_opcode)
+        break;
+    }
   
   /* Special case: disassemble `ldd r,b+0' as `ld r,b', and
      `std b+0,r' as `st b,r' (next entry in the table).  */

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers
  2014-06-30 13:17   ` S, Pitchumani
@ 2014-07-01  9:25     ` Nicholas Clifton
  0 siblings, 0 replies; 5+ messages in thread
From: Nicholas Clifton @ 2014-07-01  9:25 UTC (permalink / raw)
  To: S, Pitchumani, binutils, Denis Chertykov, Barney Stratford

Hi Pitchumani,

> I have merged the tiny support patch of Barney Startford and Atmel.
> Updated patch is attached. Please review.
>
> If OK, could someone commit please?

Approved and applied.  Note - there was one small omission - updating 
gas/doc/c-avr.texi to mention the support for the AVR Tiny architcture. 
  I took care of this.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2014-07-01  9:25 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-14 19:04 [PATCH] Add support for ATtiny4/5/9/10/20/40 microcontrollers Barney Stratford
2014-06-22 10:05 ` Barney Stratford
2014-06-24  8:27 ` S, Pitchumani
2014-06-30 13:17   ` S, Pitchumani
2014-07-01  9:25     ` Nicholas Clifton

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).