/* Target-dependent code for Atmel AVR, for GDB.

   Copyright (C) 1996-2020 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* Contributed by Theodore A. Roth, troth@openavr.org */

/* Portions of this file were taken from the original gdb-4.18 patch developed
   by Denis Chertykov, denisc@overta.ru */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "gdbtypes.h"
#include "inferior.h"
#include "symfile.h"
#include "arch-utils.h"
#include "regcache.h"
#include "dis-asm.h"
#include "objfiles.h"
#include <algorithm>

/* AVR Background:

   (AVR micros are pure Harvard Architecture processors.)

   The AVR family of microcontrollers have three distinctly different memory
   spaces: flash, sram and eeprom.  The flash is 16 bits wide and is used for
   the most part to store program instructions.  The sram is 8 bits wide and is
   used for the stack and the heap.  Some devices lack sram and some can have
   an additional external sram added on as a peripheral.

   The eeprom is 8 bits wide and is used to store data when the device is
   powered down.  Eeprom is not directly accessible, it can only be accessed
   via io-registers using a special algorithm.  Accessing eeprom via gdb's
   remote serial protocol ('m' or 'M' packets) looks difficult to do and is
   not included at this time.

   [The eeprom could be read manually via ``x/b <eaddr + AVR_EMEM_START>'' or
   written using ``set {unsigned char}<eaddr + AVR_EMEM_START>''.  For this to
   work, the remote target must be able to handle eeprom accesses and perform
   the address translation.]

   All three memory spaces have physical addresses beginning at 0x0.  In
   addition, the flash is addressed by gcc/binutils/gdb with respect to 8 bit
   bytes instead of the 16 bit wide words used by the real device for the
   Program Counter.

   In order for remote targets to work correctly, extra bits must be added to
   addresses before they are send to the target or received from the target
   via the remote serial protocol.  The extra bits are the MSBs and are used to
   decode which memory space the address is referring to.  */

/* Constants: prefixed with AVR_ to avoid name space clashes */

/* Address space flags */

/* We are assigning the TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1 to the flash address
   space.  */

#define AVR_TYPE_ADDRESS_CLASS_FLASH TYPE_ADDRESS_CLASS_1
#define AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH  \
  TYPE_INSTANCE_FLAG_ADDRESS_CLASS_1


enum
{
  AVR_REG_W = 24,
  AVR_REG_X = 26,
  AVR_REG_Y = 28,
  AVR_FP_REGNUM = 28,
  AVR_REG_Z = 30,

  AVR_SREG_REGNUM = 32,
  AVR_SP_REGNUM = 33,
  AVR_PC_REGNUM = 34,

  AVR_NUM_REGS = 32 + 1 /*SREG*/ + 1 /*SP*/ + 1 /*PC*/,
  AVR_NUM_REG_BYTES = 32 + 1 /*SREG*/ + 2 /*SP*/ + 4 /*PC*/,

  /* Pseudo registers.  */
  AVR_PSEUDO_PC_REGNUM = 35,
  AVR_NUM_PSEUDO_REGS = 1,

  AVR_PC_REG_INDEX = 35,	/* index into array of registers */

  AVR_MAX_PROLOGUE_SIZE = 64,	/* bytes */

  /* Count of pushed registers.  From r2 to r17 (inclusively), r28, r29 */
  AVR_MAX_PUSHES = 18,

  /* Number of the last pushed register.  r17 for current avr-gcc */
  AVR_LAST_PUSHED_REGNUM = 17,

  AVR_ARG1_REGNUM = 24,         /* Single byte argument */
  AVR_ARGN_REGNUM = 25,         /* Multi byte argments */
  AVR_LAST_ARG_REGNUM = 8,      /* Last argument register */

  AVR_RET1_REGNUM = 24,         /* Single byte return value */
  AVR_RETN_REGNUM = 25,         /* Multi byte return value */

  /* FIXME: TRoth/2002-01-??: Can we shift all these memory masks left 8
     bits?  Do these have to match the bfd vma values?  It sure would make
     things easier in the future if they didn't need to match.

     Note: I chose these values so as to be consistent with bfd vma
     addresses.

     TRoth/2002-04-08: There is already a conflict with very large programs
     in the mega128.  The mega128 has 128K instruction bytes (64K words),
     thus the Most Significant Bit is 0x10000 which gets masked off my
     AVR_MEM_MASK.

     The problem manifests itself when trying to set a breakpoint in a
     function which resides in the upper half of the instruction space and
     thus requires a 17-bit address.

     For now, I've just removed the EEPROM mask and changed AVR_MEM_MASK
     from 0x00ff0000 to 0x00f00000.  Eeprom is not accessible from gdb yet,
     but could be for some remote targets by just adding the correct offset
     to the address and letting the remote target handle the low-level
     details of actually accessing the eeprom.  */

  AVR_IMEM_START = 0x00000000,	/* INSN memory */
  AVR_SMEM_START = 0x00800000,	/* SRAM memory */
#if 1
  /* No eeprom mask defined */
  AVR_MEM_MASK = 0x00f00000,	/* mask to determine memory space */
#else
  AVR_EMEM_START = 0x00810000,	/* EEPROM memory */
  AVR_MEM_MASK = 0x00ff0000,	/* mask to determine memory space */
#endif
};

/* Prologue types:

   NORMAL and CALL are the typical types (the -mcall-prologues gcc option
   causes the generation of the CALL type prologues).  */

enum {
    AVR_PROLOGUE_NONE,              /* No prologue */
    AVR_PROLOGUE_NORMAL,
    AVR_PROLOGUE_CALL,              /* -mcall-prologues */
    AVR_PROLOGUE_MAIN,
    AVR_PROLOGUE_INTR,              /* interrupt handler */
    AVR_PROLOGUE_SIG,               /* signal handler */
};

/* Any function with a frame looks like this
   .......    <-SP POINTS HERE
   LOCALS1    <-FP POINTS HERE
   LOCALS0
   SAVED FP
   SAVED R3
   SAVED R2
   RET PC
   FIRST ARG
   SECOND ARG */

struct avr_unwind_cache
{
  /* The previous frame's inner most stack address.  Used as this
     frame ID's stack_addr.  */
  CORE_ADDR prev_sp;
  /* The frame's base, optionally used by the high-level debug info.  */
  CORE_ADDR base;
  int size;
  int prologue_type;
  /* Table indicating the location of each and every register.  */
  struct trad_frame_saved_reg *saved_regs;
};

struct gdbarch_tdep
{
  /* Number of bytes stored to the stack by call instructions.
     2 bytes for avr1-5 and avrxmega1-5, 3 bytes for avr6 and avrxmega6-7.  */
  int call_length;

  /* Type for void.  */
  struct type *void_type;
  /* Type for a function returning void.  */
  struct type *func_void_type;
  /* Type for a pointer to a function.  Used for the type of PC.  */
  struct type *pc_type;
};

/* Lookup the name of a register given it's number.  */

static const char *
avr_register_name (struct gdbarch *gdbarch, int regnum)
{
  static const char * const register_names[] = {
    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
    "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
    "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
    "SREG", "SP", "PC2",
    "pc"
  };
  if (regnum < 0)
    return NULL;
  if (regnum >= (sizeof (register_names) / sizeof (*register_names)))
    return NULL;
  return register_names[regnum];
}

/* Return the GDB type object for the "standard" data type
   of data in register N.  */

static struct type *
avr_register_type (struct gdbarch *gdbarch, int reg_nr)
{
  if (reg_nr == AVR_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_uint32;
  if (reg_nr == AVR_PSEUDO_PC_REGNUM)
    return gdbarch_tdep (gdbarch)->pc_type;
  if (reg_nr == AVR_SP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;
  return builtin_type (gdbarch)->builtin_uint8;
}

/* Instruction address checks and convertions.  */

static CORE_ADDR
avr_make_iaddr (CORE_ADDR x)
{
  return ((x) | AVR_IMEM_START);
}

/* FIXME: TRoth: Really need to use a larger mask for instructions.  Some
   devices are already up to 128KBytes of flash space.

   TRoth/2002-04-8: See comment above where AVR_IMEM_START is defined.  */

static CORE_ADDR
avr_convert_iaddr_to_raw (CORE_ADDR x)
{
  return ((x) & 0xffffffff);
}

/* SRAM address checks and convertions.  */

static CORE_ADDR
avr_make_saddr (CORE_ADDR x)
{
  /* Return 0 for NULL.  */
  if (x == 0)
    return 0;

  return ((x) | AVR_SMEM_START);
}

static CORE_ADDR
avr_convert_saddr_to_raw (CORE_ADDR x)
{
  return ((x) & 0xffffffff);
}

/* EEPROM address checks and convertions.  I don't know if these will ever
   actually be used, but I've added them just the same.  TRoth */

/* TRoth/2002-04-08: Commented out for now to allow fix for problem with large
   programs in the mega128.  */

/*  static CORE_ADDR */
/*  avr_make_eaddr (CORE_ADDR x) */
/*  { */
/*    return ((x) | AVR_EMEM_START); */
/*  } */

/*  static int */
/*  avr_eaddr_p (CORE_ADDR x) */
/*  { */
/*    return (((x) & AVR_MEM_MASK) == AVR_EMEM_START); */
/*  } */

/*  static CORE_ADDR */
/*  avr_convert_eaddr_to_raw (CORE_ADDR x) */
/*  { */
/*    return ((x) & 0xffffffff); */
/*  } */

/* Convert from address to pointer and vice-versa.  */

static void
avr_address_to_pointer (struct gdbarch *gdbarch,
			struct type *type, gdb_byte *buf, CORE_ADDR addr)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* Is it a data address in flash?  */
  if (AVR_TYPE_ADDRESS_CLASS_FLASH (type))
    {
      /* A data pointer in flash is byte addressed.  */
      store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order,
			      avr_convert_iaddr_to_raw (addr));
    }
  /* Is it a code address?  */
  else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
	   || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD)
    {
      /* A code pointer is word (16 bits) addressed.  We shift the address down
	 by 1 bit to convert it to a pointer.  */
      store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order,
			      avr_convert_iaddr_to_raw (addr >> 1));
    }
  else
    {
      /* Strip off any upper segment bits.  */
      store_unsigned_integer (buf, TYPE_LENGTH (type), byte_order,
			      avr_convert_saddr_to_raw (addr));
    }
}

static CORE_ADDR
avr_pointer_to_address (struct gdbarch *gdbarch,
			struct type *type, const gdb_byte *buf)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR addr
    = extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);

  /* Is it a data address in flash?  */
  if (AVR_TYPE_ADDRESS_CLASS_FLASH (type))
    {
      /* A data pointer in flash is already byte addressed.  */
      return avr_make_iaddr (addr);
    }
  /* Is it a code address?  */
  else if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_FUNC
	   || TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_METHOD
	   || TYPE_CODE_SPACE (TYPE_TARGET_TYPE (type)))
    {
      /* A code pointer is word (16 bits) addressed so we shift it up
	 by 1 bit to convert it to an address.  */
      return avr_make_iaddr (addr << 1);
    }
  else
    return avr_make_saddr (addr);
}

static CORE_ADDR
avr_integer_to_address (struct gdbarch *gdbarch,
			struct type *type, const gdb_byte *buf)
{
  ULONGEST addr = unpack_long (type, buf);

  return avr_make_saddr (addr);
}

static CORE_ADDR
avr_read_pc (readable_regcache *regcache)
{
  ULONGEST pc;

  regcache->cooked_read (AVR_PC_REGNUM, &pc);
  return avr_make_iaddr (pc);
}

static void
avr_write_pc (struct regcache *regcache, CORE_ADDR val)
{
  regcache_cooked_write_unsigned (regcache, AVR_PC_REGNUM,
                                  avr_convert_iaddr_to_raw (val));
}

static enum register_status
avr_pseudo_register_read (struct gdbarch *gdbarch, readable_regcache *regcache,
                          int regnum, gdb_byte *buf)
{
  ULONGEST val;
  enum register_status status;

  switch (regnum)
    {
    case AVR_PSEUDO_PC_REGNUM:
      status = regcache->raw_read (AVR_PC_REGNUM, &val);
      if (status != REG_VALID)
	return status;
      val >>= 1;
      store_unsigned_integer (buf, 4, gdbarch_byte_order (gdbarch), val);
      return status;
    default:
      internal_error (__FILE__, __LINE__, _("invalid regnum"));
    }
}

static void
avr_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
                           int regnum, const gdb_byte *buf)
{
  ULONGEST val;

  switch (regnum)
    {
    case AVR_PSEUDO_PC_REGNUM:
      val = extract_unsigned_integer (buf, 4, gdbarch_byte_order (gdbarch));
      val <<= 1;
      regcache_raw_write_unsigned (regcache, AVR_PC_REGNUM, val);
      break;
    default:
      internal_error (__FILE__, __LINE__, _("invalid regnum"));
    }
}

/* Function: avr_scan_prologue

   This function decodes an AVR function prologue to determine:
     1) the size of the stack frame
     2) which registers are saved on it
     3) the offsets of saved regs
   This information is stored in the avr_unwind_cache structure.

   Some devices lack the sbiw instruction, so on those replace this:
        sbiw    r28, XX
   with this:
        subi    r28,lo8(XX)
        sbci    r29,hi8(XX)

   A typical AVR function prologue with a frame pointer might look like this:
        push    rXX        ; saved regs
        ...
        push    r28
        push    r29
        in      r28,__SP_L__
        in      r29,__SP_H__
        sbiw    r28,<LOCALS_SIZE>
        in      __tmp_reg__,__SREG__
        cli
        out     __SP_H__,r29
        out     __SREG__,__tmp_reg__
        out     __SP_L__,r28

   A typical AVR function prologue without a frame pointer might look like
   this:
        push    rXX        ; saved regs
        ...

   A main function prologue looks like this:
        ldi     r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>)
        ldi     r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>)
        out     __SP_H__,r29
        out     __SP_L__,r28

   A signal handler prologue looks like this:
        push    __zero_reg__
        push    __tmp_reg__
        in      __tmp_reg__, __SREG__
        push    __tmp_reg__
        clr     __zero_reg__
        push    rXX             ; save registers r18:r27, r30:r31
        ...
        push    r28             ; save frame pointer
        push    r29
        in      r28, __SP_L__
        in      r29, __SP_H__
        sbiw    r28, <LOCALS_SIZE>
        out     __SP_H__, r29
        out     __SP_L__, r28
        
   A interrupt handler prologue looks like this:
        sei
        push    __zero_reg__
        push    __tmp_reg__
        in      __tmp_reg__, __SREG__
        push    __tmp_reg__
        clr     __zero_reg__
        push    rXX             ; save registers r18:r27, r30:r31
        ...
        push    r28             ; save frame pointer
        push    r29
        in      r28, __SP_L__
        in      r29, __SP_H__
        sbiw    r28, <LOCALS_SIZE>
        cli
        out     __SP_H__, r29
        sei     
        out     __SP_L__, r28

   A `-mcall-prologues' prologue looks like this (Note that the megas use a
   jmp instead of a rjmp, thus the prologue is one word larger since jmp is a
   32 bit insn and rjmp is a 16 bit insn):
        ldi     r26,lo8(<LOCALS_SIZE>)
        ldi     r27,hi8(<LOCALS_SIZE>)
        ldi     r30,pm_lo8(.L_foo_body)
        ldi     r31,pm_hi8(.L_foo_body)
        rjmp    __prologue_saves__+RRR
        .L_foo_body:  */

/* Not really part of a prologue, but still need to scan for it, is when a
   function prologue moves values passed via registers as arguments to new
   registers.  In this case, all local variables live in registers, so there
   may be some register saves.  This is what it looks like:
        movw    rMM, rNN
        ...

   There could be multiple movw's.  If the target doesn't have a movw insn, it
   will use two mov insns.  This could be done after any of the above prologue
   types.  */

static CORE_ADDR
avr_scan_prologue (struct gdbarch *gdbarch, CORE_ADDR pc_beg, CORE_ADDR pc_end,
		   struct avr_unwind_cache *info)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int i;
  unsigned short insn;
  int scan_stage = 0;
  struct bound_minimal_symbol msymbol;
  unsigned char prologue[AVR_MAX_PROLOGUE_SIZE];
  int vpc = 0;
  int len;

  len = pc_end - pc_beg;
  if (len > AVR_MAX_PROLOGUE_SIZE)
    len = AVR_MAX_PROLOGUE_SIZE;

  /* FIXME: TRoth/2003-06-11: This could be made more efficient by only
     reading in the bytes of the prologue.  The problem is that the figuring
     out where the end of the prologue is is a bit difficult.  The old code 
     tried to do that, but failed quite often.  */
  read_memory (pc_beg, prologue, len);

  /* Scanning main()'s prologue
     ldi r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>)
     ldi r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>)
     out __SP_H__,r29
     out __SP_L__,r28 */

  if (len >= 4)
    {
      CORE_ADDR locals;
      static const unsigned char img[] = {
	0xde, 0xbf,		/* out __SP_H__,r29 */
	0xcd, 0xbf		/* out __SP_L__,r28 */
      };

      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
      /* ldi r28,lo8(<RAM_ADDR> - <LOCALS_SIZE>) */
      if ((insn & 0xf0f0) == 0xe0c0)
	{
	  locals = (insn & 0xf) | ((insn & 0x0f00) >> 4);
	  insn = extract_unsigned_integer (&prologue[vpc + 2], 2, byte_order);
	  /* ldi r29,hi8(<RAM_ADDR> - <LOCALS_SIZE>) */
	  if ((insn & 0xf0f0) == 0xe0d0)
	    {
	      locals |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
	      if (vpc + 4 + sizeof (img) < len
		  && memcmp (prologue + vpc + 4, img, sizeof (img)) == 0)
		{
                  info->prologue_type = AVR_PROLOGUE_MAIN;
                  info->base = locals;
                  return pc_beg + 4;
		}
	    }
	}
    }

  /* Scanning `-mcall-prologues' prologue
     Classic prologue is 10 bytes, mega prologue is a 12 bytes long */

  while (1)	/* Using a while to avoid many goto's */
    {
      int loc_size;
      int body_addr;
      unsigned num_pushes;
      int pc_offset = 0;

      /* At least the fifth instruction must have been executed to
	 modify frame shape.  */
      if (len < 10)
	break;

      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
      /* ldi r26,<LOCALS_SIZE> */
      if ((insn & 0xf0f0) != 0xe0a0)
	break;
      loc_size = (insn & 0xf) | ((insn & 0x0f00) >> 4);
      pc_offset += 2;

      insn = extract_unsigned_integer (&prologue[vpc + 2], 2, byte_order);
      /* ldi r27,<LOCALS_SIZE> / 256 */
      if ((insn & 0xf0f0) != 0xe0b0)
	break;
      loc_size |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
      pc_offset += 2;

      insn = extract_unsigned_integer (&prologue[vpc + 4], 2, byte_order);
      /* ldi r30,pm_lo8(.L_foo_body) */
      if ((insn & 0xf0f0) != 0xe0e0)
	break;
      body_addr = (insn & 0xf) | ((insn & 0x0f00) >> 4);
      pc_offset += 2;

      insn = extract_unsigned_integer (&prologue[vpc + 6], 2, byte_order);
      /* ldi r31,pm_hi8(.L_foo_body) */
      if ((insn & 0xf0f0) != 0xe0f0)
	break;
      body_addr |= ((insn & 0xf) | ((insn & 0x0f00) >> 4)) << 8;
      pc_offset += 2;

      msymbol = lookup_minimal_symbol ("__prologue_saves__", NULL, NULL);
      if (!msymbol.minsym)
	break;

      insn = extract_unsigned_integer (&prologue[vpc + 8], 2, byte_order);
      /* rjmp __prologue_saves__+RRR */
      if ((insn & 0xf000) == 0xc000)
        {
          /* Extract PC relative offset from RJMP */
          i = (insn & 0xfff) | (insn & 0x800 ? (-1 ^ 0xfff) : 0);
          /* Convert offset to byte addressable mode */
          i *= 2;
          /* Destination address */
          i += pc_beg + 10;

          if (body_addr != (pc_beg + 10)/2)
            break;

          pc_offset += 2;
        }
      else if ((insn & 0xfe0e) == 0x940c)
        {
          /* Extract absolute PC address from JMP */
          i = (((insn & 0x1) | ((insn & 0x1f0) >> 3) << 16)
	       | (extract_unsigned_integer (&prologue[vpc + 10], 2, byte_order)
		  & 0xffff));
          /* Convert address to byte addressable mode */
          i *= 2;

          if (body_addr != (pc_beg + 12)/2)
            break;

          pc_offset += 4;
        }
      else
        break;

      /* Resolve offset (in words) from __prologue_saves__ symbol.
         Which is a pushes count in `-mcall-prologues' mode */
      num_pushes = AVR_MAX_PUSHES - (i - BMSYMBOL_VALUE_ADDRESS (msymbol)) / 2;

      if (num_pushes > AVR_MAX_PUSHES)
        {
          fprintf_unfiltered (gdb_stderr, _("Num pushes too large: %d\n"),
                              num_pushes);
          num_pushes = 0;
        }

      if (num_pushes)
	{
	  int from;

	  info->saved_regs[AVR_FP_REGNUM + 1].addr = num_pushes;
	  if (num_pushes >= 2)
	    info->saved_regs[AVR_FP_REGNUM].addr = num_pushes - 1;

	  i = 0;
	  for (from = AVR_LAST_PUSHED_REGNUM + 1 - (num_pushes - 2);
	       from <= AVR_LAST_PUSHED_REGNUM; ++from)
	    info->saved_regs [from].addr = ++i;
	}
      info->size = loc_size + num_pushes;
      info->prologue_type = AVR_PROLOGUE_CALL;

      return pc_beg + pc_offset;
    }

  /* Scan for the beginning of the prologue for an interrupt or signal
     function.  Note that we have to set the prologue type here since the
     third stage of the prologue may not be present (e.g. no saved registered
     or changing of the SP register).  */

  if (1)
    {
      static const unsigned char img[] = {
	0x78, 0x94,		/* sei */
	0x1f, 0x92,		/* push r1 */
	0x0f, 0x92,		/* push r0 */
	0x0f, 0xb6,		/* in r0,0x3f SREG */
	0x0f, 0x92,		/* push r0 */
	0x11, 0x24		/* clr r1 */
      };
      if (len >= sizeof (img)
	  && memcmp (prologue, img, sizeof (img)) == 0)
	{
          info->prologue_type = AVR_PROLOGUE_INTR;
	  vpc += sizeof (img);
          info->saved_regs[AVR_SREG_REGNUM].addr = 3;
          info->saved_regs[0].addr = 2;
          info->saved_regs[1].addr = 1;
          info->size += 3;
	}
      else if (len >= sizeof (img) - 2
	       && memcmp (img + 2, prologue, sizeof (img) - 2) == 0)
	{
          info->prologue_type = AVR_PROLOGUE_SIG;
          vpc += sizeof (img) - 2;
          info->saved_regs[AVR_SREG_REGNUM].addr = 3;
          info->saved_regs[0].addr = 2;
          info->saved_regs[1].addr = 1;
          info->size += 2;
	}
    }

  /* First stage of the prologue scanning.
     Scan pushes (saved registers) */

  for (; vpc < len; vpc += 2)
    {
      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
      if ((insn & 0xfe0f) == 0x920f)	/* push rXX */
	{
	  /* Bits 4-9 contain a mask for registers R0-R32.  */
	  int regno = (insn & 0x1f0) >> 4;
	  info->size++;
	  info->saved_regs[regno].addr = info->size;
	  scan_stage = 1;
	}
      else
	break;
    }

  gdb_assert (vpc < AVR_MAX_PROLOGUE_SIZE);

  /* Handle static small stack allocation using rcall or push.  */

  while (scan_stage == 1 && vpc < len)
    {
      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
      if (insn == 0xd000)	/* rcall .+0 */
        {
          info->size += gdbarch_tdep (gdbarch)->call_length;
          vpc += 2;
        }
      else if (insn == 0x920f || insn == 0x921f)  /* push r0 or push r1 */
        {
          info->size += 1;
          vpc += 2;
        }
      else
        break;
    }

  /* Second stage of the prologue scanning.
     Scan:
     in r28,__SP_L__
     in r29,__SP_H__ */

  if (scan_stage == 1 && vpc < len)
    {
      static const unsigned char img[] = {
	0xcd, 0xb7,		/* in r28,__SP_L__ */
	0xde, 0xb7		/* in r29,__SP_H__ */
      };

      if (vpc + sizeof (img) < len
	  && memcmp (prologue + vpc, img, sizeof (img)) == 0)
	{
	  vpc += 4;
	  scan_stage = 2;
	}
    }

  /* Third stage of the prologue scanning.  (Really two stages).
     Scan for:
     sbiw r28,XX or subi r28,lo8(XX)
                    sbci r29,hi8(XX)
     in __tmp_reg__,__SREG__
     cli
     out __SP_H__,r29
     out __SREG__,__tmp_reg__
     out __SP_L__,r28 */

  if (scan_stage == 2 && vpc < len)
    {
      int locals_size = 0;
      static const unsigned char img[] = {
	0x0f, 0xb6,		/* in r0,0x3f */
	0xf8, 0x94,		/* cli */
	0xde, 0xbf,		/* out 0x3e,r29 ; SPH */
	0x0f, 0xbe,		/* out 0x3f,r0  ; SREG */
	0xcd, 0xbf		/* out 0x3d,r28 ; SPL */
      };
      static const unsigned char img_sig[] = {
	0xde, 0xbf,		/* out 0x3e,r29 ; SPH */
	0xcd, 0xbf		/* out 0x3d,r28 ; SPL */
      };
      static const unsigned char img_int[] = {
	0xf8, 0x94,		/* cli */
	0xde, 0xbf,		/* out 0x3e,r29 ; SPH */
	0x78, 0x94,		/* sei */
	0xcd, 0xbf		/* out 0x3d,r28 ; SPL */
      };

      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
      if ((insn & 0xff30) == 0x9720)	/* sbiw r28,XXX */
        {
          locals_size = (insn & 0xf) | ((insn & 0xc0) >> 2);
          vpc += 2;
        }
      else if ((insn & 0xf0f0) == 0x50c0)	/* subi r28,lo8(XX) */
	{
	  locals_size = (insn & 0xf) | ((insn & 0xf00) >> 4);
	  vpc += 2;
	  insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
	  vpc += 2;
	  locals_size += ((insn & 0xf) | ((insn & 0xf00) >> 4)) << 8;
	}
      else
        return pc_beg + vpc;

      /* Scan the last part of the prologue.  May not be present for interrupt
         or signal handler functions, which is why we set the prologue type
         when we saw the beginning of the prologue previously.  */

      if (vpc + sizeof (img_sig) < len
	  && memcmp (prologue + vpc, img_sig, sizeof (img_sig)) == 0)
        {
          vpc += sizeof (img_sig);
        }
      else if (vpc + sizeof (img_int) < len 
	       && memcmp (prologue + vpc, img_int, sizeof (img_int)) == 0)
        {
          vpc += sizeof (img_int);
        }
      if (vpc + sizeof (img) < len
	  && memcmp (prologue + vpc, img, sizeof (img)) == 0)
        {
          info->prologue_type = AVR_PROLOGUE_NORMAL;
          vpc += sizeof (img);
        }

      info->size += locals_size;

      /* Fall through.  */
    }

  /* If we got this far, we could not scan the prologue, so just return the pc
     of the frame plus an adjustment for argument move insns.  */

  for (; vpc < len; vpc += 2)
    {
      insn = extract_unsigned_integer (&prologue[vpc], 2, byte_order);
      if ((insn & 0xff00) == 0x0100)	/* movw rXX, rYY */
        continue;
      else if ((insn & 0xfc00) == 0x2c00) /* mov rXX, rYY */
        continue;
      else
          break;
    }
    
  return pc_beg + vpc;
}

static CORE_ADDR
avr_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr, func_end;
  CORE_ADDR post_prologue_pc;

  /* See what the symbol table says */

  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
    return pc;

  post_prologue_pc = skip_prologue_using_sal (gdbarch, func_addr);
  if (post_prologue_pc != 0)
    return std::max (pc, post_prologue_pc);

  {
    CORE_ADDR prologue_end = pc;
    struct avr_unwind_cache info = {0};
    struct trad_frame_saved_reg saved_regs[AVR_NUM_REGS];

    info.saved_regs = saved_regs;
    
    /* Need to run the prologue scanner to figure out if the function has a
       prologue and possibly skip over moving arguments passed via registers
       to other registers.  */
    
    prologue_end = avr_scan_prologue (gdbarch, func_addr, func_end, &info);
    
    if (info.prologue_type != AVR_PROLOGUE_NONE)
      return prologue_end;
  }

  /* Either we didn't find the start of this function (nothing we can do),
     or there's no line info, or the line after the prologue is after
     the end of the function (there probably isn't a prologue).  */

  return pc;
}

/* Not all avr devices support the BREAK insn.  Those that don't should treat
   it as a NOP.  Thus, it should be ok.  Since the avr is currently a remote
   only target, this shouldn't be a problem (I hope).  TRoth/2003-05-14  */

constexpr gdb_byte avr_break_insn [] = { 0x98, 0x95 };

typedef BP_MANIPULATION (avr_break_insn) avr_breakpoint;

/* Determine, for architecture GDBARCH, how a return value of TYPE
   should be returned.  If it is supposed to be returned in registers,
   and READBUF is non-zero, read the appropriate value from REGCACHE,
   and copy it into READBUF.  If WRITEBUF is non-zero, write the value
   from WRITEBUF into REGCACHE.  */

static enum return_value_convention
avr_return_value (struct gdbarch *gdbarch, struct value *function,
		  struct type *valtype, struct regcache *regcache,
		  gdb_byte *readbuf, const gdb_byte *writebuf)
{
  int i;
  /* Single byte are returned in r24.
     Otherwise, the MSB of the return value is always in r25, calculate which
     register holds the LSB.  */
  int lsb_reg;

  if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
       || TYPE_CODE (valtype) == TYPE_CODE_UNION
       || TYPE_CODE (valtype) == TYPE_CODE_ARRAY)
      && TYPE_LENGTH (valtype) > 8)
    return RETURN_VALUE_STRUCT_CONVENTION;

  if (TYPE_LENGTH (valtype) <= 2)
    lsb_reg = 24;
  else if (TYPE_LENGTH (valtype) <= 4)
    lsb_reg = 22;
  else if (TYPE_LENGTH (valtype) <= 8)
    lsb_reg = 18;
  else
    gdb_assert_not_reached ("unexpected type length");

  if (writebuf != NULL)
    {
      for (i = 0; i < TYPE_LENGTH (valtype); i++)
	regcache->cooked_write (lsb_reg + i, writebuf + i);
    }

  if (readbuf != NULL)
    {
      for (i = 0; i < TYPE_LENGTH (valtype); i++)
	regcache->cooked_read (lsb_reg + i, readbuf + i);
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}


/* Put here the code to store, into fi->saved_regs, the addresses of
   the saved registers of frame described by FRAME_INFO.  This
   includes special registers such as pc and fp saved in special ways
   in the stack frame.  sp is even more special: the address we return
   for it IS the sp for the next frame.  */

static struct avr_unwind_cache *
avr_frame_unwind_cache (struct frame_info *this_frame,
                        void **this_prologue_cache)
{
  CORE_ADDR start_pc, current_pc;
  ULONGEST prev_sp;
  ULONGEST this_base;
  struct avr_unwind_cache *info;
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;
  int i;

  if (*this_prologue_cache)
    return (struct avr_unwind_cache *) *this_prologue_cache;

  info = FRAME_OBSTACK_ZALLOC (struct avr_unwind_cache);
  *this_prologue_cache = info;
  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);

  info->size = 0;
  info->prologue_type = AVR_PROLOGUE_NONE;

  start_pc = get_frame_func (this_frame);
  current_pc = get_frame_pc (this_frame);
  if ((start_pc > 0) && (start_pc <= current_pc))
    avr_scan_prologue (get_frame_arch (this_frame),
		       start_pc, current_pc, info);

  if ((info->prologue_type != AVR_PROLOGUE_NONE)
      && (info->prologue_type != AVR_PROLOGUE_MAIN))
    {
      ULONGEST high_base;       /* High byte of FP */

      /* The SP was moved to the FP.  This indicates that a new frame
         was created.  Get THIS frame's FP value by unwinding it from
         the next frame.  */
      this_base = get_frame_register_unsigned (this_frame, AVR_FP_REGNUM);
      high_base = get_frame_register_unsigned (this_frame, AVR_FP_REGNUM + 1);
      this_base += (high_base << 8);
      
      /* The FP points at the last saved register.  Adjust the FP back
         to before the first saved register giving the SP.  */
      prev_sp = this_base + info->size; 
   }
  else
    {
      /* Assume that the FP is this frame's SP but with that pushed
         stack space added back.  */
      this_base = get_frame_register_unsigned (this_frame, AVR_SP_REGNUM);
      prev_sp = this_base + info->size;
    }

  /* Add 1 here to adjust for the post-decrement nature of the push
     instruction.*/
  info->prev_sp = avr_make_saddr (prev_sp + 1);
  info->base = avr_make_saddr (this_base);

  gdbarch = get_frame_arch (this_frame);

  /* Adjust all the saved registers so that they contain addresses and not
     offsets.  */
  for (i = 0; i < gdbarch_num_regs (gdbarch) - 1; i++)
    if (info->saved_regs[i].addr > 0)
      info->saved_regs[i].addr = info->prev_sp - info->saved_regs[i].addr;

  /* Except for the main and startup code, the return PC is always saved on
     the stack and is at the base of the frame.  */

  if (info->prologue_type != AVR_PROLOGUE_MAIN)
    info->saved_regs[AVR_PC_REGNUM].addr = info->prev_sp;

  /* The previous frame's SP needed to be computed.  Save the computed
     value.  */
  tdep = gdbarch_tdep (gdbarch);
  trad_frame_set_value (info->saved_regs, AVR_SP_REGNUM,
                        info->prev_sp - 1 + tdep->call_length);

  return info;
}

static CORE_ADDR
avr_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  ULONGEST pc;

  pc = frame_unwind_register_unsigned (next_frame, AVR_PC_REGNUM);

  return avr_make_iaddr (pc);
}

static CORE_ADDR
avr_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  ULONGEST sp;

  sp = frame_unwind_register_unsigned (next_frame, AVR_SP_REGNUM);

  return avr_make_saddr (sp);
}

/* Given a GDB frame, determine the address of the calling function's
   frame.  This will be used to create a new GDB frame struct.  */

static void
avr_frame_this_id (struct frame_info *this_frame,
                   void **this_prologue_cache,
                   struct frame_id *this_id)
{
  struct avr_unwind_cache *info
    = avr_frame_unwind_cache (this_frame, this_prologue_cache);
  CORE_ADDR base;
  CORE_ADDR func;
  struct frame_id id;

  /* The FUNC is easy.  */
  func = get_frame_func (this_frame);

  /* Hopefully the prologue analysis either correctly determined the
     frame's base (which is the SP from the previous frame), or set
     that base to "NULL".  */
  base = info->prev_sp;
  if (base == 0)
    return;

  id = frame_id_build (base, func);
  (*this_id) = id;
}

static struct value *
avr_frame_prev_register (struct frame_info *this_frame,
			 void **this_prologue_cache, int regnum)
{
  struct avr_unwind_cache *info
    = avr_frame_unwind_cache (this_frame, this_prologue_cache);

  if (regnum == AVR_PC_REGNUM || regnum == AVR_PSEUDO_PC_REGNUM)
    {
      if (trad_frame_addr_p (info->saved_regs, AVR_PC_REGNUM))
        {
	  /* Reading the return PC from the PC register is slightly
	     abnormal.  register_size(AVR_PC_REGNUM) says it is 4 bytes,
	     but in reality, only two bytes (3 in upcoming mega256) are
	     stored on the stack.

	     Also, note that the value on the stack is an addr to a word
	     not a byte, so we will need to multiply it by two at some
	     point. 

	     And to confuse matters even more, the return address stored
	     on the stack is in big endian byte order, even though most
	     everything else about the avr is little endian.  Ick!  */
	  ULONGEST pc;
	  int i;
	  gdb_byte buf[3];
	  struct gdbarch *gdbarch = get_frame_arch (this_frame);
	  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);

	  read_memory (info->saved_regs[AVR_PC_REGNUM].addr,
                       buf, tdep->call_length);

	  /* Extract the PC read from memory as a big-endian.  */
	  pc = 0;
	  for (i = 0; i < tdep->call_length; i++)
	    pc = (pc << 8) | buf[i];

          if (regnum == AVR_PC_REGNUM)
            pc <<= 1;

	  return frame_unwind_got_constant (this_frame, regnum, pc);
        }

      return frame_unwind_got_optimized (this_frame, regnum);
    }

  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
}

static const struct frame_unwind avr_frame_unwind = {
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  avr_frame_this_id,
  avr_frame_prev_register,
  NULL,
  default_frame_sniffer
};

static CORE_ADDR
avr_frame_base_address (struct frame_info *this_frame, void **this_cache)
{
  struct avr_unwind_cache *info
    = avr_frame_unwind_cache (this_frame, this_cache);

  return info->base;
}

static const struct frame_base avr_frame_base = {
  &avr_frame_unwind,
  avr_frame_base_address,
  avr_frame_base_address,
  avr_frame_base_address
};

/* Assuming THIS_FRAME is a dummy, return the frame ID of that dummy
   frame.  The frame ID's base needs to match the TOS value saved by
   save_dummy_frame_tos(), and the PC match the dummy frame's breakpoint.  */

static struct frame_id
avr_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
{
  ULONGEST base;

  base = get_frame_register_unsigned (this_frame, AVR_SP_REGNUM);
  return frame_id_build (avr_make_saddr (base), get_frame_pc (this_frame));
}

/* When arguments must be pushed onto the stack, they go on in reverse
   order.  The below implements a FILO (stack) to do this.  */

struct stack_item
{
  int len;
  struct stack_item *prev;
  gdb_byte *data;
};

static struct stack_item *
push_stack_item (struct stack_item *prev, const bfd_byte *contents, int len)
{
  struct stack_item *si;
  si = XNEW (struct stack_item);
  si->data = (gdb_byte *) xmalloc (len);
  si->len = len;
  si->prev = prev;
  memcpy (si->data, contents, len);
  return si;
}

static struct stack_item *pop_stack_item (struct stack_item *si);
static struct stack_item *
pop_stack_item (struct stack_item *si)
{
  struct stack_item *dead = si;
  si = si->prev;
  xfree (dead->data);
  xfree (dead);
  return si;
}

/* Setup the function arguments for calling a function in the inferior.

   On the AVR architecture, there are 18 registers (R25 to R8) which are
   dedicated for passing function arguments.  Up to the first 18 arguments
   (depending on size) may go into these registers.  The rest go on the stack.

   All arguments are aligned to start in even-numbered registers (odd-sized
   arguments, including char, have one free register above them).  For example,
   an int in arg1 and a char in arg2 would be passed as such:

      arg1 -> r25:r24
      arg2 -> r22

   Arguments that are larger than 2 bytes will be split between two or more
   registers as available, but will NOT be split between a register and the
   stack.  Arguments that go onto the stack are pushed last arg first (this is
   similar to the d10v).  */

/* NOTE: TRoth/2003-06-17: The rest of this comment is old looks to be
   inaccurate.

   An exceptional case exists for struct arguments (and possibly other
   aggregates such as arrays) -- if the size is larger than WORDSIZE bytes but
   not a multiple of WORDSIZE bytes.  In this case the argument is never split
   between the registers and the stack, but instead is copied in its entirety
   onto the stack, AND also copied into as many registers as there is room
   for.  In other words, space in registers permitting, two copies of the same
   argument are passed in.  As far as I can tell, only the one on the stack is
   used, although that may be a function of the level of compiler
   optimization.  I suspect this is a compiler bug.  Arguments of these odd
   sizes are left-justified within the word (as opposed to arguments smaller
   than WORDSIZE bytes, which are right-justified).
 
   If the function is to return an aggregate type such as a struct, the caller
   must allocate space into which the callee will copy the return value.  In
   this case, a pointer to the return value location is passed into the callee
   in register R0, which displaces one of the other arguments passed in via
   registers R0 to R2.  */

static CORE_ADDR
avr_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     struct regcache *regcache, CORE_ADDR bp_addr,
                     int nargs, struct value **args, CORE_ADDR sp,
		     function_call_return_method return_method,
		     CORE_ADDR struct_addr)
{
  int i;
  gdb_byte buf[3];
  int call_length = gdbarch_tdep (gdbarch)->call_length;
  CORE_ADDR return_pc = avr_convert_iaddr_to_raw (bp_addr);
  int regnum = AVR_ARGN_REGNUM;
  struct stack_item *si = NULL;

  if (return_method == return_method_struct)
    {
      regcache_cooked_write_unsigned
        (regcache, regnum--, (struct_addr >> 8) & 0xff);
      regcache_cooked_write_unsigned
        (regcache, regnum--, struct_addr & 0xff);
      /* SP being post decremented, we need to reserve one byte so that the
         return address won't overwrite the result (or vice-versa).  */
      if (sp == struct_addr)
        sp--;
    }

  for (i = 0; i < nargs; i++)
    {
      int last_regnum;
      int j;
      struct value *arg = args[i];
      struct type *type = check_typedef (value_type (arg));
      const bfd_byte *contents = value_contents (arg);
      int len = TYPE_LENGTH (type);

      /* Calculate the potential last register needed.
         E.g. For length 2, registers regnum and regnum-1 (say 25 and 24)
         shall be used. So, last needed register will be regnum-1(24).  */
      last_regnum = regnum - (len + (len & 1)) + 1;

      /* If there are registers available, use them.  Once we start putting
         stuff on the stack, all subsequent args go on stack.  */
      if ((si == NULL) && (last_regnum >= AVR_LAST_ARG_REGNUM))
        {
          /* Skip a register for odd length args.  */
          if (len & 1)
            regnum--;

          /* Write MSB of argument into register and subsequent bytes in
             decreasing register numbers.  */
          for (j = 0; j < len; j++)
            regcache_cooked_write_unsigned
              (regcache, regnum--, contents[len - j - 1]);
        }
      /* No registers available, push the args onto the stack.  */
      else
        {
          /* From here on, we don't care about regnum.  */
          si = push_stack_item (si, contents, len);
        }
    }

  /* Push args onto the stack.  */
  while (si)
    {
      sp -= si->len;
      /* Add 1 to sp here to account for post decr nature of pushes.  */
      write_memory (sp + 1, si->data, si->len);
      si = pop_stack_item (si);
    }

  /* Set the return address.  For the avr, the return address is the BP_ADDR.
     Need to push the return address onto the stack noting that it needs to be
     in big-endian order on the stack.  */
  for (i = 1; i <= call_length; i++)
    {
      buf[call_length - i] = return_pc & 0xff;
      return_pc >>= 8;
    }

  sp -= call_length;
  /* Use 'sp + 1' since pushes are post decr ops.  */
  write_memory (sp + 1, buf, call_length);

  /* Finally, update the SP register.  */
  regcache_cooked_write_unsigned (regcache, AVR_SP_REGNUM,
				  avr_convert_saddr_to_raw (sp));

  /* Return SP value for the dummy frame, where the return address hasn't been
     pushed.  */
  return sp + call_length;
}

/* Unfortunately dwarf2 register for SP is 32.  */

static int
avr_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  if (reg >= 0 && reg < 32)
    return reg;
  if (reg == 32)
    return AVR_SP_REGNUM;
  return -1;
}

/* Implementation of `address_class_type_flags' gdbarch method.

   This method maps DW_AT_address_class attributes to a
   type_instance_flag_value.  */

static int
avr_address_class_type_flags (int byte_size, int dwarf2_addr_class)
{
  /* The value 1 of the DW_AT_address_class attribute corresponds to the
     __flash qualifier.  Note that this attribute is only valid with
     pointer types and therefore the flag is set to the pointer type and
     not its target type.  */
  if (dwarf2_addr_class == 1 && byte_size == 2)
    return AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH;
  return 0;
}

/* Implementation of `address_class_type_flags_to_name' gdbarch method.

   Convert a type_instance_flag_value to an address space qualifier.  */

static const char*
avr_address_class_type_flags_to_name (struct gdbarch *gdbarch, int type_flags)
{
  if (type_flags & AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH)
    return "flash";
  else
    return NULL;
}

/* Implementation of `address_class_name_to_type_flags' gdbarch method.

   Convert an address space qualifier to a type_instance_flag_value.  */

static int
avr_address_class_name_to_type_flags (struct gdbarch *gdbarch,
                                      const char* name,
                                      int *type_flags_ptr)
{
  if (strcmp (name, "flash") == 0)
    {
      *type_flags_ptr = AVR_TYPE_INSTANCE_FLAG_ADDRESS_CLASS_FLASH;
      return 1;
    }
  else
    return 0;
}

/* Initialize the gdbarch structure for the AVR's.  */

static struct gdbarch *
avr_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;
  struct gdbarch_list *best_arch;
  int call_length;

  /* Avr-6 call instructions save 3 bytes.  */
  switch (info.bfd_arch_info->mach)
    {
    case bfd_mach_avr1:
    case bfd_mach_avrxmega1:
    case bfd_mach_avr2:
    case bfd_mach_avrxmega2:
    case bfd_mach_avr3:
    case bfd_mach_avrxmega3:
    case bfd_mach_avr4:
    case bfd_mach_avrxmega4:
    case bfd_mach_avr5:
    case bfd_mach_avrxmega5:
    default:
      call_length = 2;
      break;
    case bfd_mach_avr6:
    case bfd_mach_avrxmega6:
    case bfd_mach_avrxmega7:
      call_length = 3;
      break;
    }

  /* If there is already a candidate, use it.  */
  for (best_arch = gdbarch_list_lookup_by_info (arches, &info);
       best_arch != NULL;
       best_arch = gdbarch_list_lookup_by_info (best_arch->next, &info))
    {
      if (gdbarch_tdep (best_arch->gdbarch)->call_length == call_length)
	return best_arch->gdbarch;
    }

  /* None found, create a new architecture from the information provided.  */
  tdep = XCNEW (struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);
  
  tdep->call_length = call_length;

  /* Create a type for PC.  We can't use builtin types here, as they may not
     be defined.  */
  tdep->void_type = arch_type (gdbarch, TYPE_CODE_VOID, TARGET_CHAR_BIT,
			       "void");
  tdep->func_void_type = make_function_type (tdep->void_type, NULL);
  tdep->pc_type = arch_pointer_type (gdbarch, 4 * TARGET_CHAR_BIT, NULL,
				     tdep->func_void_type);

  set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
  set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_addr_bit (gdbarch, 32);

  set_gdbarch_wchar_bit (gdbarch, 2 * TARGET_CHAR_BIT);
  set_gdbarch_wchar_signed (gdbarch, 1);

  set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
  set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);

  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
  set_gdbarch_double_format (gdbarch, floatformats_ieee_single);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_single);

  set_gdbarch_read_pc (gdbarch, avr_read_pc);
  set_gdbarch_write_pc (gdbarch, avr_write_pc);

  set_gdbarch_num_regs (gdbarch, AVR_NUM_REGS);

  set_gdbarch_sp_regnum (gdbarch, AVR_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, AVR_PC_REGNUM);

  set_gdbarch_register_name (gdbarch, avr_register_name);
  set_gdbarch_register_type (gdbarch, avr_register_type);

  set_gdbarch_num_pseudo_regs (gdbarch, AVR_NUM_PSEUDO_REGS);
  set_gdbarch_pseudo_register_read (gdbarch, avr_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, avr_pseudo_register_write);

  set_gdbarch_return_value (gdbarch, avr_return_value);

  set_gdbarch_push_dummy_call (gdbarch, avr_push_dummy_call);

  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, avr_dwarf_reg_to_regnum);

  set_gdbarch_address_to_pointer (gdbarch, avr_address_to_pointer);
  set_gdbarch_pointer_to_address (gdbarch, avr_pointer_to_address);
  set_gdbarch_integer_to_address (gdbarch, avr_integer_to_address);

  set_gdbarch_skip_prologue (gdbarch, avr_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  set_gdbarch_breakpoint_kind_from_pc (gdbarch, avr_breakpoint::kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, avr_breakpoint::bp_from_kind);

  frame_unwind_append_unwinder (gdbarch, &avr_frame_unwind);
  frame_base_set_default (gdbarch, &avr_frame_base);

  set_gdbarch_dummy_id (gdbarch, avr_dummy_id);

  set_gdbarch_unwind_pc (gdbarch, avr_unwind_pc);
  set_gdbarch_unwind_sp (gdbarch, avr_unwind_sp);

  set_gdbarch_address_class_type_flags (gdbarch, avr_address_class_type_flags);
  set_gdbarch_address_class_name_to_type_flags
    (gdbarch, avr_address_class_name_to_type_flags);
  set_gdbarch_address_class_type_flags_to_name
    (gdbarch, avr_address_class_type_flags_to_name);

  return gdbarch;
}

/* Send a query request to the avr remote target asking for values of the io
   registers.  If args parameter is not NULL, then the user has requested info
   on a specific io register [This still needs implemented and is ignored for
   now].  The query string should be one of these forms:

   "Ravr.io_reg" -> reply is "NN" number of io registers

   "Ravr.io_reg:addr,len" where addr is first register and len is number of
   registers to be read.  The reply should be "<NAME>,VV;" for each io register
   where, <NAME> is a string, and VV is the hex value of the register.

   All io registers are 8-bit.  */

static void
avr_io_reg_read_command (const char *args, int from_tty)
{
  char query[400];
  unsigned int nreg = 0;
  unsigned int val;

  /* Find out how many io registers the target has.  */
  gdb::optional<gdb::byte_vector> buf
    = target_read_alloc (current_top_target (), TARGET_OBJECT_AVR, "avr.io_reg");

  if (!buf)
    {
      fprintf_unfiltered (gdb_stderr,
			  _("ERR: info io_registers NOT supported "
			    "by current target\n"));
      return;
    }

  const char *bufstr = (const char *) buf->data ();

  if (sscanf (bufstr, "%x", &nreg) != 1)
    {
      fprintf_unfiltered (gdb_stderr,
			  _("Error fetching number of io registers\n"));
      return;
    }

  reinitialize_more_filter ();

  printf_unfiltered (_("Target has %u io registers:\n\n"), nreg);

  /* only fetch up to 8 registers at a time to keep the buffer small */
  int step = 8;

  for (int i = 0; i < nreg; i += step)
    {
      /* how many registers this round? */
      int j = step;
      if ((i+j) >= nreg)
        j = nreg - i;           /* last block is less than 8 registers */

      snprintf (query, sizeof (query) - 1, "avr.io_reg:%x,%x", i, j);
      buf = target_read_alloc (current_top_target (), TARGET_OBJECT_AVR, query);

      if (!buf)
        {
          fprintf_unfiltered (gdb_stderr,
			      _("ERR: error reading avr.io_reg:%x,%x\n"),
			      i, j);
          return;
        }

      const char *p = (const char *) buf->data ();
      for (int k = i; k < (i + j); k++)
	{
	  if (sscanf (p, "%[^,],%x;", query, &val) == 2)
	    {
	      printf_filtered ("[%02x] %-15s : %02x\n", k, query, val);
	      while ((*p != ';') && (*p != '\0'))
		p++;
	      p++;		/* skip over ';' */
	      if (*p == '\0')
		break;
	    }
	}
    }
}

void
_initialize_avr_tdep (void)
{
  register_gdbarch_init (bfd_arch_avr, avr_gdbarch_init);

  /* Add a new command to allow the user to query the avr remote target for
     the values of the io space registers in a saner way than just using
     `x/NNNb ADDR`.  */

  /* FIXME: TRoth/2002-02-18: This should probably be changed to 'info avr
     io_registers' to signify it is not available on other platforms.  */

  add_info ("io_registers", avr_io_reg_read_command,
	    _("Query remote AVR target for I/O space register values."));
}
