$OpenBSD: patch-gas_config_tc-avr_c,v 1.3 2010/06/27 20:58:10 ckuethe Exp $
--- gas/config/tc-avr.c.orig	Sat Jun 26 11:23:23 2010
+++ gas/config/tc-avr.c	Sat Jun 26 11:31:17 2010
@@ -27,20 +27,21 @@
 
 struct avr_opcodes_s
 {
-  char *        name;
-  char *        constraints;
-  int           insn_size;		/* In words.  */
-  int           isa;
+  char *name;
+  char *constraints;
+  char *opcode;
+  int insn_size;		/* In words.  */
+  int isa;
   unsigned int  bin_opcode;
 };
 
 #define AVR_INSN(NAME, CONSTR, OPCODE, SIZE, ISA, BIN) \
-{#NAME, CONSTR, SIZE, ISA, BIN},
+{#NAME, CONSTR, OPCODE, SIZE, ISA, BIN},
 
 struct avr_opcodes_s avr_opcodes[] =
 {
   #include "opcode/avr.h"
-  {NULL, NULL, 0, 0, 0}
+  {NULL, NULL, NULL, 0, 0, 0}
 };
 
 const char comment_chars[] = ";";
@@ -79,6 +80,13 @@ static struct mcu_type_s mcu_types[] =
   {"avr5",       AVR_ISA_AVR51,   bfd_mach_avr5},
   {"avr51",      AVR_ISA_AVR51,   bfd_mach_avr51},
   {"avr6",       AVR_ISA_AVR6,    bfd_mach_avr6},
+  {"avrxmega1",  AVR_ISA_XMEGA,   bfd_mach_avrxmega1},
+  {"avrxmega2",  AVR_ISA_XMEGA,   bfd_mach_avrxmega2},
+  {"avrxmega3",  AVR_ISA_XMEGA,   bfd_mach_avrxmega3},
+  {"avrxmega4",  AVR_ISA_XMEGA,   bfd_mach_avrxmega4},
+  {"avrxmega5",  AVR_ISA_XMEGA,   bfd_mach_avrxmega5},
+  {"avrxmega6",  AVR_ISA_XMEGA,   bfd_mach_avrxmega6},
+  {"avrxmega7",  AVR_ISA_XMEGA,   bfd_mach_avrxmega7},
   {"at90s1200",  AVR_ISA_1200,    bfd_mach_avr1},
   {"attiny11",   AVR_ISA_AVR1,    bfd_mach_avr1},
   {"attiny12",   AVR_ISA_AVR1,    bfd_mach_avr1},
@@ -133,9 +141,12 @@ static struct mcu_type_s mcu_types[] =
   {"atmega32u2", AVR_ISA_AVR35,   bfd_mach_avr35},
   {"atmega8",    AVR_ISA_M8,      bfd_mach_avr4},
   {"atmega48",   AVR_ISA_AVR4,    bfd_mach_avr4},
+  {"atmega48a",  AVR_ISA_AVR4,    bfd_mach_avr4},
   {"atmega48p",  AVR_ISA_AVR4,    bfd_mach_avr4},
   {"atmega88",   AVR_ISA_AVR4,    bfd_mach_avr4},
+  {"atmega88a",  AVR_ISA_AVR4,    bfd_mach_avr4},
   {"atmega88p",  AVR_ISA_AVR4,    bfd_mach_avr4},
+  {"atmega88pa", AVR_ISA_AVR4,    bfd_mach_avr4},
   {"atmega8515", AVR_ISA_M8,      bfd_mach_avr4},
   {"atmega8535", AVR_ISA_M8,      bfd_mach_avr4},
   {"atmega8hva", AVR_ISA_AVR4,    bfd_mach_avr4},
@@ -150,40 +161,63 @@ static struct mcu_type_s mcu_types[] =
   {"at90pwm3b",  AVR_ISA_AVR4,    bfd_mach_avr4},
   {"at90pwm81",  AVR_ISA_AVR4,    bfd_mach_avr4},
   {"atmega16",   AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega16a",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega161",  AVR_ISA_M161,    bfd_mach_avr5},
   {"atmega162",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega163",  AVR_ISA_M161,    bfd_mach_avr5},
+  {"atmega164a", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega164p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega165",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega165p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega168",  AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega168a", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega168p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega169",  AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega169a", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega169p", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega169pa",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega16hva",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega16hvb",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega16c1", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega32",   AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega323",  AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega324a", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega324p", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega324pa",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega325",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega325p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega3250", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega3250p",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega328",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega328p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega329",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega329p", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega329pa",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega3290", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega3290p",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega32hvb",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega406",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega64",   AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega640",  AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega644",  AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega644a", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega644p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega644pa",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega645",  AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega645a", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega645p", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega649",  AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega649p", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega649a", AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega6450", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega6450a",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega6450p",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega6490", AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega6490a",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega6490p",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega64hve",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega16hva",AVR_ISA_AVR5,    bfd_mach_avr5},
+  {"atmega16hva2",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega16hvb",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"atmega32hvb",AVR_ISA_AVR5,    bfd_mach_avr5},
   {"at90can32" , AVR_ISA_AVR5,    bfd_mach_avr5},
@@ -215,6 +249,21 @@ static struct mcu_type_s mcu_types[] =
   {"m3001b",     AVR_ISA_AVR51,   bfd_mach_avr51},
   {"atmega2560", AVR_ISA_AVR6,    bfd_mach_avr6},
   {"atmega2561", AVR_ISA_AVR6,    bfd_mach_avr6},
+  {"atxmega16a4", AVR_ISA_XMEGA,  bfd_mach_avrxmega2},
+  {"atxmega16d4", AVR_ISA_XMEGA,  bfd_mach_avrxmega2},
+  {"atxmega32d4", AVR_ISA_XMEGA,  bfd_mach_avrxmega2},
+  {"atxmega32a4", AVR_ISA_XMEGA,  bfd_mach_avrxmega3},
+  {"atxmega64a3", AVR_ISA_XMEGA,  bfd_mach_avrxmega4},
+  {"atxmega64d3", AVR_ISA_XMEGA,  bfd_mach_avrxmega4},
+  {"atxmega64a1", AVR_ISA_XMEGA,  bfd_mach_avrxmega5},
+  {"atxmega128a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega128d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega192a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega192d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega256a3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega256a3b",AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega256d3", AVR_ISA_XMEGA, bfd_mach_avrxmega6},
+  {"atxmega128a1", AVR_ISA_XMEGA, bfd_mach_avrxmega7},
   {NULL, 0, 0}
 };
 
@@ -392,6 +441,11 @@ md_show_usage (FILE *stream)
 	"                   avr5  - enhanced AVR core with up to 64K program memory\n"
 	"                   avr51 - enhanced AVR core with up to 128K program memory\n"
 	"                   avr6  - enhanced AVR core with up to 256K program memory\n"
+	"                   avrxmega3 - XMEGA, > 8K, <= 64K FLASH, > 64K RAM\n"
+	"                   avrxmega4 - XMEGA, > 64K, <= 128K FLASH, <= 64K RAM\n"
+	"                   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"));
   fprintf (stream,
       _("  -mall-opcodes    accept all AVR opcodes, even if not supported by MCU\n"
@@ -819,7 +873,12 @@ avr_operand (struct avr_opcodes_s *opcode,
       if (*str == '+')
 	{
 	  ++str;
-	  op_mask |= 1;
+          char *s;
+          for (s = opcode->opcode; *s; ++s)
+            {
+              if (*s == '+')
+                op_mask |= (1 << (15 - (s - opcode->opcode)));
+            }
 	}
 
       /* attiny26 can do "lpm" and "lpm r,Z" but not "lpm r,Z+".  */
@@ -936,6 +995,16 @@ avr_operand (struct avr_opcodes_s *opcode,
       }
       break;
 
+    case 'E':
+      {
+	unsigned int x;
+
+	x = avr_get_constant (str, 15);
+	str = input_line_pointer;
+	op_mask |= (x << 4);
+      }
+      break;
+    
     case '?':
       break;
 
