/* Target-dependent code for Xilinx MicroBlaze.

   Copyright 2009 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/>.  */

#include "defs.h"
#include "arch-utils.h"
#include "dis-asm.h"
#include "frame.h"
#include "trad-frame.h"
#include "symtab.h"
#include "value.h"
#include "gdbcmd.h"
#include "breakpoint.h"
#include "inferior.h"
#include "regcache.h"
#include "target.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "dwarf2-frame.h"
#include "osabi.h"

#include "gdb_assert.h"
#include "gdb_string.h"
#include "target-descriptions.h"
#include "opcodes/microblaze-opcm.h"
#include "opcodes/microblaze-dis.h"
#include "microblaze-tdep.h"

/* Instruction macros used for analyzing the prologue.  */
/* This set of instruction macros need to be changed whenever the
   prologue generated by the compiler could have more instructions or
   different type of instructions.
   This set also needs to be verified if it is complete.  */
#define IS_RETURN(op) (op == rtsd || op == rtid)
#define IS_UPDATE_SP(op, rd, ra) \
	((op == addik || op == addi) && rd == REG_SP && ra == REG_SP)
#define IS_SPILL_SP(op, rd, ra) \
	((op == swi || op == sw) && rd == REG_SP && ra == REG_SP)
#define IS_SPILL_REG(op, rd, ra) \
	((op == swi || op == sw) && rd != REG_SP && ra == REG_SP)
#define IS_ALSO_SPILL_REG(op, rd, ra, rb) \
	((op == swi || op == sw) && rd != REG_SP && ra == 0 && rb == REG_SP)
#define IS_SETUP_FP(op, ra, rb) \
	((op == add || op == addik || op == addk) && ra == REG_SP && rb == 0)
#define IS_SPILL_REG_FP(op, rd, ra, fpregnum) \
	((op == swi || op == sw) && rd != REG_SP && ra == fpregnum && ra != 0)
#define IS_SAVE_HIDDEN_PTR(op, rd, ra, rb) \
	((op == add || op == addik) && ra == MICROBLAZE_FIRST_ARGREG && rb == 0)

/* The registers of the Xilinx microblaze processor.  */

static const char *microblaze_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",
  "rpc",  "rmsr", "rear", "resr", "rfsr", "rbtr",
  "rpvr0", "rpvr1", "rpvr2", "rpvr3", "rpvr4", "rpvr5", "rpvr6",
  "rpvr7", "rpvr8", "rpvr9", "rpvr10", "rpvr11",
  "redr", "rpid", "rzpr", "rtlbx", "rtlbsx", "rtlblo", "rtlbhi"
};

#define MICROBLAZE_NUM_REGS ARRAY_SIZE (microblaze_register_names)

static int microblaze_debug_flag = 0;

void
microblaze_debug (const char *fmt, ...)
{ 
  if (microblaze_debug_flag)
    {
       va_list args;

       va_start (args, fmt);
       printf_unfiltered ("MICROBLAZE: ");
       vprintf_unfiltered (fmt, args);
       va_end (args);
    }
}

/* Return the name of register REGNUM.  */

static const char *
microblaze_register_name (struct gdbarch *gdbarch, int regnum)
{
  if (regnum >= 0 && regnum < MICROBLAZE_NUM_REGS)
    return microblaze_register_names[regnum];
  return NULL;
}

static struct type *
microblaze_register_type (struct gdbarch *gdbarch, int regnum)
{
  if (regnum == MICROBLAZE_SP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;

  if (regnum == MICROBLAZE_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;

  return builtin_type (gdbarch)->builtin_int;
}


/* Fetch the instruction at PC.  */

unsigned long
microblaze_fetch_instruction (CORE_ADDR pc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
  gdb_byte buf[4];

  /* If we can't read the instruction at PC, return zero.  */
  if (target_read_memory (pc, buf, sizeof (buf)))
    return 0;

  return extract_unsigned_integer (buf, 4, byte_order);
}


static CORE_ADDR
microblaze_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
			    CORE_ADDR funcaddr,
			    struct value **args, int nargs,
			    struct type *value_type,
			    CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
			    struct regcache *regcache)
{
  error (_("push_dummy_code not implemented"));
  return sp;
}


static CORE_ADDR
microblaze_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
			    struct regcache *regcache, CORE_ADDR bp_addr,
			    int nargs, struct value **args, CORE_ADDR sp,
			    int struct_return, CORE_ADDR struct_addr)
{
  error (_("store_arguments not implemented"));
  return sp;
}

static const gdb_byte *
microblaze_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pc, 
			       int *len)
{
  static gdb_byte break_insn[] = MICROBLAZE_BREAKPOINT;

  *len = sizeof (break_insn);
  return break_insn;
}

/* Allocate and initialize a frame cache.  */

static struct microblaze_frame_cache *
microblaze_alloc_frame_cache (void)
{
  struct microblaze_frame_cache *cache;
  int i;

  cache = FRAME_OBSTACK_ZALLOC (struct microblaze_frame_cache);

  /* Base address.  */
  cache->base = 0;
  cache->pc = 0;

  /* Frameless until proven otherwise.  */
  cache->frameless_p = 1;

  return cache;
}

/* The base of the current frame is actually in the stack pointer.
   This happens when there is no frame pointer (microblaze ABI does not
   require a frame pointer) or when we're stopped in the prologue or
   epilogue itself.  In these cases, microblaze_analyze_prologue will need
   to update fi->frame before returning or analyzing the register
   save instructions.  */
#define MICROBLAZE_MY_FRAME_IN_SP 0x1

/* The base of the current frame is in a frame pointer register.
   This register is noted in frame_extra_info->fp_regnum.

   Note that the existance of an FP might also indicate that the
   function has called alloca.  */
#define MICROBLAZE_MY_FRAME_IN_FP 0x2

/* Function prologues on the Xilinx microblaze processors consist of:

   - adjustments to the stack pointer (r1) (addi r1, r1, imm)
   - making a copy of r1 into another register (a "frame" pointer)
     (add r?, r1, r0)
   - store word/multiples that use r1 or the frame pointer as the
     base address (swi r?, r1, imm OR swi r?, fp, imm)

   Note that microblaze really doesn't have a real frame pointer.
   Instead, the compiler may copy the SP into a register (usually
   r19) to act as an arg pointer.  For our target-dependent purposes,
   the frame info's "frame" member will be the beginning of the
   frame.  The SP could, in fact, point below this.

   The prologue ends when an instruction fails to meet either of
   these criteria.  */

/* Analyze the prologue to determine where registers are saved,
   the end of the prologue, etc.  Return the address of the first line
   of "real" code (i.e., the end of the prologue). */

static CORE_ADDR
microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc, 
			     CORE_ADDR current_pc,
			     struct microblaze_frame_cache *cache)
{
  char *name;
  CORE_ADDR func_addr, func_end, addr, stop, prologue_end_addr = 0;
  unsigned long insn;
  int rn, rd, ra, rb, imm;
  enum microblaze_instr op;
  int flags = 0;
  int save_hidden_pointer_found = 0;
  int non_stack_instruction_found = 0;

  /* Find the start of this function. */
  find_pc_partial_function (pc, &name, &func_addr, &func_end);
  if (func_addr < pc)
    pc = func_addr;

  if (current_pc < pc)
    return current_pc;

   /* Initialize info about frame.  */
   cache->framesize = 0;
   cache->fp_regnum = MICROBLAZE_SP_REGNUM;
   cache->frameless_p = 1;

  /* Start decoding the prologue.  We start by checking two special cases:

     1. We're about to return
     2. We're at the first insn of the prologue.

     If we're about to return, our frame has already been deallocated.
     If we are stopped at the first instruction of a prologue,
     then our frame has not yet been set up. */

  /* Get the first insn from memory.  */

  insn = microblaze_fetch_instruction (pc);
  op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);

  if (IS_RETURN(op))
    return pc;

  /* Start at beginning of function and analyze until we get to the
     current pc, or the end of the function, whichever is first.  */
  stop = (current_pc < func_end ? current_pc : func_end);

  microblaze_debug ("Scanning prologue: name=%s, func_addr=%s, stop=%s\n", 
		    name, paddress (gdbarch, func_addr), 
		    paddress (gdbarch, stop));

  for (addr = func_addr; addr < stop; addr += INST_WORD_SIZE)
    {
      insn = microblaze_fetch_instruction (addr);
      op = microblaze_decode_insn (insn, &rd, &ra, &rb, &imm);
      microblaze_debug ("%s %08lx\n", paddress (gdbarch, pc), insn);

      /* This code is very sensitive to what functions are present in the
	 prologue.  It assumes that the (addi, addik, swi, sw) can be the 
	 only instructions in the prologue.  */
      if (IS_UPDATE_SP(op, rd, ra))
	{
	  microblaze_debug ("got addi r1,r1,%d; contnuing\n", imm);
	  if (cache->framesize)
	    break;	/* break if framesize already computed.  */
	  cache->framesize = -imm; /* stack grows towards low memory.  */
	  cache->frameless_p = 0; /* Frame found.  */
	  save_hidden_pointer_found = 0;
	  non_stack_instruction_found = 0;
	  continue;
	}
      else if (IS_SPILL_SP(op, rd, ra))
	{
	  /* Spill stack pointer.  */
	  cache->register_offsets[rd] = imm; /* SP spilled before updating.  */

	  microblaze_debug ("swi r1 r1 %d, continuing\n", imm);
	  save_hidden_pointer_found = 0;
	  if (!cache->framesize)
	    non_stack_instruction_found = 0;
	  continue;
	}
      else if (IS_SPILL_REG(op, rd, ra))
	{
	  /* Spill register.  */
	  cache->register_offsets[rd] = imm - cache->framesize;

	  microblaze_debug ("swi %d r1 %d, continuing\n", rd, imm);
	  save_hidden_pointer_found = 0;
	  if (!cache->framesize)
	    non_stack_instruction_found = 0;
	  continue;
	}
      else if (IS_ALSO_SPILL_REG(op, rd, ra, rb))
	{
	  /* Spill register.  */
	  cache->register_offsets[rd] = 0 - cache->framesize;

	  microblaze_debug ("sw %d r0 r1, continuing\n", rd);
	  save_hidden_pointer_found = 0;
	  if (!cache->framesize)
	    non_stack_instruction_found = 0;
	  continue;
	}
      else if (IS_SETUP_FP(op, ra, rb))
	{
	  /* We have a frame pointer.  Note the register which is 
             acting as the frame pointer. */
	  flags |= MICROBLAZE_MY_FRAME_IN_FP;
	  flags &= ~MICROBLAZE_MY_FRAME_IN_SP;
	  cache->fp_regnum = rd;
	  microblaze_debug ("Found a frame pointer: r%d\n", cache->fp_regnum);
	  save_hidden_pointer_found = 0;
	  if (!cache->framesize)
	    non_stack_instruction_found = 0;
	  continue;
	}
      else if (IS_SPILL_REG_FP(op, rd, ra, cache->fp_regnum))
	{
	  /* reg spilled after updating.  */
	  cache->register_offsets[rd] = imm - cache->framesize;

	  microblaze_debug ("swi %d %d %d, continuing\n", rd, ra, imm);
	  save_hidden_pointer_found = 0;
	  if (!cache->framesize)
	    non_stack_instruction_found = 0;
	  continue;
	}
      else if (IS_SAVE_HIDDEN_PTR(op, rd, ra, rb))
	{
	  /* If the first argument is a hidden pointer to the area where the
	     return structure is to be saved, then it is saved as part of the
	     prologue.  */

	  microblaze_debug ("add %d %d %d, continuing\n", rd, ra, rb);
	  save_hidden_pointer_found = 1;
	  if (!cache->framesize)
	    non_stack_instruction_found = 0;
	  continue;
	}

      /* As a result of the modification in the next step where we continue
	 to analyze the prologue till we reach a control flow instruction,
	 we need another variable to store when exactly a non-stack
	 instruction was encountered, which is the current definition
	 of a prologue.  */
      if (!non_stack_instruction_found)
	prologue_end_addr = addr;
      non_stack_instruction_found = 1;

      /* When optimizations are enabled, it is not guaranteed that prologue
	 instructions are not mixed in with other instructions from the
	 program. Some programs show this behavior at -O2. This can be
	 avoided by adding -fno-schedule-insns2 switch as of now (edk 8.1)
	 In such cases, we scan the function until we see the first control
	 instruction.  */

      {
	unsigned op = (unsigned)insn >> 26;

	/* continue if not control flow (branch, return).  */
	if (op != 0x26 && op != 0x27 && op != 0x2d && op != 0x2e && op != 0x2f)
	  continue;
	else if (op == 0x2c)
	  continue;    /* continue if imm.  */
      }

      /* This is not a prologue insn, so stop here. */
      microblaze_debug ("insn is not a prologue insn -- ending scan\n");
      break;
    }

  microblaze_debug ("done analyzing prologue\n");
  microblaze_debug ("prologue end = 0x%x\n", (int) addr);

  /* If the last instruction was an add rd, r5, r0 then don't count it as
     part of the prologue.  */
  if (save_hidden_pointer_found)
    prologue_end_addr -= INST_WORD_SIZE;

  return prologue_end_addr;
}

static CORE_ADDR
microblaze_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
{
  gdb_byte buf[4];
  CORE_ADDR pc;

  frame_unwind_register (next_frame, MICROBLAZE_PC_REGNUM, buf);
  pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
  /* For sentinel frame, return address is actual PC.  For other frames,
     return address is pc+8.  This is a workaround because gcc does not
     generate correct return address in CIE.  */
  if (frame_relative_level (next_frame) >= 0)
    pc += 8;
  return pc;
}

/* Return PC of first real instruction of the function starting at
   START_PC.  */

CORE_ADDR
microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
  struct symtab_and_line sal;
  CORE_ADDR func_start, func_end, ostart_pc;
  struct microblaze_frame_cache cache;

  /* This is the preferred method, find the end of the prologue by
     using the debugging information.  Debugging info does not always
     give the right answer since parameters are stored on stack after this.
     Always analyze the prologue.  */
  if (find_pc_partial_function (start_pc, NULL, &func_start, &func_end))
    {
      sal = find_pc_line (func_start, 0);

      if (sal.end < func_end
	  && start_pc <= sal.end)
	start_pc = sal.end;
    }

  ostart_pc = microblaze_analyze_prologue (gdbarch, func_start, 0xffffffffUL, 
					   &cache);

  if (ostart_pc > start_pc)
    return ostart_pc;
  return start_pc;
}

/* Normal frames.  */

struct microblaze_frame_cache *
microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
{
  struct microblaze_frame_cache *cache;
  struct gdbarch *gdbarch = get_frame_arch (next_frame);
  CORE_ADDR func, pc, fp;
  int rn;

  if (*this_cache)
    return *this_cache;

  cache = microblaze_alloc_frame_cache ();
  *this_cache = cache;
  cache->saved_regs = trad_frame_alloc_saved_regs (next_frame);

  /* Clear offsets to saved regs in frame.  */
  for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
    cache->register_offsets[rn] = -1;

  func = get_frame_func (next_frame);

  cache->pc = get_frame_address_in_block (next_frame);

  return cache;
}

static void
microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache,
		       struct frame_id *this_id)
{
  struct microblaze_frame_cache *cache =
    microblaze_frame_cache (next_frame, this_cache);

  /* This marks the outermost frame.  */
  if (cache->base == 0)
    return;

  (*this_id) = frame_id_build (cache->base, cache->pc);
}

static struct value *
microblaze_frame_prev_register (struct frame_info *this_frame,
				 void **this_cache, int regnum)
{
  struct microblaze_frame_cache *cache =
    microblaze_frame_cache (this_frame, this_cache);

  if (cache->frameless_p)
    {
      if (regnum == MICROBLAZE_PC_REGNUM)
        regnum = 15;
      if (regnum == MICROBLAZE_SP_REGNUM)
        regnum = 1;
      return trad_frame_get_prev_register (this_frame, cache->saved_regs, regnum);
    }
  else
    return trad_frame_get_prev_register (this_frame, cache->saved_regs,
					 regnum);

}

static const struct frame_unwind microblaze_frame_unwind =
{
  NORMAL_FRAME,
  microblaze_frame_this_id,
  microblaze_frame_prev_register,
  NULL,
  default_frame_sniffer
};

static CORE_ADDR
microblaze_frame_base_address (struct frame_info *next_frame, void **this_cache)
{
  struct microblaze_frame_cache *cache =
    microblaze_frame_cache (next_frame, this_cache);

  return cache->base;
}

static const struct frame_base microblaze_frame_base =
{
  &microblaze_frame_unwind,
  microblaze_frame_base_address,
  microblaze_frame_base_address,
  microblaze_frame_base_address
};

/* Extract from an array REGBUF containing the (raw) register state, a
   function return value of TYPE, and copy that into VALBUF.  */
static void
microblaze_extract_return_value (struct type *type, struct regcache *regcache,
				 gdb_byte *valbuf)
{
  gdb_byte buf[8];

  /* Copy the return value (starting) in RETVAL_REGNUM to VALBUF.  */
  switch (TYPE_LENGTH (type))
    {
      case 1:	/* return last byte in the register.  */
	regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf);
	memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 1, 1);
	return;
      case 2:	/* return last 2 bytes in register.  */
	memcpy(valbuf, buf + MICROBLAZE_REGISTER_SIZE - 2, 2);
	return;
      case 4:	/* for sizes 4 or 8, copy the required length.  */
      case 8:
	regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM, buf);
	regcache_cooked_read (regcache, MICROBLAZE_RETVAL_REGNUM+1, buf+4);
	memcpy (valbuf, buf, TYPE_LENGTH (type));
	return;
      default:
	internal_error (__FILE__, __LINE__, 
			_("Unsupported return value size requested"));
    }
}

/* Store the return value in VALBUF (of type TYPE) where the caller
   expects to see it.

   Integers up to four bytes are stored in r3.

   Longs are stored in r3 (most significant word) and r4 (least
   significant word).

   Small structures are always returned on stack.
*/

static void
microblaze_store_return_value (struct type *type, struct regcache *regcache,
			       const gdb_byte *valbuf)
{
  int len = TYPE_LENGTH (type);
  gdb_byte buf[8];

  memset (buf, 0, sizeof(buf));

  /* Integral and pointer return values.  */

  if (len > 4)
    {
       gdb_assert (len == 8);
       memcpy (buf, valbuf, 8);
       regcache_cooked_write (regcache, MICROBLAZE_RETVAL_REGNUM+1, buf + 4);
    }
  else
    /* ??? Do we need to do any sign-extension here?  */
    memcpy (buf + 4 - len, valbuf, len);

  regcache_cooked_write (regcache, MICROBLAZE_RETVAL_REGNUM, buf);
}

static enum return_value_convention
microblaze_return_value (struct gdbarch *gdbarch, struct type *func_type,
			 struct type *type, struct regcache *regcache,
			 gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (readbuf)
    microblaze_extract_return_value (type, regcache, readbuf);
  if (writebuf)
    microblaze_store_return_value (type, regcache, writebuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}

static int
microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
{
  return (TYPE_LENGTH (type) == 16);
}

static void
microblaze_write_pc (struct regcache *regcache, CORE_ADDR pc)
{
  regcache_cooked_write_unsigned (regcache, MICROBLAZE_PC_REGNUM, pc);
}

static int dwarf2_to_reg_map[78] =
{ 0  /* r0  */,   1  /* r1  */,   2  /* r2  */,   3  /* r3  */,  /*  0- 3 */
  4  /* r4  */,   5  /* r5  */,   6  /* r6  */,   7  /* r7  */,  /*  4- 7 */
  8  /* r8  */,   9  /* r9  */,  10  /* r10 */,  11  /* r11 */,  /*  8-11 */
  12 /* r12 */,  13  /* r13 */,  14  /* r14 */,  15  /* r15 */,  /* 12-15 */
  16 /* r16 */,  17  /* r17 */,  18  /* r18 */,  19  /* r19 */,  /* 16-19 */
  20 /* r20 */,  21  /* r21 */,  22  /* r22 */,  23  /* r23 */,  /* 20-23 */
  24 /* r24 */,  25  /* r25 */,  26  /* r26 */,  27  /* r27 */,  /* 24-25 */
  28 /* r28 */,  29  /* r29 */,  30  /* r30 */,  31  /* r31 */,  /* 28-31 */
  -1 /* $f0 */,  -1  /* $f1 */,  -1  /* $f2 */,  -1  /* $f3 */,  /* 32-35 */
  -1 /* $f4 */,  -1  /* $f5 */,  -1  /* $f6 */,  -1  /* $f7 */,  /* 36-39 */
  -1 /* $f8 */,  -1  /* $f9 */,  -1  /* $f10 */, -1  /* $f11 */, /* 40-43 */
  -1 /* $f12 */, -1  /* $f13 */, -1  /* $f14 */, -1  /* $f15 */, /* 44-47 */
  -1 /* $f16 */, -1  /* $f17 */, -1  /* $f18 */, -1  /* $f19 */, /* 48-51 */
  -1 /* $f20 */, -1  /* $f21 */, -1  /* $f22 */, -1  /* $f23 */, /* 52-55 */
  -1 /* $f24 */, -1  /* $f25 */, -1  /* $f26 */, -1  /* $f27 */, /* 56-59 */
  -1 /* $f28 */, -1  /* $f29 */, -1  /* $f30 */, -1  /* $f31 */, /* 60-63 */
  -1 /* hi   */, -1  /* lo   */, -1  /* accum*/, 33  /* rmsr */, /* 64-67 */
  -1 /* $fcc1*/, -1  /* $fcc2*/, -1  /* $fcc3*/, -1  /* $fcc4*/, /* 68-71 */
  -1 /* $fcc5*/, -1  /* $fcc6*/, -1  /* $fcc7*/, -1  /* $ap  */, /* 72-75 */
  -1 /* $rap */, -1  /* $frp */					 /* 76-77 */
};

static int
microblaze_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  gdb_assert (reg < sizeof (dwarf2_to_reg_map));
  return dwarf2_to_reg_map[reg];
}

static struct gdbarch *
microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch_tdep *tdep;
  struct gdbarch *gdbarch;

  /* If there is already a candidate, use it.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  /* Allocate space for the new architecture.  */
  tdep = XMALLOC (struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);

  set_gdbarch_long_double_bit (gdbarch, 128);

  set_gdbarch_num_regs (gdbarch, MICROBLAZE_NUM_REGS);
  set_gdbarch_register_name (gdbarch, microblaze_register_name);
  set_gdbarch_register_type (gdbarch, microblaze_register_type);

  /* Register numbers of various important registers.  */
  set_gdbarch_sp_regnum (gdbarch, MICROBLAZE_SP_REGNUM); 
  set_gdbarch_pc_regnum (gdbarch, MICROBLAZE_PC_REGNUM); 

  /* Map Dwarf2 registers to GDB registers.  */
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, microblaze_dwarf2_reg_to_regnum);

  /* Call dummy code.  */
  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
  set_gdbarch_push_dummy_code (gdbarch, microblaze_push_dummy_code);
  set_gdbarch_push_dummy_call (gdbarch, microblaze_push_dummy_call);

  set_gdbarch_return_value (gdbarch, microblaze_return_value);
  set_gdbarch_stabs_argument_has_addr
    (gdbarch, microblaze_stabs_argument_has_addr);

  set_gdbarch_skip_prologue (gdbarch, microblaze_skip_prologue);

  /* Stack grows downward.  */
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  set_gdbarch_breakpoint_from_pc (gdbarch, microblaze_breakpoint_from_pc);

  set_gdbarch_frame_args_skip (gdbarch, 8);

  set_gdbarch_print_insn (gdbarch, print_insn_microblaze);

  set_gdbarch_write_pc (gdbarch, microblaze_write_pc);

  set_gdbarch_unwind_pc (gdbarch, microblaze_unwind_pc);

  frame_base_set_default (gdbarch, &microblaze_frame_base);

  /* Hook in ABI-specific overrides, if they have been registered.  */
  gdbarch_init_osabi (info, gdbarch);

  /* Unwind the frame. */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &microblaze_frame_unwind);
  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);

  return gdbarch;
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
void _initialize_microblaze_tdep (void);

void
_initialize_microblaze_tdep (void)
{
  register_gdbarch_init (bfd_arch_microblaze, microblaze_gdbarch_init);

  /* Debug this files internals.  */
  add_setshow_zinteger_cmd ("microblaze", class_maintenance,
			    &microblaze_debug_flag, _("\
Set microblaze debugging."), _("\
Show microblaze debugging."), _("\
When non-zero, microblaze specific debugging is enabled."),
			    NULL,
			    NULL, 
			    &setdebuglist, &showdebuglist);

}
