X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmn10300-tdep.c;h=c62052fd50a05c96ab1edab17897698d35c9c380;hb=58dadb1bdf0ace689fd17cab2676338fe32b44c0;hp=cdb1cdc216bdaeee073134812f1da52f3d3bbd55;hpb=b80b83f36a33c7baeeb2ba812e6a85e14ff434cc;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index cdb1cdc216..c62052fd50 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -1,595 +1,1477 @@ -/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger. - - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 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 2 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, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* MVS Notes: - - To get from 1.1 to 1.2, add: - use_struct_convention - store_return_value - extract_return_value - extract_struct_value_address - - Make sure to use regcache. */ - -/* MVS Notes: - - Apparently cannot run without a stub placeholder for unwind_dummy_id. -*/ - -/* MVS Notes: - - To get from 1.2 to 1.3, add: - read_pc, write_pc - frame_unwind_init - struct mn10300_unwind_cache - unwind_pc - unwind_dummy_id - frame_this_id - frame_prev_register - frame_sniffer (struct mn10300_frame_unwind) -*/ - -#include "defs.h" -#include "arch-utils.h" -#include "dis-asm.h" -#include "gdbtypes.h" -#include "regcache.h" -#include "gdb_string.h" -#include "gdb_assert.h" -#include "gdbcore.h" /* for write_memory_unsigned_integer */ -#include "value.h" -#include "gdbtypes.h" -#include "frame.h" -#include "frame-unwind.h" -#include "frame-base.h" -#include "trad-frame.h" -#include "symtab.h" -#include "dwarf2-frame.h" -#include "regcache.h" - -#include "mn10300-tdep.h" - - -/* Compute the alignment required by a type. */ - -static int -mn10300_type_align (struct type *type) -{ - int i, align = 1; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_INT: - case TYPE_CODE_ENUM: - case TYPE_CODE_SET: - case TYPE_CODE_RANGE: - case TYPE_CODE_CHAR: - case TYPE_CODE_BOOL: - case TYPE_CODE_FLT: - case TYPE_CODE_PTR: - case TYPE_CODE_REF: - return TYPE_LENGTH (type); - - case TYPE_CODE_COMPLEX: - return TYPE_LENGTH (type) / 2; - - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - for (i = 0; i < TYPE_NFIELDS (type); i++) - { - int falign = mn10300_type_align (TYPE_FIELD_TYPE (type, i)); - while (align < falign) - align <<= 1; - } - return align; - - case TYPE_CODE_ARRAY: - /* HACK! Structures containing arrays, even small ones, are not - elligible for returning in registers. */ - return 256; - - case TYPE_CODE_TYPEDEF: - return mn10300_type_align (check_typedef (type)); - - default: - internal_error (__FILE__, __LINE__, _("bad switch")); - } -} - -/* MVS note this is deprecated. */ -/* Should call_function allocate stack space for a struct return? */ -/* gcc_p unused */ -static int -mn10300_use_struct_convention (int gcc_p, struct type *type) -{ - /* Structures bigger than a pair of words can't be returned in - registers. */ - if (TYPE_LENGTH (type) > 8) - return 1; - - switch (TYPE_CODE (type)) - { - case TYPE_CODE_STRUCT: - case TYPE_CODE_UNION: - /* Structures with a single field are handled as the field - itself. */ - if (TYPE_NFIELDS (type) == 1) - return mn10300_use_struct_convention (gcc_p, - TYPE_FIELD_TYPE (type, 0)); - - /* Structures with word or double-word size are passed in memory, as - long as they require at least word alignment. */ - if (mn10300_type_align (type) >= 4) - return 0; - - return 1; - - /* Arrays are addressable, so they're never returned in - registers. This condition can only hold when the array is - the only field of a struct or union. */ - case TYPE_CODE_ARRAY: - return 1; - - case TYPE_CODE_TYPEDEF: - return mn10300_use_struct_convention (gcc_p, check_typedef (type)); - - default: - return 0; - } -} - -/* MVS note this is deprecated. */ -static void -mn10300_store_return_value (struct type *type, - struct regcache *regcache, const void *valbuf) -{ - struct gdbarch *gdbarch = get_regcache_arch (regcache); - int len = TYPE_LENGTH (type); - int reg, regsz; - - if (TYPE_CODE (type) == TYPE_CODE_PTR) - reg = 4; - else - reg = 0; - - regsz = register_size (gdbarch, reg); - - if (len <= regsz) - regcache_raw_write_part (regcache, reg, 0, len, valbuf); - else if (len <= 2 * regsz) - { - regcache_raw_write (regcache, reg, valbuf); - gdb_assert (regsz == register_size (gdbarch, reg + 1)); - regcache_raw_write_part (regcache, reg+1, 0, - len - regsz, (char *) valbuf + regsz); - } - else - internal_error (__FILE__, __LINE__, - _("Cannot store return value %d bytes long."), len); -} - -/* MVS note deprecated. */ -static void -mn10300_extract_return_value (struct type *type, - struct regcache *regcache, void *valbuf) -{ - struct gdbarch *gdbarch = get_regcache_arch (regcache); - char buf[MAX_REGISTER_SIZE]; - int len = TYPE_LENGTH (type); - int reg, regsz; - - if (TYPE_CODE (type) == TYPE_CODE_PTR) - reg = 4; - else - reg = 0; - - regsz = register_size (gdbarch, reg); - if (len <= regsz) - { - regcache_raw_read (regcache, reg, buf); - memcpy (valbuf, buf, len); - } - else if (len <= 2 * regsz) - { - regcache_raw_read (regcache, reg, buf); - memcpy (valbuf, buf, regsz); - gdb_assert (regsz == register_size (gdbarch, reg + 1)); - regcache_raw_read (regcache, reg + 1, buf); - memcpy ((char *) valbuf + regsz, buf, len - regsz); - } - else - internal_error (__FILE__, __LINE__, - _("Cannot extract return value %d bytes long."), len); -} - -static char * -register_name (int reg, char **regs, long sizeof_regs) -{ - if (reg < 0 || reg >= sizeof_regs / sizeof (regs[0])) - return NULL; - else - return regs[reg]; -} - -static const char * -mn10300_generic_register_name (int reg) -{ - static char *regs[] = - { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", - "sp", "pc", "mdr", "psw", "lir", "lar", "", "", - "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "fp" - }; - return register_name (reg, regs, sizeof regs); -} - - -static const char * -am33_register_name (int reg) -{ - static char *regs[] = - { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", - "sp", "pc", "mdr", "psw", "lir", "lar", "", - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "ssp", "msp", "usp", "mcrh", "mcrl", "mcvf", "", "", "" - }; - return register_name (reg, regs, sizeof regs); -} - - -static struct type * -mn10300_register_type (struct gdbarch *gdbarch, int reg) -{ - return builtin_type_int; -} - -static CORE_ADDR -mn10300_read_pc (ptid_t ptid) -{ - return read_register_pid (E_PC_REGNUM, ptid); -} - -static void -mn10300_write_pc (CORE_ADDR val, ptid_t ptid) -{ - return write_register_pid (E_PC_REGNUM, val, ptid); -} - -/* The breakpoint instruction must be the same size as the smallest - instruction in the instruction set. - - The Matsushita mn10x00 processors have single byte instructions - so we need a single byte breakpoint. Matsushita hasn't defined - one, so we defined it ourselves. */ - -const static unsigned char * -mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) -{ - static char breakpoint[] = {0xff}; - *bp_size = 1; - return breakpoint; -} - -/* Function: skip_prologue - Return the address of the first inst past the prologue of the function. */ - -static CORE_ADDR -mn10300_skip_prologue (CORE_ADDR pc) -{ - /* FIXME: not implemented. */ - /* First approximation, try simply using skip_prologue_using_sal. */ - return skip_prologue_using_sal (pc); -} - -/* Simple frame_unwind_cache. - This finds the "extra info" for the frame. */ -struct trad_frame_cache * -mn10300_frame_unwind_cache (struct frame_info *next_frame, - void **this_prologue_cache) -{ - struct trad_frame_cache *cache; - CORE_ADDR pc; - - if (*this_prologue_cache) - return (*this_prologue_cache); - - cache = trad_frame_cache_zalloc (next_frame); - pc = gdbarch_unwind_pc (current_gdbarch, next_frame); - mn10300_analyze_prologue (next_frame, (void **) &cache, pc); - - trad_frame_set_id (cache, - frame_id_build (trad_frame_get_this_base (cache), pc)); - - (*this_prologue_cache) = cache; - return cache; -} - -/* Here is a dummy implementation. */ -static struct frame_id -mn10300_unwind_dummy_id (struct gdbarch *gdbarch, - struct frame_info *next_frame) -{ - return frame_id_build (frame_sp_unwind (next_frame), - frame_pc_unwind (next_frame)); -} - -/* Trad frame implementation. */ -static void -mn10300_frame_this_id (struct frame_info *next_frame, - void **this_prologue_cache, - struct frame_id *this_id) -{ - struct trad_frame_cache *cache = - mn10300_frame_unwind_cache (next_frame, this_prologue_cache); - - trad_frame_get_id (cache, this_id); -} - -static void -mn10300_frame_prev_register (struct frame_info *next_frame, - void **this_prologue_cache, - int regnum, int *optimizedp, - enum lval_type *lvalp, CORE_ADDR *addrp, - int *realnump, void *bufferp) -{ - struct trad_frame_cache *cache = - mn10300_frame_unwind_cache (next_frame, this_prologue_cache); - - trad_frame_get_register (cache, next_frame, regnum, optimizedp, - lvalp, addrp, realnump, bufferp); - /* Or... - trad_frame_get_prev_register (next_frame, cache->prev_regs, regnum, - optimizedp, lvalp, addrp, realnump, bufferp); - */ -} - -static const struct frame_unwind mn10300_frame_unwind = { - NORMAL_FRAME, - mn10300_frame_this_id, - mn10300_frame_prev_register -}; - -static CORE_ADDR -mn10300_frame_base_address (struct frame_info *next_frame, - void **this_prologue_cache) -{ - struct trad_frame_cache *cache = - mn10300_frame_unwind_cache (next_frame, this_prologue_cache); - - return trad_frame_get_this_base (cache); -} - -static const struct frame_unwind * -mn10300_frame_sniffer (struct frame_info *next_frame) -{ - return &mn10300_frame_unwind; -} - -static const struct frame_base mn10300_frame_base = { - &mn10300_frame_unwind, - mn10300_frame_base_address, - mn10300_frame_base_address, - mn10300_frame_base_address -}; - -static CORE_ADDR -mn10300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) -{ - ULONGEST pc; - - frame_unwind_unsigned_register (next_frame, E_PC_REGNUM, &pc); - return pc; -} - -static CORE_ADDR -mn10300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) -{ - ULONGEST sp; - - frame_unwind_unsigned_register (next_frame, E_SP_REGNUM, &sp); - return sp; -} - -static void -mn10300_frame_unwind_init (struct gdbarch *gdbarch) -{ - frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer); - frame_unwind_append_sniffer (gdbarch, mn10300_frame_sniffer); - frame_base_set_default (gdbarch, &mn10300_frame_base); - set_gdbarch_unwind_dummy_id (gdbarch, mn10300_unwind_dummy_id); - set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc); - set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp); -} - -/* Function: push_dummy_call - * - * Set up machine state for a target call, including - * function arguments, stack, return address, etc. - * - */ - -static CORE_ADDR -mn10300_push_dummy_call (struct gdbarch *gdbarch, - struct value *target_func, - struct regcache *regcache, - CORE_ADDR bp_addr, - int nargs, struct value **args, - CORE_ADDR sp, - int struct_return, - CORE_ADDR struct_addr) -{ - const int push_size = register_size (gdbarch, E_PC_REGNUM); - int regs_used = struct_return ? 1 : 0; - int len, arg_len; - int stack_offset = 0; - int argnum; - char *val; - - /* FIXME temp, don't handle struct args at all. */ - if (struct_return) - error ("Target doesn't handle struct return"); - - /* This should be a nop, but align the stack just in case something - went wrong. Stacks are four byte aligned on the mn10300. */ - sp &= ~3; - - /* Now make space on the stack for the args. - - XXX This doesn't appear to handle pass-by-invisible reference - arguments. */ - for (len = 0, argnum = 0; argnum < nargs; argnum++) - { - arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3; - if (TYPE_CODE (value_type (args[argnum])) == TYPE_CODE_STRUCT) - error ("Target does not handle struct args"); - while (regs_used < 2 && arg_len > 0) - { - regs_used++; - arg_len -= push_size; - } - len += arg_len; - } - - /* Allocate stack space. */ - sp -= len; - - regs_used = struct_return ? 1 : 0; - /* Push all arguments onto the stack. */ - for (argnum = 0; argnum < nargs; argnum++) - { - /* FIXME what about structs? */ - arg_len = TYPE_LENGTH (value_type (*args)); - val = (char *) value_contents (*args); - - while (regs_used < 2 && arg_len > 0) - { - write_register (regs_used, extract_unsigned_integer (val, - push_size)); - val += push_size; - arg_len -= push_size; - regs_used++; - } - - while (arg_len > 0) - { - write_memory (sp + stack_offset, val, push_size); - arg_len -= push_size; - val += push_size; - stack_offset += push_size; - } - - args++; - } - - /* Make space for the flushback area. */ - sp -= 8; - - /* Push the return address that contains the magic breakpoint. */ - sp -= 4; - write_memory_unsigned_integer (sp, push_size, bp_addr); - /* Update $sp. */ - regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp); - return sp; -} - - -static struct gdbarch * -mn10300_gdbarch_init (struct gdbarch_info info, - struct gdbarch_list *arches) -{ - struct gdbarch *gdbarch; - struct gdbarch_tdep *tdep; - - arches = gdbarch_list_lookup_by_info (arches, &info); - if (arches != NULL) - return arches->gdbarch; - - tdep = xmalloc (sizeof (struct gdbarch_tdep)); - gdbarch = gdbarch_alloc (&info, tdep); - - switch (info.bfd_arch_info->mach) - { - case 0: - case bfd_mach_mn10300: - set_gdbarch_register_name (gdbarch, mn10300_generic_register_name); - tdep->am33_mode = 0; - break; - case bfd_mach_am33: - set_gdbarch_register_name (gdbarch, am33_register_name); - tdep->am33_mode = 1; - break; - default: - internal_error (__FILE__, __LINE__, - _("mn10300_gdbarch_init: Unknown mn10300 variant")); - break; - } - - /* Registers. */ - set_gdbarch_num_regs (gdbarch, E_NUM_REGS); - set_gdbarch_register_type (gdbarch, mn10300_register_type); - set_gdbarch_skip_prologue (gdbarch, mn10300_skip_prologue); - set_gdbarch_read_pc (gdbarch, mn10300_read_pc); - set_gdbarch_write_pc (gdbarch, mn10300_write_pc); - set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM); - set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM); - - /* Stack unwinding. */ - set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - /* Breakpoints. */ - set_gdbarch_breakpoint_from_pc (gdbarch, mn10300_breakpoint_from_pc); - /* decr_pc_after_break? */ - /* Disassembly. */ - set_gdbarch_print_insn (gdbarch, print_insn_mn10300); - - /* Stage 2 */ - /* MVS Note: at least the first one is deprecated! */ - set_gdbarch_deprecated_use_struct_convention (gdbarch, - mn10300_use_struct_convention); - set_gdbarch_store_return_value (gdbarch, mn10300_store_return_value); - set_gdbarch_extract_return_value (gdbarch, mn10300_extract_return_value); - - /* Stage 3 -- get target calls working. */ - set_gdbarch_push_dummy_call (gdbarch, mn10300_push_dummy_call); - /* set_gdbarch_return_value (store, extract) */ - - - mn10300_frame_unwind_init (gdbarch); - - return gdbarch; -} - -/* Dump out the mn10300 specific architecture information. */ - -static void -mn10300_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n", - tdep->am33_mode); -} - -void -_initialize_mn10300_tdep (void) -{ - gdbarch_register (bfd_arch_mn10300, mn10300_gdbarch_init, mn10300_dump_tdep); -} - +/* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger. + + Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, + 2007, 2008, 2009, 2010 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 . */ + +#include "defs.h" +#include "arch-utils.h" +#include "dis-asm.h" +#include "gdbtypes.h" +#include "regcache.h" +#include "gdb_string.h" +#include "gdb_assert.h" +#include "gdbcore.h" /* for write_memory_unsigned_integer */ +#include "value.h" +#include "gdbtypes.h" +#include "frame.h" +#include "frame-unwind.h" +#include "frame-base.h" +#include "symtab.h" +#include "dwarf2-frame.h" +#include "osabi.h" +#include "infcall.h" +#include "prologue-value.h" +#include "target.h" + +#include "mn10300-tdep.h" + + +/* The am33-2 has 64 registers. */ +#define MN10300_MAX_NUM_REGS 64 + +/* This structure holds the results of a prologue analysis. */ +struct mn10300_prologue +{ + /* The architecture for which we generated this prologue info. */ + struct gdbarch *gdbarch; + + /* The offset from the frame base to the stack pointer --- always + zero or negative. + + Calling this a "size" is a bit misleading, but given that the + stack grows downwards, using offsets for everything keeps one + from going completely sign-crazy: you never change anything's + sign for an ADD instruction; always change the second operand's + sign for a SUB instruction; and everything takes care of + itself. */ + int frame_size; + + /* Non-zero if this function has initialized the frame pointer from + the stack pointer, zero otherwise. */ + int has_frame_ptr; + + /* If has_frame_ptr is non-zero, this is the offset from the frame + base to where the frame pointer points. This is always zero or + negative. */ + int frame_ptr_offset; + + /* The address of the first instruction at which the frame has been + set up and the arguments are where the debug info says they are + --- as best as we can tell. */ + CORE_ADDR prologue_end; + + /* reg_offset[R] is the offset from the CFA at which register R is + saved, or 1 if register R has not been saved. (Real values are + always zero or negative.) */ + int reg_offset[MN10300_MAX_NUM_REGS]; +}; + + +/* Compute the alignment required by a type. */ + +static int +mn10300_type_align (struct type *type) +{ + int i, align = 1; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_INT: + case TYPE_CODE_ENUM: + case TYPE_CODE_SET: + case TYPE_CODE_RANGE: + case TYPE_CODE_CHAR: + case TYPE_CODE_BOOL: + case TYPE_CODE_FLT: + case TYPE_CODE_PTR: + case TYPE_CODE_REF: + return TYPE_LENGTH (type); + + case TYPE_CODE_COMPLEX: + return TYPE_LENGTH (type) / 2; + + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + for (i = 0; i < TYPE_NFIELDS (type); i++) + { + int falign = mn10300_type_align (TYPE_FIELD_TYPE (type, i)); + while (align < falign) + align <<= 1; + } + return align; + + case TYPE_CODE_ARRAY: + /* HACK! Structures containing arrays, even small ones, are not + elligible for returning in registers. */ + return 256; + + case TYPE_CODE_TYPEDEF: + return mn10300_type_align (check_typedef (type)); + + default: + internal_error (__FILE__, __LINE__, _("bad switch")); + } +} + +/* Should call_function allocate stack space for a struct return? */ +static int +mn10300_use_struct_convention (struct type *type) +{ + /* Structures bigger than a pair of words can't be returned in + registers. */ + if (TYPE_LENGTH (type) > 8) + return 1; + + switch (TYPE_CODE (type)) + { + case TYPE_CODE_STRUCT: + case TYPE_CODE_UNION: + /* Structures with a single field are handled as the field + itself. */ + if (TYPE_NFIELDS (type) == 1) + return mn10300_use_struct_convention (TYPE_FIELD_TYPE (type, 0)); + + /* Structures with word or double-word size are passed in memory, as + long as they require at least word alignment. */ + if (mn10300_type_align (type) >= 4) + return 0; + + return 1; + + /* Arrays are addressable, so they're never returned in + registers. This condition can only hold when the array is + the only field of a struct or union. */ + case TYPE_CODE_ARRAY: + return 1; + + case TYPE_CODE_TYPEDEF: + return mn10300_use_struct_convention (check_typedef (type)); + + default: + return 0; + } +} + +static void +mn10300_store_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, const void *valbuf) +{ + int len = TYPE_LENGTH (type); + int reg, regsz; + + if (TYPE_CODE (type) == TYPE_CODE_PTR) + reg = 4; + else + reg = 0; + + regsz = register_size (gdbarch, reg); + + if (len <= regsz) + regcache_raw_write_part (regcache, reg, 0, len, valbuf); + else if (len <= 2 * regsz) + { + regcache_raw_write (regcache, reg, valbuf); + gdb_assert (regsz == register_size (gdbarch, reg + 1)); + regcache_raw_write_part (regcache, reg+1, 0, + len - regsz, (char *) valbuf + regsz); + } + else + internal_error (__FILE__, __LINE__, + _("Cannot store return value %d bytes long."), len); +} + +static void +mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type, + struct regcache *regcache, void *valbuf) +{ + char buf[MAX_REGISTER_SIZE]; + int len = TYPE_LENGTH (type); + int reg, regsz; + + if (TYPE_CODE (type) == TYPE_CODE_PTR) + reg = 4; + else + reg = 0; + + regsz = register_size (gdbarch, reg); + if (len <= regsz) + { + regcache_raw_read (regcache, reg, buf); + memcpy (valbuf, buf, len); + } + else if (len <= 2 * regsz) + { + regcache_raw_read (regcache, reg, buf); + memcpy (valbuf, buf, regsz); + gdb_assert (regsz == register_size (gdbarch, reg + 1)); + regcache_raw_read (regcache, reg + 1, buf); + memcpy ((char *) valbuf + regsz, buf, len - regsz); + } + else + internal_error (__FILE__, __LINE__, + _("Cannot extract return value %d bytes long."), len); +} + +/* 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 +mn10300_return_value (struct gdbarch *gdbarch, struct type *func_type, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) +{ + if (mn10300_use_struct_convention (type)) + return RETURN_VALUE_STRUCT_CONVENTION; + + if (readbuf) + mn10300_extract_return_value (gdbarch, type, regcache, readbuf); + if (writebuf) + mn10300_store_return_value (gdbarch, type, regcache, writebuf); + + return RETURN_VALUE_REGISTER_CONVENTION; +} + +static char * +register_name (int reg, char **regs, long sizeof_regs) +{ + if (reg < 0 || reg >= sizeof_regs / sizeof (regs[0])) + return NULL; + else + return regs[reg]; +} + +static const char * +mn10300_generic_register_name (struct gdbarch *gdbarch, int reg) +{ + static char *regs[] = + { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", + "sp", "pc", "mdr", "psw", "lir", "lar", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "fp" + }; + return register_name (reg, regs, sizeof regs); +} + + +static const char * +am33_register_name (struct gdbarch *gdbarch, int reg) +{ + static char *regs[] = + { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", + "sp", "pc", "mdr", "psw", "lir", "lar", "", + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "ssp", "msp", "usp", "mcrh", "mcrl", "mcvf", "", "", "" + }; + return register_name (reg, regs, sizeof regs); +} + +static const char * +am33_2_register_name (struct gdbarch *gdbarch, int reg) +{ + static char *regs[] = + { + "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", + "sp", "pc", "mdr", "psw", "lir", "lar", "mdrq", "r0", + "r1", "r2", "r3", "r4", "r5", "r6", "r7", "ssp", + "msp", "usp", "mcrh", "mcrl", "mcvf", "fpcr", "", "", + "fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15", + "fs16", "fs17", "fs18", "fs19", "fs20", "fs21", "fs22", "fs23", + "fs24", "fs25", "fs26", "fs27", "fs28", "fs29", "fs30", "fs31" + }; + return register_name (reg, regs, sizeof regs); +} + +static struct type * +mn10300_register_type (struct gdbarch *gdbarch, int reg) +{ + return builtin_type (gdbarch)->builtin_int; +} + +static CORE_ADDR +mn10300_read_pc (struct regcache *regcache) +{ + ULONGEST val; + regcache_cooked_read_unsigned (regcache, E_PC_REGNUM, &val); + return val; +} + +static void +mn10300_write_pc (struct regcache *regcache, CORE_ADDR val) +{ + regcache_cooked_write_unsigned (regcache, E_PC_REGNUM, val); +} + +/* The breakpoint instruction must be the same size as the smallest + instruction in the instruction set. + + The Matsushita mn10x00 processors have single byte instructions + so we need a single byte breakpoint. Matsushita hasn't defined + one, so we defined it ourselves. */ + +const static unsigned char * +mn10300_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr, + int *bp_size) +{ + static char breakpoint[] = {0xff}; + *bp_size = 1; + return breakpoint; +} + +/* Model the semantics of pushing a register onto the stack. This + is a helper function for mn10300_analyze_prologue, below. */ +static void +push_reg (pv_t *regs, struct pv_area *stack, int regnum) +{ + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], -4); + pv_area_store (stack, regs[E_SP_REGNUM], 4, regs[regnum]); +} + +/* Translate an "r" register number extracted from an instruction encoding + into a GDB register number. Adapted from a simulator function + of the same name; see am33.igen. */ +static int +translate_rreg (int rreg) +{ + /* The higher register numbers actually correspond to the + basic machine's address and data registers. */ + if (rreg > 7 && rreg < 12) + return E_A0_REGNUM + rreg - 8; + else if (rreg > 11 && rreg < 16) + return E_D0_REGNUM + rreg - 12; + else + return E_E0_REGNUM + rreg; +} + +/* Find saved registers in a 'struct pv_area'; we pass this to pv_area_scan. + + If VALUE is a saved register, ADDR says it was saved at a constant + offset from the frame base, and SIZE indicates that the whole + register was saved, record its offset in RESULT_UNTYPED. */ +static void +check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value) +{ + struct mn10300_prologue *result = (struct mn10300_prologue *) result_untyped; + + if (value.kind == pvk_register + && value.k == 0 + && pv_is_register (addr, E_SP_REGNUM) + && size == register_size (result->gdbarch, value.reg)) + result->reg_offset[value.reg] = addr.k; +} + +/* Analyze the prologue to determine where registers are saved, + the end of the prologue, etc. The result of this analysis is + returned in RESULT. See struct mn10300_prologue above for more + information. */ +static void +mn10300_analyze_prologue (struct gdbarch *gdbarch, + CORE_ADDR start_pc, CORE_ADDR limit_pc, + struct mn10300_prologue *result) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + CORE_ADDR pc, next_pc; + int rn; + pv_t regs[MN10300_MAX_NUM_REGS]; + struct pv_area *stack; + struct cleanup *back_to; + CORE_ADDR after_last_frame_setup_insn = start_pc; + int am33_mode = AM33_MODE (gdbarch); + + memset (result, 0, sizeof (*result)); + result->gdbarch = gdbarch; + + for (rn = 0; rn < MN10300_MAX_NUM_REGS; rn++) + { + regs[rn] = pv_register (rn, 0); + result->reg_offset[rn] = 1; + } + stack = make_pv_area (E_SP_REGNUM, gdbarch_addr_bit (gdbarch)); + back_to = make_cleanup_free_pv_area (stack); + + /* The typical call instruction will have saved the return address on the + stack. Space for the return address has already been preallocated in + the caller's frame. It's possible, such as when using -mrelax with gcc + that other registers were saved as well. If this happens, we really + have no chance of deciphering the frame. DWARF info can save the day + when this happens. */ + pv_area_store (stack, regs[E_SP_REGNUM], 4, regs[E_PC_REGNUM]); + + pc = start_pc; + while (pc < limit_pc) + { + int status; + gdb_byte instr[2]; + + /* Instructions can be as small as one byte; however, we usually + need at least two bytes to do the decoding, so fetch that many + to begin with. */ + status = target_read_memory (pc, instr, 2); + if (status != 0) + break; + + /* movm [regs], sp */ + if (instr[0] == 0xcf) + { + gdb_byte save_mask; + + save_mask = instr[1]; + + if ((save_mask & movm_exreg0_bit) && am33_mode) + { + push_reg (regs, stack, E_E2_REGNUM); + push_reg (regs, stack, E_E3_REGNUM); + } + if ((save_mask & movm_exreg1_bit) && am33_mode) + { + push_reg (regs, stack, E_E4_REGNUM); + push_reg (regs, stack, E_E5_REGNUM); + push_reg (regs, stack, E_E6_REGNUM); + push_reg (regs, stack, E_E7_REGNUM); + } + if ((save_mask & movm_exother_bit) && am33_mode) + { + push_reg (regs, stack, E_E0_REGNUM); + push_reg (regs, stack, E_E1_REGNUM); + push_reg (regs, stack, E_MDRQ_REGNUM); + push_reg (regs, stack, E_MCRH_REGNUM); + push_reg (regs, stack, E_MCRL_REGNUM); + push_reg (regs, stack, E_MCVF_REGNUM); + } + if (save_mask & movm_d2_bit) + push_reg (regs, stack, E_D2_REGNUM); + if (save_mask & movm_d3_bit) + push_reg (regs, stack, E_D3_REGNUM); + if (save_mask & movm_a2_bit) + push_reg (regs, stack, E_A2_REGNUM); + if (save_mask & movm_a3_bit) + push_reg (regs, stack, E_A3_REGNUM); + if (save_mask & movm_other_bit) + { + push_reg (regs, stack, E_D0_REGNUM); + push_reg (regs, stack, E_D1_REGNUM); + push_reg (regs, stack, E_A0_REGNUM); + push_reg (regs, stack, E_A1_REGNUM); + push_reg (regs, stack, E_MDR_REGNUM); + push_reg (regs, stack, E_LIR_REGNUM); + push_reg (regs, stack, E_LAR_REGNUM); + /* The `other' bit leaves a blank area of four bytes at + the beginning of its block of saved registers, making + it 32 bytes long in total. */ + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], -4); + } + + pc += 2; + after_last_frame_setup_insn = pc; + } + /* mov sp, aN */ + else if ((instr[0] & 0xfc) == 0x3c) + { + int aN = instr[0] & 0x03; + + regs[E_A0_REGNUM + aN] = regs[E_SP_REGNUM]; + + pc += 1; + if (aN == 3) + after_last_frame_setup_insn = pc; + } + /* mov aM, aN */ + else if ((instr[0] & 0xf0) == 0x90 + && (instr[0] & 0x03) != ((instr[0] & 0x0c) >> 2)) + { + int aN = instr[0] & 0x03; + int aM = (instr[0] & 0x0c) >> 2; + + regs[E_A0_REGNUM + aN] = regs[E_A0_REGNUM + aM]; + + pc += 1; + } + /* mov dM, dN */ + else if ((instr[0] & 0xf0) == 0x80 + && (instr[0] & 0x03) != ((instr[0] & 0x0c) >> 2)) + { + int dN = instr[0] & 0x03; + int dM = (instr[0] & 0x0c) >> 2; + + regs[E_D0_REGNUM + dN] = regs[E_D0_REGNUM + dM]; + + pc += 1; + } + /* mov aM, dN */ + else if (instr[0] == 0xf1 && (instr[1] & 0xf0) == 0xd0) + { + int dN = instr[1] & 0x03; + int aM = (instr[1] & 0x0c) >> 2; + + regs[E_D0_REGNUM + dN] = regs[E_A0_REGNUM + aM]; + + pc += 2; + } + /* mov dM, aN */ + else if (instr[0] == 0xf1 && (instr[1] & 0xf0) == 0xe0) + { + int aN = instr[1] & 0x03; + int dM = (instr[1] & 0x0c) >> 2; + + regs[E_A0_REGNUM + aN] = regs[E_D0_REGNUM + dM]; + + pc += 2; + } + /* add imm8, SP */ + else if (instr[0] == 0xf8 && instr[1] == 0xfe) + { + gdb_byte buf[1]; + LONGEST imm8; + + + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; + + imm8 = extract_signed_integer (buf, 1, byte_order); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm8); + + pc += 3; + /* Stack pointer adjustments are frame related. */ + after_last_frame_setup_insn = pc; + } + /* add imm16, SP */ + else if (instr[0] == 0xfa && instr[1] == 0xfe) + { + gdb_byte buf[2]; + LONGEST imm16; + + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; + + imm16 = extract_signed_integer (buf, 2, byte_order); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm16); + + pc += 4; + /* Stack pointer adjustments are frame related. */ + after_last_frame_setup_insn = pc; + } + /* add imm32, SP */ + else if (instr[0] == 0xfc && instr[1] == 0xfe) + { + gdb_byte buf[4]; + LONGEST imm32; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + + imm32 = extract_signed_integer (buf, 4, byte_order); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm32); + + pc += 6; + /* Stack pointer adjustments are frame related. */ + after_last_frame_setup_insn = pc; + } + /* add imm8, aN */ + else if ((instr[0] & 0xfc) == 0x20) + { + int aN; + LONGEST imm8; + + aN = instr[0] & 0x03; + imm8 = extract_signed_integer (&instr[1], 1, byte_order); + + regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN], + imm8); + + pc += 2; + } + /* add imm16, aN */ + else if (instr[0] == 0xfa && (instr[1] & 0xfc) == 0xd0) + { + int aN; + LONGEST imm16; + gdb_byte buf[2]; + + aN = instr[1] & 0x03; + + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; + + + imm16 = extract_signed_integer (buf, 2, byte_order); + + regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN], + imm16); + + pc += 4; + } + /* add imm32, aN */ + else if (instr[0] == 0xfc && (instr[1] & 0xfc) == 0xd0) + { + int aN; + LONGEST imm32; + gdb_byte buf[4]; + + aN = instr[1] & 0x03; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + imm32 = extract_signed_integer (buf, 2, byte_order); + + regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN], + imm32); + pc += 6; + } + /* fmov fsM, (rN) */ + else if (instr[0] == 0xf9 && (instr[1] & 0xfd) == 0x30) + { + int fsM, sM, Y, rN; + gdb_byte buf[1]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + + pv_area_store (stack, regs[translate_rreg (rN)], 4, + regs[E_FS0_REGNUM + fsM]); + + pc += 3; + } + /* fmov fsM, (sp) */ + else if (instr[0] == 0xf9 && (instr[1] & 0xfd) == 0x34) + { + int fsM, sM, Y; + gdb_byte buf[1]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + fsM = (Y << 4) | sM; + + pv_area_store (stack, regs[E_SP_REGNUM], 4, + regs[E_FS0_REGNUM + fsM]); + + pc += 3; + } + /* fmov fsM, (rN, rI) */ + else if (instr[0] == 0xfb && instr[1] == 0x37) + { + int fsM, sM, Z, rN, rI; + gdb_byte buf[2]; + + + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; + + rI = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + sM = (buf[1] & 0xf0) >> 4; + Z = (buf[1] & 0x02) >> 1; + fsM = (Z << 4) | sM; + + pv_area_store (stack, + pv_add (regs[translate_rreg (rN)], + regs[translate_rreg (rI)]), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 4; + } + /* fmov fsM, (d8, rN) */ + else if (instr[0] == 0xfb && (instr[1] & 0xfd) == 0x30) + { + int fsM, sM, Y, rN; + LONGEST d8; + gdb_byte buf[2]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + d8 = extract_signed_integer (&buf[1], 1, byte_order); + + pv_area_store (stack, + pv_add_constant (regs[translate_rreg (rN)], d8), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 4; + } + /* fmov fsM, (d24, rN) */ + else if (instr[0] == 0xfd && (instr[1] & 0xfd) == 0x30) + { + int fsM, sM, Y, rN; + LONGEST d24; + gdb_byte buf[4]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + d24 = extract_signed_integer (&buf[1], 3, byte_order); + + pv_area_store (stack, + pv_add_constant (regs[translate_rreg (rN)], d24), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 6; + } + /* fmov fsM, (d32, rN) */ + else if (instr[0] == 0xfe && (instr[1] & 0xfd) == 0x30) + { + int fsM, sM, Y, rN; + LONGEST d32; + gdb_byte buf[5]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 5); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + d32 = extract_signed_integer (&buf[1], 4, byte_order); + + pv_area_store (stack, + pv_add_constant (regs[translate_rreg (rN)], d32), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 7; + } + /* fmov fsM, (d8, SP) */ + else if (instr[0] == 0xfb && (instr[1] & 0xfd) == 0x34) + { + int fsM, sM, Y; + LONGEST d8; + gdb_byte buf[2]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + fsM = (Y << 4) | sM; + d8 = extract_signed_integer (&buf[1], 1, byte_order); + + pv_area_store (stack, + pv_add_constant (regs[E_SP_REGNUM], d8), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 4; + } + /* fmov fsM, (d24, SP) */ + else if (instr[0] == 0xfd && (instr[1] & 0xfd) == 0x34) + { + int fsM, sM, Y; + LONGEST d24; + gdb_byte buf[4]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + fsM = (Y << 4) | sM; + d24 = extract_signed_integer (&buf[1], 3, byte_order); + + pv_area_store (stack, + pv_add_constant (regs[E_SP_REGNUM], d24), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 6; + } + /* fmov fsM, (d32, SP) */ + else if (instr[0] == 0xfe && (instr[1] & 0xfd) == 0x34) + { + int fsM, sM, Y; + LONGEST d32; + gdb_byte buf[5]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 5); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + fsM = (Y << 4) | sM; + d32 = extract_signed_integer (&buf[1], 4, byte_order); + + pv_area_store (stack, + pv_add_constant (regs[E_SP_REGNUM], d32), + 4, regs[E_FS0_REGNUM + fsM]); + + pc += 7; + } + /* fmov fsM, (rN+) */ + else if (instr[0] == 0xf9 && (instr[1] & 0xfd) == 0x31) + { + int fsM, sM, Y, rN, rN_regnum; + gdb_byte buf[1]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + + rN_regnum = translate_rreg (rN); + + pv_area_store (stack, regs[rN_regnum], 4, + regs[E_FS0_REGNUM + fsM]); + regs[rN_regnum] = pv_add_constant (regs[rN_regnum], 4); + + pc += 3; + } + /* fmov fsM, (rN+, imm8) */ + else if (instr[0] == 0xfb && (instr[1] & 0xfd) == 0x31) + { + int fsM, sM, Y, rN, rN_regnum; + LONGEST imm8; + gdb_byte buf[2]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + imm8 = extract_signed_integer (&buf[1], 1, byte_order); + + rN_regnum = translate_rreg (rN); + + pv_area_store (stack, regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]); + regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm8); + + pc += 4; + } + /* fmov fsM, (rN+, imm24) */ + else if (instr[0] == 0xfd && (instr[1] & 0xfd) == 0x31) + { + int fsM, sM, Y, rN, rN_regnum; + LONGEST imm24; + gdb_byte buf[4]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + imm24 = extract_signed_integer (&buf[1], 3, byte_order); + + rN_regnum = translate_rreg (rN); + + pv_area_store (stack, regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]); + regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm24); + + pc += 6; + } + /* fmov fsM, (rN+, imm32) */ + else if (instr[0] == 0xfe && (instr[1] & 0xfd) == 0x31) + { + int fsM, sM, Y, rN, rN_regnum; + LONGEST imm32; + gdb_byte buf[5]; + + Y = (instr[1] & 0x02) >> 1; + + status = target_read_memory (pc + 2, buf, 5); + if (status != 0) + break; + + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + imm32 = extract_signed_integer (&buf[1], 4, byte_order); + + rN_regnum = translate_rreg (rN); + + pv_area_store (stack, regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]); + regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm32); + + pc += 7; + } + /* mov imm8, aN */ + else if ((instr[0] & 0xf0) == 0x90) + { + int aN = instr[0] & 0x03; + LONGEST imm8; + + imm8 = extract_signed_integer (&instr[1], 1, byte_order); + + regs[E_A0_REGNUM + aN] = pv_constant (imm8); + pc += 2; + } + /* mov imm16, aN */ + else if ((instr[0] & 0xfc) == 0x24) + { + int aN = instr[0] & 0x03; + gdb_byte buf[2]; + LONGEST imm16; + + status = target_read_memory (pc + 1, buf, 2); + if (status != 0) + break; + + imm16 = extract_signed_integer (buf, 2, byte_order); + regs[E_A0_REGNUM + aN] = pv_constant (imm16); + pc += 3; + } + /* mov imm32, aN */ + else if (instr[0] == 0xfc && ((instr[1] & 0xfc) == 0xdc)) + { + int aN = instr[1] & 0x03; + gdb_byte buf[4]; + LONGEST imm32; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + imm32 = extract_signed_integer (buf, 4, byte_order); + regs[E_A0_REGNUM + aN] = pv_constant (imm32); + pc += 6; + } + /* mov imm8, dN */ + else if ((instr[0] & 0xf0) == 0x80) + { + int dN = instr[0] & 0x03; + LONGEST imm8; + + imm8 = extract_signed_integer (&instr[1], 1, byte_order); + + regs[E_D0_REGNUM + dN] = pv_constant (imm8); + pc += 2; + } + /* mov imm16, dN */ + else if ((instr[0] & 0xfc) == 0x2c) + { + int dN = instr[0] & 0x03; + gdb_byte buf[2]; + LONGEST imm16; + + status = target_read_memory (pc + 1, buf, 2); + if (status != 0) + break; + + imm16 = extract_signed_integer (buf, 2, byte_order); + regs[E_D0_REGNUM + dN] = pv_constant (imm16); + pc += 3; + } + /* mov imm32, dN */ + else if (instr[0] == 0xfc && ((instr[1] & 0xfc) == 0xcc)) + { + int dN = instr[1] & 0x03; + gdb_byte buf[4]; + LONGEST imm32; + + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; + + imm32 = extract_signed_integer (buf, 4, byte_order); + regs[E_D0_REGNUM + dN] = pv_constant (imm32); + pc += 6; + } + else + { + /* We've hit some instruction that we don't recognize. Hopefully, + we have enough to do prologue analysis. */ + break; + } + } + + /* Is the frame size (offset, really) a known constant? */ + if (pv_is_register (regs[E_SP_REGNUM], E_SP_REGNUM)) + result->frame_size = regs[E_SP_REGNUM].k; + + /* Was the frame pointer initialized? */ + if (pv_is_register (regs[E_A3_REGNUM], E_SP_REGNUM)) + { + result->has_frame_ptr = 1; + result->frame_ptr_offset = regs[E_A3_REGNUM].k; + } + + /* Record where all the registers were saved. */ + pv_area_scan (stack, check_for_saved, (void *) result); + + result->prologue_end = after_last_frame_setup_insn; + + do_cleanups (back_to); +} + +/* Function: skip_prologue + Return the address of the first inst past the prologue of the function. */ + +static CORE_ADDR +mn10300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + char *name; + CORE_ADDR func_addr, func_end; + struct mn10300_prologue p; + + /* Try to find the extent of the function that contains PC. */ + if (!find_pc_partial_function (pc, &name, &func_addr, &func_end)) + return pc; + + mn10300_analyze_prologue (gdbarch, pc, func_end, &p); + return p.prologue_end; +} + +/* Wrapper for mn10300_analyze_prologue: find the function start; + use the current frame PC as the limit, then + invoke mn10300_analyze_prologue and return its result. */ +static struct mn10300_prologue * +mn10300_analyze_frame_prologue (struct frame_info *this_frame, + void **this_prologue_cache) +{ + if (!*this_prologue_cache) + { + CORE_ADDR func_start, stop_addr; + + *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct mn10300_prologue); + + func_start = get_frame_func (this_frame); + stop_addr = get_frame_pc (this_frame); + + /* If we couldn't find any function containing the PC, then + just initialize the prologue cache, but don't do anything. */ + if (!func_start) + stop_addr = func_start; + + mn10300_analyze_prologue (get_frame_arch (this_frame), + func_start, stop_addr, *this_prologue_cache); + } + + return *this_prologue_cache; +} + +/* Given the next frame and a prologue cache, return this frame's + base. */ +static CORE_ADDR +mn10300_frame_base (struct frame_info *this_frame, void **this_prologue_cache) +{ + struct mn10300_prologue *p + = mn10300_analyze_frame_prologue (this_frame, this_prologue_cache); + + /* In functions that use alloca, the distance between the stack + pointer and the frame base varies dynamically, so we can't use + the SP plus static information like prologue analysis to find the + frame base. However, such functions must have a frame pointer, + to be able to restore the SP on exit. So whenever we do have a + frame pointer, use that to find the base. */ + if (p->has_frame_ptr) + { + CORE_ADDR fp = get_frame_register_unsigned (this_frame, E_A3_REGNUM); + return fp - p->frame_ptr_offset; + } + else + { + CORE_ADDR sp = get_frame_register_unsigned (this_frame, E_SP_REGNUM); + return sp - p->frame_size; + } +} + +/* Here is a dummy implementation. */ +static struct frame_id +mn10300_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + CORE_ADDR sp = get_frame_register_unsigned (this_frame, E_SP_REGNUM); + CORE_ADDR pc = get_frame_register_unsigned (this_frame, E_PC_REGNUM); + return frame_id_build (sp, pc); +} + +static void +mn10300_frame_this_id (struct frame_info *this_frame, + void **this_prologue_cache, + struct frame_id *this_id) +{ + *this_id = frame_id_build (mn10300_frame_base (this_frame, this_prologue_cache), + get_frame_func (this_frame)); + +} + +static struct value * +mn10300_frame_prev_register (struct frame_info *this_frame, + void **this_prologue_cache, int regnum) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame)); + struct mn10300_prologue *p + = mn10300_analyze_frame_prologue (this_frame, this_prologue_cache); + CORE_ADDR frame_base = mn10300_frame_base (this_frame, this_prologue_cache); + int reg_size = register_size (get_frame_arch (this_frame), regnum); + + if (regnum == E_SP_REGNUM) + return frame_unwind_got_constant (this_frame, regnum, frame_base); + + /* If prologue analysis says we saved this register somewhere, + return a description of the stack slot holding it. */ + if (p->reg_offset[regnum] != 1) + return frame_unwind_got_memory (this_frame, regnum, + frame_base + p->reg_offset[regnum]); + + /* Otherwise, presume we haven't changed the value of this + register, and get it from the next frame. */ + return frame_unwind_got_register (this_frame, regnum, regnum); +} + +static const struct frame_unwind mn10300_frame_unwind = { + NORMAL_FRAME, + mn10300_frame_this_id, + mn10300_frame_prev_register, + NULL, + default_frame_sniffer +}; + +static CORE_ADDR +mn10300_unwind_pc (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + ULONGEST pc; + + pc = frame_unwind_register_unsigned (this_frame, E_PC_REGNUM); + return pc; +} + +static CORE_ADDR +mn10300_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame) +{ + ULONGEST sp; + + sp = frame_unwind_register_unsigned (this_frame, E_SP_REGNUM); + return sp; +} + +static void +mn10300_frame_unwind_init (struct gdbarch *gdbarch) +{ + dwarf2_append_unwinders (gdbarch); + frame_unwind_append_unwinder (gdbarch, &mn10300_frame_unwind); + set_gdbarch_dummy_id (gdbarch, mn10300_dummy_id); + set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc); + set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp); +} + +/* Function: push_dummy_call + * + * Set up machine state for a target call, including + * function arguments, stack, return address, etc. + * + */ + +static CORE_ADDR +mn10300_push_dummy_call (struct gdbarch *gdbarch, + struct value *target_func, + struct regcache *regcache, + CORE_ADDR bp_addr, + int nargs, struct value **args, + CORE_ADDR sp, + int struct_return, + CORE_ADDR struct_addr) +{ + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + const int push_size = register_size (gdbarch, E_PC_REGNUM); + int regs_used; + int len, arg_len; + int stack_offset = 0; + int argnum; + char *val, valbuf[MAX_REGISTER_SIZE]; + + /* This should be a nop, but align the stack just in case something + went wrong. Stacks are four byte aligned on the mn10300. */ + sp &= ~3; + + /* Now make space on the stack for the args. + + XXX This doesn't appear to handle pass-by-invisible reference + arguments. */ + regs_used = struct_return ? 1 : 0; + for (len = 0, argnum = 0; argnum < nargs; argnum++) + { + arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3; + while (regs_used < 2 && arg_len > 0) + { + regs_used++; + arg_len -= push_size; + } + len += arg_len; + } + + /* Allocate stack space. */ + sp -= len; + + if (struct_return) + { + regs_used = 1; + regcache_cooked_write_unsigned (regcache, E_D0_REGNUM, struct_addr); + } + else + regs_used = 0; + + /* Push all arguments onto the stack. */ + for (argnum = 0; argnum < nargs; argnum++) + { + /* FIXME what about structs? Unions? */ + if (TYPE_CODE (value_type (*args)) == TYPE_CODE_STRUCT + && TYPE_LENGTH (value_type (*args)) > 8) + { + /* Change to pointer-to-type. */ + arg_len = push_size; + store_unsigned_integer (valbuf, push_size, byte_order, + value_address (*args)); + val = &valbuf[0]; + } + else + { + arg_len = TYPE_LENGTH (value_type (*args)); + val = (char *) value_contents (*args); + } + + while (regs_used < 2 && arg_len > 0) + { + regcache_cooked_write_unsigned (regcache, regs_used, + extract_unsigned_integer (val, push_size, byte_order)); + val += push_size; + arg_len -= push_size; + regs_used++; + } + + while (arg_len > 0) + { + write_memory (sp + stack_offset, val, push_size); + arg_len -= push_size; + val += push_size; + stack_offset += push_size; + } + + args++; + } + + /* Make space for the flushback area. */ + sp -= 8; + + /* Push the return address that contains the magic breakpoint. */ + sp -= 4; + write_memory_unsigned_integer (sp, push_size, byte_order, bp_addr); + + /* The CPU also writes the return address always into the + MDR register on "call". */ + regcache_cooked_write_unsigned (regcache, E_MDR_REGNUM, bp_addr); + + /* Update $sp. */ + regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp); + + /* On the mn10300, it's possible to move some of the stack adjustment + and saving of the caller-save registers out of the prologue and + into the call sites. (When using gcc, this optimization can + occur when using the -mrelax switch.) If this occurs, the dwarf2 + info will reflect this fact. We can test to see if this is the + case by creating a new frame using the current stack pointer and + the address of the function that we're about to call. We then + unwind SP and see if it's different than the SP of our newly + created frame. If the SP values are the same, the caller is not + expected to allocate any additional stack. On the other hand, if + the SP values are different, the difference determines the + additional stack that must be allocated. + + Note that we don't update the return value though because that's + the value of the stack just after pushing the arguments, but prior + to performing the call. This value is needed in order to + construct the frame ID of the dummy call. */ + { + CORE_ADDR func_addr = find_function_addr (target_func, NULL); + CORE_ADDR unwound_sp + = mn10300_unwind_sp (gdbarch, create_new_frame (sp, func_addr)); + if (sp != unwound_sp) + regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, + sp - (unwound_sp - sp)); + } + + return sp; +} + +/* If DWARF2 is a register number appearing in Dwarf2 debug info, then + mn10300_dwarf2_reg_to_regnum (DWARF2) is the corresponding GDB + register number. Why don't Dwarf2 and GDB use the same numbering? + Who knows? But since people have object files lying around with + the existing Dwarf2 numbering, and other people have written stubs + to work with the existing GDB, neither of them can change. So we + just have to cope. */ +static int +mn10300_dwarf2_reg_to_regnum (struct gdbarch *gdbarch, int dwarf2) +{ + /* This table is supposed to be shaped like the gdbarch_register_name + initializer in gcc/config/mn10300/mn10300.h. Registers which + appear in GCC's numbering, but have no counterpart in GDB's + world, are marked with a -1. */ + static int dwarf2_to_gdb[] = { + 0, 1, 2, 3, 4, 5, 6, 7, -1, 8, + 15, 16, 17, 18, 19, 20, 21, 22, + 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, + 9, 11 + }; + + if (dwarf2 < 0 + || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb)) + { + warning (_("Bogus register number in debug info: %d"), dwarf2); + return -1; + } + + return dwarf2_to_gdb[dwarf2]; +} + +static struct gdbarch * +mn10300_gdbarch_init (struct gdbarch_info info, + struct gdbarch_list *arches) +{ + struct gdbarch *gdbarch; + struct gdbarch_tdep *tdep; + int num_regs; + + arches = gdbarch_list_lookup_by_info (arches, &info); + if (arches != NULL) + return arches->gdbarch; + + tdep = xmalloc (sizeof (struct gdbarch_tdep)); + gdbarch = gdbarch_alloc (&info, tdep); + + switch (info.bfd_arch_info->mach) + { + case 0: + case bfd_mach_mn10300: + set_gdbarch_register_name (gdbarch, mn10300_generic_register_name); + tdep->am33_mode = 0; + num_regs = 32; + break; + case bfd_mach_am33: + set_gdbarch_register_name (gdbarch, am33_register_name); + tdep->am33_mode = 1; + num_regs = 32; + break; + case bfd_mach_am33_2: + set_gdbarch_register_name (gdbarch, am33_2_register_name); + tdep->am33_mode = 2; + num_regs = 64; + set_gdbarch_fp0_regnum (gdbarch, 32); + break; + default: + internal_error (__FILE__, __LINE__, + _("mn10300_gdbarch_init: Unknown mn10300 variant")); + break; + } + + /* By default, chars are unsigned. */ + set_gdbarch_char_signed (gdbarch, 0); + + /* Registers. */ + set_gdbarch_num_regs (gdbarch, num_regs); + set_gdbarch_register_type (gdbarch, mn10300_register_type); + set_gdbarch_skip_prologue (gdbarch, mn10300_skip_prologue); + set_gdbarch_read_pc (gdbarch, mn10300_read_pc); + set_gdbarch_write_pc (gdbarch, mn10300_write_pc); + set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM); + set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM); + set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mn10300_dwarf2_reg_to_regnum); + + /* Stack unwinding. */ + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); + /* Breakpoints. */ + set_gdbarch_breakpoint_from_pc (gdbarch, mn10300_breakpoint_from_pc); + /* decr_pc_after_break? */ + /* Disassembly. */ + set_gdbarch_print_insn (gdbarch, print_insn_mn10300); + + /* Stage 2 */ + set_gdbarch_return_value (gdbarch, mn10300_return_value); + + /* Stage 3 -- get target calls working. */ + set_gdbarch_push_dummy_call (gdbarch, mn10300_push_dummy_call); + /* set_gdbarch_return_value (store, extract) */ + + + mn10300_frame_unwind_init (gdbarch); + + /* Hook in ABI-specific overrides, if they have been registered. */ + gdbarch_init_osabi (info, gdbarch); + + return gdbarch; +} + +/* Dump out the mn10300 specific architecture information. */ + +static void +mn10300_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) +{ + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n", + tdep->am33_mode); +} + +/* Provide a prototype to silence -Wmissing-prototypes. */ +extern initialize_file_ftype _initialize_mn10300_tdep; + +void +_initialize_mn10300_tdep (void) +{ + gdbarch_register (bfd_arch_mn10300, mn10300_gdbarch_init, mn10300_dump_tdep); +} +