Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: "Jon Beniston" <jon@beniston.com>
To: "'Joel Brobecker'" <brobecker@adacore.com>
Cc: <gdb-patches@sourceware.org>
Subject: RE: [PATCH] Add support for the Lattice Mico32 (LM32) architecture
Date: Thu, 07 May 2009 23:13:00 -0000	[thread overview]
Message-ID: <AD09E295C701498880A655CB2C6D0969@bibi> (raw)
In-Reply-To: <20090507164853.GD659@adacore.com>

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

Hi Joel, 

Thanks for the second review.

> You don't need the func_end variable, here, as you can just pass NULL
instead.

Ok, I've updated that.

> That being said, I'm afraid that you won't be 
> able to commit this patch until the sim 
> counterpart is approved. This is due to the 
> two dependencies (one in configure.tgt, and one 
> in lm32-tdep.c) that you have.  Have you 
> heard from the sim maintainers?

I haven't heard anything yet.

Cheers,
Jon



ChangeLog

gdb
2009-05-08  Jon Beniston <jon@beniston.com>
        
        * MAINTAINERS: Add lm32 target.        
        * Makefile.in: Add lm32 dependencies.        
        * NEWS: Indicate lm32 is a new target.
        * configure.tgt: Add lm32 targets.
        * lm32-tdep.c: New file.

gdb/testsuite
2009-05-08  Jon Beniston <jon@beniston.com>

        * gdb.asm/asm-source.exp: Add lm32 target.



[-- Attachment #2: lm32.patch.2 --]
[-- Type: application/octet-stream, Size: 22412 bytes --]

Index: gdb/MAINTAINERS
===================================================================
RCS file: /cvs/src/src/gdb/MAINTAINERS,v
retrieving revision 1.413
diff -u -p -r1.413 MAINTAINERS
--- gdb/MAINTAINERS	27 Feb 2009 15:03:47 -0000	1.413
+++ gdb/MAINTAINERS	15 Apr 2009 17:21:19 -0000
@@ -270,6 +270,8 @@ the native maintainer when resolving ABI
 	ia64		--target=ia64-linux-gnu ,-Werror
 			(--target=ia64-elf broken)
 
+	lm32		--target=lm32-elf ,-Werror
+
 	m32c		--target=m32c-elf ,-Werror
 			Jim Blandy, jimb@codesourcery.com
 
Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1076
diff -u -p -r1.1076 Makefile.in
--- gdb/Makefile.in	30 Mar 2009 19:54:19 -0000	1.1076
+++ gdb/Makefile.in	15 Apr 2009 17:21:19 -0000
@@ -485,6 +485,7 @@ ALL_TARGET_OBS = \
 	i386-dicos-tdep.o \
 	iq2000-tdep.o \
 	linux-tdep.o \
+	lm32-tdep.o \
 	m32c-tdep.o \
 	m32r-linux-tdep.o m32r-tdep.o \
 	m68hc11-tdep.o \
@@ -1308,6 +1309,7 @@ ALLDEPFILES = \
 	libunwind-frame.c \
 	linux-fork.c \
 	linux-tdep.c \
+	lm32-tdep.c \
 	m68hc11-tdep.c \
 	m32r-tdep.c \
 	m32r-linux-nat.c m32r-linux-tdep.c \
Index: gdb/NEWS
===================================================================
RCS file: /cvs/src/src/gdb/NEWS,v
retrieving revision 1.305
diff -u -p -r1.305 NEWS
--- gdb/NEWS	31 Mar 2009 20:21:06 -0000	1.305
+++ gdb/NEWS	15 Apr 2009 17:21:21 -0000
@@ -234,6 +234,7 @@ x86_64 MinGW			x86_64-*-mingw*
 
 * New targets
 
+Lattice Mico32                  lm32-*
 x86 DICOS			i[34567]86-*-dicos*
 x86_64 DICOS		        x86_64-*-dicos*
 
Index: gdb/configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.213
diff -u -p -r1.213 configure.tgt
--- gdb/configure.tgt	16 Mar 2009 15:04:14 -0000	1.213
+++ gdb/configure.tgt	15 Apr 2009 17:21:22 -0000
@@ -231,6 +231,11 @@ iq2000-*-*)
 	gdb_sim=../sim/iq2000/libsim.a
 	;;
 
+lm32-*-*)		
+	gdb_target_obs="lm32-tdep.o" 
+	gdb_sim=../sim/lm32/libsim.a
+	;;
+
 m32c-*-*)
 	# Target: Renesas M32C family
 	gdb_target_obs="m32c-tdep.o prologue-value.o"
Index: gdb/lm32-tdep.c
===================================================================
RCS file: gdb/lm32-tdep.c
diff -N gdb/lm32-tdep.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/lm32-tdep.c	15 Apr 2009 17:21:22 -0000
@@ -0,0 +1,585 @@
+/* Target-dependent code for Lattice Mico32 processor, for GDB.
+   Contributed by Jon Beniston <jon@beniston.com>
+
+   Copyright (C) 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 "frame.h"
+#include "frame-unwind.h"
+#include "frame-base.h"
+#include "inferior.h"
+#include "dis-asm.h"
+#include "symfile.h"
+#include "remote.h"
+#include "gdbcore.h"
+#include "gdb/sim-lm32.h"
+#include "gdb/callback.h"
+#include "gdb/remote-sim.h"
+#include "sim-regno.h"
+#include "arch-utils.h"
+#include "regcache.h"
+#include "trad-frame.h"
+#include "reggroups.h"
+#include "opcodes/lm32-desc.h"
+
+#include "gdb_string.h"
+
+/* Macros to extract fields from an instruction.  */
+#define LM32_OPCODE(insn)       ((insn >> 26) & 0x3f)
+#define LM32_REG0(insn)         ((insn >> 21) & 0x1f)
+#define LM32_REG1(insn)         ((insn >> 16) & 0x1f)
+#define LM32_REG2(insn)         ((insn >> 11) & 0x1f)
+#define LM32_IMM16(insn)        ((((long)insn & 0xffff) << 16) >> 16)
+
+struct gdbarch_tdep
+{
+  /* gdbarch target dependent data here. Currently unused for LM32.  */
+};
+
+struct lm32_frame_cache
+{
+  /* The frame's base.  Used when constructing a frame ID.  */
+  CORE_ADDR base;
+  CORE_ADDR pc;
+  /* Size of frame.  */
+  int size;
+  /* Table indicating the location of each and every register.  */
+  struct trad_frame_saved_reg *saved_regs;
+};
+
+/* Add the available register groups.  */
+
+static void
+lm32_add_reggroups (struct gdbarch *gdbarch)
+{
+  reggroup_add (gdbarch, general_reggroup);
+  reggroup_add (gdbarch, all_reggroup);
+  reggroup_add (gdbarch, system_reggroup);
+}
+
+/* Return whether a given register is in a given group.  */
+
+static int
+lm32_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+			  struct reggroup *group)
+{
+  if (group == general_reggroup)
+    return ((regnum >= SIM_LM32_R0_REGNUM) && (regnum <= SIM_LM32_RA_REGNUM))
+      || (regnum == SIM_LM32_PC_REGNUM);
+  else if (group == system_reggroup)
+    return ((regnum >= SIM_LM32_EA_REGNUM) && (regnum <= SIM_LM32_BA_REGNUM))
+      || ((regnum >= SIM_LM32_EID_REGNUM) && (regnum <= SIM_LM32_IP_REGNUM));
+  return default_register_reggroup_p (gdbarch, regnum, group);
+}
+
+/* Return a name that corresponds to the given register number.  */
+
+static const char *
+lm32_register_name (struct gdbarch *gdbarch, int reg_nr)
+{
+  static char *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", "gp", "fp", "sp", "ra", "ea", "ba",
+    "PC", "EID", "EBA", "DEBA", "IE", "IM", "IP"
+  };
+
+  if ((reg_nr < 0) || (reg_nr >= ARRAY_SIZE (register_names)))
+    return NULL;
+  else
+    return register_names[reg_nr];
+}
+
+/* Return type of register.  */
+
+static struct type *
+lm32_register_type (struct gdbarch *gdbarch, int reg_nr)
+{
+  return builtin_type_int32;
+}
+
+/* Return non-zero if a register can't be written.  */
+
+static int
+lm32_cannot_store_register (struct gdbarch *gdbarch, int regno)
+{
+  return (regno == SIM_LM32_R0_REGNUM) || (regno == SIM_LM32_EID_REGNUM);
+}
+
+/* Analyze a function's prologue.  */
+
+static CORE_ADDR
+lm32_analyze_prologue (CORE_ADDR pc, CORE_ADDR limit,
+		       struct lm32_frame_cache *info)
+{
+  unsigned long instruction;
+
+  /* Keep reading though instructions, until we come across an instruction 
+     that isn't likely to be part of the prologue.  */
+  info->size = 0;
+  for (; pc < limit; pc += 4)
+    {
+
+      /* Read an instruction.  */
+      instruction = read_memory_integer (pc, 4);
+
+      if ((LM32_OPCODE (instruction) == OP_SW)
+	  && (LM32_REG0 (instruction) == SIM_LM32_SP_REGNUM))
+	{
+	  /* Any stack displaced store is likely part of the prologue.  
+	     Record that the register is being saved, and the offset 
+	     into the stack.  */
+	  info->saved_regs[LM32_REG1 (instruction)].addr =
+	    LM32_IMM16 (instruction);
+	}
+      else if ((LM32_OPCODE (instruction) == OP_ADDI)
+	       && (LM32_REG1 (instruction) == SIM_LM32_SP_REGNUM))
+	{
+	  /* An add to the SP is likely to be part of the prologue.  
+	     Adjust stack size by whatever the instruction adds to the sp.  */
+	  info->size -= LM32_IMM16 (instruction);
+	}
+      else if (			/* add fp,fp,sp */
+		((LM32_OPCODE (instruction) == OP_ADD)
+		 && (LM32_REG2 (instruction) == SIM_LM32_FP_REGNUM)
+		 && (LM32_REG0 (instruction) == SIM_LM32_FP_REGNUM)
+		 && (LM32_REG1 (instruction) == SIM_LM32_SP_REGNUM))
+		/* mv fp,imm */
+		|| ((LM32_OPCODE (instruction) == OP_ADDI)
+		    && (LM32_REG1 (instruction) == SIM_LM32_FP_REGNUM)
+		    && (LM32_REG0 (instruction) == SIM_LM32_R0_REGNUM)))
+	{
+	  /* Likely to be in the prologue for functions that require 
+	     a frame pointer.  */
+	}
+      else
+	{
+	  /* Any other instruction is likely not to be part of the prologue.  */
+	  break;
+	}
+    }
+
+  return pc;
+}
+
+/* Return PC of first non prologue instruction, for the function at the 
+   specified address.  */
+
+static CORE_ADDR
+lm32_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  CORE_ADDR func_addr, limit_pc;
+  struct symtab_and_line sal;
+  struct lm32_frame_cache frame_info;
+  struct trad_frame_saved_reg saved_regs[SIM_LM32_NUM_REGS];
+
+  /* See if we can determine the end of the prologue via the symbol table.
+     If so, then return either PC, or the PC after the prologue, whichever
+     is greater.  */
+  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
+    {
+      CORE_ADDR post_prologue_pc = skip_prologue_using_sal (func_addr);
+      if (post_prologue_pc != 0)
+	return max (pc, post_prologue_pc);
+    }
+
+  /* Can't determine prologue from the symbol table, need to examine
+     instructions.  */
+
+  /* Find an upper limit on the function prologue using the debug
+     information.  If the debug information could not be used to provide
+     that bound, then use an arbitrary large number as the upper bound.  */
+  limit_pc = skip_prologue_using_sal (pc);
+  if (limit_pc == 0)
+    limit_pc = pc + 100;	/* Magic.  */
+
+  frame_info.saved_regs = saved_regs;
+  return lm32_analyze_prologue (pc, limit_pc, &frame_info);
+}
+
+/* Create a breakpoint instruction.  */
+
+static const gdb_byte *
+lm32_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
+			 int *lenptr)
+{
+  static const gdb_byte breakpoint[4] = { OP_RAISE << 2, 0, 0, 2 };
+
+  *lenptr = sizeof (breakpoint);
+  return breakpoint;
+}
+
+/* Setup registers and stack for faking a call to a function in the 
+   inferior.  */
+
+static CORE_ADDR
+lm32_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)
+{
+  int first_arg_reg = SIM_LM32_R1_REGNUM;
+  int num_arg_regs = 8;
+  int i;
+
+  /* Set the return address.  */
+  regcache_cooked_write_signed (regcache, SIM_LM32_RA_REGNUM, bp_addr);
+
+  /* If we're returning a large struct, a pointer to the address to
+     store it at is passed as a first hidden parameter.  */
+  if (struct_return)
+    {
+      regcache_cooked_write_unsigned (regcache, first_arg_reg, struct_addr);
+      first_arg_reg++;
+      num_arg_regs--;
+      sp -= 4;
+    }
+
+  /* Setup parameters.  */
+  for (i = 0; i < nargs; i++)
+    {
+      struct value *arg = args[i];
+      struct type *arg_type = check_typedef (value_type (arg));
+      gdb_byte *contents;
+      int len;
+      int j;
+      int reg;
+      ULONGEST val;
+
+      /* Promote small integer types to int.  */
+      switch (TYPE_CODE (arg_type))
+	{
+	case TYPE_CODE_INT:
+	case TYPE_CODE_BOOL:
+	case TYPE_CODE_CHAR:
+	case TYPE_CODE_RANGE:
+	case TYPE_CODE_ENUM:
+	  if (TYPE_LENGTH (arg_type) < 4)
+	    {
+	      arg_type = builtin_type_int32;
+	      arg = value_cast (arg_type, arg);
+	    }
+	  break;
+	}
+
+      /* FIXME: Handle structures.  */
+
+      contents = (gdb_byte *) value_contents (arg);
+      len = TYPE_LENGTH (arg_type);
+      val = extract_unsigned_integer (contents, len);
+
+      /* First num_arg_regs parameters are passed by registers, 
+         and the rest are passed on the stack.  */
+      if (i < num_arg_regs)
+	regcache_cooked_write_unsigned (regcache, first_arg_reg + i, val);
+      else
+	{
+	  write_memory (sp, (void *) &val, len);
+	  sp -= 4;
+	}
+    }
+
+  /* Update stack pointer.  */
+  regcache_cooked_write_signed (regcache, SIM_LM32_SP_REGNUM, sp);
+
+  /* Return adjusted stack pointer.  */
+  return sp;
+}
+
+/* Extract return value after calling a function in the inferior.  */
+
+static void
+lm32_extract_return_value (struct type *type, struct regcache *regcache,
+			   gdb_byte *valbuf)
+{
+  int offset;
+  ULONGEST l;
+  CORE_ADDR return_buffer;
+
+  if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+      && TYPE_CODE (type) != TYPE_CODE_UNION
+      && TYPE_CODE (type) != TYPE_CODE_ARRAY && TYPE_LENGTH (type) <= 4)
+    {
+      /* Return value is returned in a single register.  */
+      regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l);
+      store_unsigned_integer (valbuf, TYPE_LENGTH (type), l);
+    }
+  else if ((TYPE_CODE (type) == TYPE_CODE_INT) && (TYPE_LENGTH (type) == 8))
+    {
+      /* 64-bit values are returned in a register pair.  */
+      regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l);
+      memcpy (valbuf, &l, 4);
+      regcache_cooked_read_unsigned (regcache, SIM_LM32_R2_REGNUM, &l);
+      memcpy (valbuf + 4, &l, 4);
+    }
+  else
+    {
+      /* Aggregate types greater than a single register are returned in memory. 
+         FIXME: Unless they are only 2 regs?.  */
+      regcache_cooked_read_unsigned (regcache, SIM_LM32_R1_REGNUM, &l);
+      return_buffer = l;
+      read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
+    }
+}
+
+/* Write into appropriate registers a function return value of type
+   TYPE, given in virtual format.  */
+static void
+lm32_store_return_value (struct type *type, struct regcache *regcache,
+			 const gdb_byte *valbuf)
+{
+  ULONGEST val;
+  int len = TYPE_LENGTH (type);
+
+  if (len <= 4)
+    {
+      val = extract_unsigned_integer (valbuf, len);
+      regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val);
+    }
+  else if (len <= 8)
+    {
+      val = extract_unsigned_integer (valbuf, 4);
+      regcache_cooked_write_unsigned (regcache, SIM_LM32_R1_REGNUM, val);
+      val = extract_unsigned_integer (valbuf + 4, len - 4);
+      regcache_cooked_write_unsigned (regcache, SIM_LM32_R2_REGNUM, val);
+    }
+  else
+    error (_("lm32_store_return_value: type length too large."));
+}
+
+/* Determine whether a functions return value is in a register or memory.  */
+static enum return_value_convention
+lm32_return_value (struct gdbarch *gdbarch, struct type *func_type,
+		   struct type *valtype, struct regcache *regcache,
+		   gdb_byte *readbuf, const gdb_byte *writebuf)
+{
+  enum type_code code = TYPE_CODE (valtype);
+
+  if (code == TYPE_CODE_STRUCT
+      || code == TYPE_CODE_UNION
+      || code == TYPE_CODE_ARRAY || TYPE_LENGTH (valtype) > 8)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+
+  if (readbuf)
+    lm32_extract_return_value (valtype, regcache, readbuf);
+  if (writebuf)
+    lm32_store_return_value (valtype, regcache, writebuf);
+
+  return RETURN_VALUE_REGISTER_CONVENTION;
+}
+
+static CORE_ADDR
+lm32_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  return frame_unwind_register_unsigned (next_frame, SIM_LM32_PC_REGNUM);
+}
+
+static CORE_ADDR
+lm32_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  return frame_unwind_register_unsigned (next_frame, SIM_LM32_SP_REGNUM);
+}
+
+static struct frame_id
+lm32_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
+{
+  CORE_ADDR sp = get_frame_register_unsigned (this_frame, SIM_LM32_SP_REGNUM);
+
+  return frame_id_build (sp, get_frame_pc (this_frame));
+}
+
+/* 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 lm32_frame_cache *
+lm32_frame_cache (struct frame_info *this_frame, void **this_prologue_cache)
+{
+  CORE_ADDR prologue_pc;
+  CORE_ADDR current_pc;
+  ULONGEST prev_sp;
+  ULONGEST this_base;
+  struct lm32_frame_cache *info;
+  int prefixed;
+  unsigned long instruction;
+  int op;
+  int offsets[32];
+  int i;
+  long immediate;
+
+  if ((*this_prologue_cache))
+    return (*this_prologue_cache);
+
+  info = FRAME_OBSTACK_ZALLOC (struct lm32_frame_cache);
+  (*this_prologue_cache) = info;
+  info->saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+  info->pc = get_frame_func (this_frame);
+  current_pc = get_frame_pc (this_frame);
+  lm32_analyze_prologue (info->pc, current_pc, info);
+
+  /* Compute the frame's base, and the previous frame's SP.  */
+  this_base = get_frame_register_unsigned (this_frame, SIM_LM32_SP_REGNUM);
+  prev_sp = this_base + info->size;
+  info->base = this_base;
+
+  /* Convert callee save offsets into addresses.  */
+  for (i = 0; i < gdbarch_num_regs (get_frame_arch (this_frame)) - 1; i++)
+    {
+      if (trad_frame_addr_p (info->saved_regs, i))
+	info->saved_regs[i].addr = this_base + info->saved_regs[i].addr;
+    }
+
+  /* The call instruction moves the caller's PC in the callee's RA register.
+     Since this is an unwind, do the reverse.  Copy the location of RA register
+     into PC (the address / regnum) so that a request for PC will be
+     converted into a request for the RA register.  */
+  info->saved_regs[SIM_LM32_PC_REGNUM] = info->saved_regs[SIM_LM32_RA_REGNUM];
+
+  /* The previous frame's SP needed to be computed.  Save the computed value. */
+  trad_frame_set_value (info->saved_regs, SIM_LM32_SP_REGNUM, prev_sp);
+
+  return info;
+}
+
+static void
+lm32_frame_this_id (struct frame_info *this_frame, void **this_cache,
+		    struct frame_id *this_id)
+{
+  struct lm32_frame_cache *cache = lm32_frame_cache (this_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 *
+lm32_frame_prev_register (struct frame_info *this_frame,
+			  void **this_prologue_cache, int regnum)
+{
+  struct lm32_frame_cache *info;
+
+  info = lm32_frame_cache (this_frame, this_prologue_cache);
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+}
+
+static const struct frame_unwind lm32_frame_unwind = {
+  NORMAL_FRAME,
+  lm32_frame_this_id,
+  lm32_frame_prev_register,
+  NULL,
+  default_frame_sniffer
+};
+
+static CORE_ADDR
+lm32_frame_base_address (struct frame_info *this_frame, void **this_cache)
+{
+  struct lm32_frame_cache *info = lm32_frame_cache (this_frame, this_cache);
+
+  return info->base;
+}
+
+static const struct frame_base lm32_frame_base = {
+  &lm32_frame_unwind,
+  lm32_frame_base_address,
+  lm32_frame_base_address,
+  lm32_frame_base_address
+};
+
+static CORE_ADDR
+lm32_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
+{
+  /* Align to the size of an instruction (so that they can safely be
+     pushed onto the stack.  */
+  return sp & ~3;
+}
+
+static struct gdbarch *
+lm32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
+{
+  struct gdbarch *gdbarch;
+  struct gdbarch_tdep *tdep;
+
+  /* If there is already a candidate, use it.  */
+  arches = gdbarch_list_lookup_by_info (arches, &info);
+  if (arches != NULL)
+    return arches->gdbarch;
+
+  /* None found, create a new architecture from the information provided.  */
+  tdep = XMALLOC (struct gdbarch_tdep);
+  gdbarch = gdbarch_alloc (&info, tdep);
+
+  /* Type sizes.  */
+  set_gdbarch_short_bit (gdbarch, 16);
+  set_gdbarch_int_bit (gdbarch, 32);
+  set_gdbarch_long_bit (gdbarch, 32);
+  set_gdbarch_long_long_bit (gdbarch, 64);
+  set_gdbarch_float_bit (gdbarch, 32);
+  set_gdbarch_double_bit (gdbarch, 64);
+  set_gdbarch_long_double_bit (gdbarch, 64);
+  set_gdbarch_ptr_bit (gdbarch, 32);
+
+  /* Register info.  */
+  set_gdbarch_num_regs (gdbarch, SIM_LM32_NUM_REGS);
+  set_gdbarch_sp_regnum (gdbarch, SIM_LM32_SP_REGNUM);
+  set_gdbarch_pc_regnum (gdbarch, SIM_LM32_PC_REGNUM);
+  set_gdbarch_register_name (gdbarch, lm32_register_name);
+  set_gdbarch_register_type (gdbarch, lm32_register_type);
+  set_gdbarch_cannot_store_register (gdbarch, lm32_cannot_store_register);
+
+  /* Frame info.  */
+  set_gdbarch_skip_prologue (gdbarch, lm32_skip_prologue);
+  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+  set_gdbarch_decr_pc_after_break (gdbarch, 0);
+  set_gdbarch_frame_args_skip (gdbarch, 0);
+
+  /* Frame unwinding.  */
+  set_gdbarch_frame_align (gdbarch, lm32_frame_align);
+  frame_base_set_default (gdbarch, &lm32_frame_base);
+  set_gdbarch_unwind_pc (gdbarch, lm32_unwind_pc);
+  set_gdbarch_unwind_sp (gdbarch, lm32_unwind_sp);
+  set_gdbarch_dummy_id (gdbarch, lm32_dummy_id);
+  frame_unwind_append_unwinder (gdbarch, &lm32_frame_unwind);
+
+  /* Breakpoints.  */
+  set_gdbarch_breakpoint_from_pc (gdbarch, lm32_breakpoint_from_pc);
+  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+
+  /* Calling functions in the inferior.  */
+  set_gdbarch_push_dummy_call (gdbarch, lm32_push_dummy_call);
+  set_gdbarch_return_value (gdbarch, lm32_return_value);
+
+  /* Instruction disassembler.  */
+  set_gdbarch_print_insn (gdbarch, print_insn_lm32);
+
+  lm32_add_reggroups (gdbarch);
+  set_gdbarch_register_reggroup_p (gdbarch, lm32_register_reggroup_p);
+
+  return gdbarch;
+}
+
+void
+_initialize_lm32_tdep (void)
+{
+  register_gdbarch_init (bfd_arch_lm32, lm32_gdbarch_init);
+}
Index: gdb/testsuite/gdb.asm/asm-source.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.asm/asm-source.exp,v
retrieving revision 1.73
diff -u -p -r1.73 asm-source.exp
--- gdb/testsuite/gdb.asm/asm-source.exp	3 Jan 2009 05:58:03 -0000	1.73
+++ gdb/testsuite/gdb.asm/asm-source.exp	15 Apr 2009 17:21:23 -0000
@@ -64,6 +64,9 @@ switch -glob -- [istarget] {
     "i\[3456\]86-*-*" {
         set asm-arch i386
     }
+    "lm32-*" {
+        set asm-arch lm32
+    }
     "m32r*-linux*" {
         set asm-arch m32r-linux
     }

  parent reply	other threads:[~2009-05-07 23:13 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-22 12:06 Jon Beniston
2009-02-07  4:14 ` Joel Brobecker
2009-04-15 18:09   ` Jon Beniston
2009-04-15 19:24     ` Eli Zaretskii
2009-05-07 16:49     ` Joel Brobecker
2009-05-07 18:35       ` Eli Zaretskii
2009-05-07 23:13       ` Jon Beniston [this message]
2009-05-08 15:32         ` Joel Brobecker
2009-05-11 16:24           ` Jon Beniston
2009-05-11 16:39             ` Joel Brobecker
2009-05-13 14:49               ` Jon Beniston
2009-05-13 15:29                 ` Joel Brobecker
2009-05-18 15:57                 ` Pierre Muller
2009-05-18 16:09                   ` Pierre Muller
  -- strict thread matches above, loose matches on Subject: below --
2008-12-16  0:52 Jon Beniston

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=AD09E295C701498880A655CB2C6D0969@bibi \
    --to=jon@beniston.com \
    --cc=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox