X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Fmn10300-tdep.c;h=7f81c5985fff53637f9c1095644f498d335bce93;hb=refs%2Fheads%2Fconcurrent-displaced-stepping-2020-04-01;hp=43c4e175a12975bd1d02e533c1ade842fd0efd1c;hpb=3e6b1689167b5b359770be126c938979a2683244;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c index 43c4e175a1..7f81c5985f 100644 --- a/gdb/mn10300-tdep.c +++ b/gdb/mn10300-tdep.c @@ -1,13 +1,12 @@ /* Target-dependent code for the Matsushita MN10300 for GDB, the GNU debugger. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 - Free Software Foundation, Inc. + Copyright (C) 1996-2020 Free Software Foundation, Inc. This file is part of GDB. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + 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, @@ -16,33 +15,71 @@ 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. */ + 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 "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 "dwarf2/frame.h" #include "osabi.h" +#include "infcall.h" +#include "prologue-value.h" +#include "target.h" #include "mn10300-tdep.h" -/* Forward decl. */ -extern struct trad_frame_cache *mn10300_frame_unwind_cache (struct frame_info*, - void **); + +/* The am33-2 has 64 registers. */ +#define MN10300_MAX_NUM_REGS 64 + +/* Big enough to hold the size of the largest register in bytes. */ +#define MN10300_MAX_REGISTER_SIZE 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. */ @@ -51,7 +88,7 @@ mn10300_type_align (struct type *type) { int i, align = 1; - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_INT: case TYPE_CODE_ENUM: @@ -62,6 +99,7 @@ mn10300_type_align (struct type *type) case TYPE_CODE_FLT: case TYPE_CODE_PTR: case TYPE_CODE_REF: + case TYPE_CODE_RVALUE_REF: return TYPE_LENGTH (type); case TYPE_CODE_COMPLEX: @@ -69,7 +107,7 @@ mn10300_type_align (struct type *type) case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: - for (i = 0; i < TYPE_NFIELDS (type); i++) + for (i = 0; i < type->num_fields (); i++) { int falign = mn10300_type_align (TYPE_FIELD_TYPE (type, i)); while (align < falign) @@ -79,7 +117,7 @@ mn10300_type_align (struct type *type) case TYPE_CODE_ARRAY: /* HACK! Structures containing arrays, even small ones, are not - elligible for returning in registers. */ + eligible for returning in registers. */ return 256; case TYPE_CODE_TYPEDEF: @@ -99,13 +137,13 @@ mn10300_use_struct_convention (struct type *type) if (TYPE_LENGTH (type) > 8) return 1; - switch (TYPE_CODE (type)) + switch (type->code ()) { case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: /* Structures with a single field are handled as the field itself. */ - if (TYPE_NFIELDS (type) == 1) + if (type->num_fields () == 1) return mn10300_use_struct_convention (TYPE_FIELD_TYPE (type, 0)); /* Structures with word or double-word size are passed in memory, as @@ -131,12 +169,12 @@ mn10300_use_struct_convention (struct type *type) static void mn10300_store_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, const void *valbuf) + struct regcache *regcache, const gdb_byte *valbuf) { int len = TYPE_LENGTH (type); int reg, regsz; - if (TYPE_CODE (type) == TYPE_CODE_PTR) + if (type->code () == TYPE_CODE_PTR) reg = 4; else reg = 0; @@ -144,13 +182,12 @@ mn10300_store_return_value (struct gdbarch *gdbarch, struct type *type, regsz = register_size (gdbarch, reg); if (len <= regsz) - regcache_raw_write_part (regcache, reg, 0, len, valbuf); + regcache->raw_write_part (reg, 0, len, valbuf); else if (len <= 2 * regsz) { - regcache_raw_write (regcache, reg, valbuf); + regcache->raw_write (reg, valbuf); gdb_assert (regsz == register_size (gdbarch, reg + 1)); - regcache_raw_write_part (regcache, reg+1, 0, - len - regsz, (char *) valbuf + regsz); + regcache->raw_write_part (reg + 1, 0, len - regsz, valbuf + regsz); } else internal_error (__FILE__, __LINE__, @@ -161,27 +198,28 @@ static void mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type, struct regcache *regcache, void *valbuf) { - char buf[MAX_REGISTER_SIZE]; + gdb_byte buf[MN10300_MAX_REGISTER_SIZE]; int len = TYPE_LENGTH (type); int reg, regsz; - if (TYPE_CODE (type) == TYPE_CODE_PTR) + if (type->code () == TYPE_CODE_PTR) reg = 4; else reg = 0; regsz = register_size (gdbarch, reg); + gdb_assert (regsz <= MN10300_MAX_REGISTER_SIZE); if (len <= regsz) { - regcache_raw_read (regcache, reg, buf); + regcache->raw_read (reg, buf); memcpy (valbuf, buf, len); } else if (len <= 2 * regsz) { - regcache_raw_read (regcache, reg, buf); + regcache->raw_read (reg, buf); memcpy (valbuf, buf, regsz); gdb_assert (regsz == register_size (gdbarch, reg + 1)); - regcache_raw_read (regcache, reg + 1, buf); + regcache->raw_read (reg + 1, buf); memcpy ((char *) valbuf + regsz, buf, len - regsz); } else @@ -196,9 +234,9 @@ mn10300_extract_return_value (struct gdbarch *gdbarch, struct type *type, from WRITEBUF into REGCACHE. */ static enum return_value_convention -mn10300_return_value (struct gdbarch *gdbarch, struct type *type, - struct regcache *regcache, gdb_byte *readbuf, - const gdb_byte *writebuf) +mn10300_return_value (struct gdbarch *gdbarch, struct value *function, + struct type *type, struct regcache *regcache, + gdb_byte *readbuf, const gdb_byte *writebuf) { if (mn10300_use_struct_convention (type)) return RETURN_VALUE_STRUCT_CONVENTION; @@ -211,8 +249,8 @@ mn10300_return_value (struct gdbarch *gdbarch, struct type *type, return RETURN_VALUE_REGISTER_CONVENTION; } -static char * -register_name (int reg, char **regs, long sizeof_regs) +static const char * +register_name (int reg, const char **regs, long sizeof_regs) { if (reg < 0 || reg >= sizeof_regs / sizeof (regs[0])) return NULL; @@ -221,9 +259,9 @@ register_name (int reg, char **regs, long sizeof_regs) } static const char * -mn10300_generic_register_name (int reg) +mn10300_generic_register_name (struct gdbarch *gdbarch, int reg) { - static char *regs[] = + static const char *regs[] = { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "sp", "pc", "mdr", "psw", "lir", "lar", "", "", "", "", "", "", "", "", "", "", @@ -234,9 +272,9 @@ mn10300_generic_register_name (int reg) static const char * -am33_register_name (int reg) +am33_register_name (struct gdbarch *gdbarch, int reg) { - static char *regs[] = + static const char *regs[] = { "d0", "d1", "d2", "d3", "a0", "a1", "a2", "a3", "sp", "pc", "mdr", "psw", "lir", "lar", "", "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", @@ -245,23 +283,27 @@ am33_register_name (int reg) 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) +static const char * +am33_2_register_name (struct gdbarch *gdbarch, int reg) { - return read_register_pid (E_PC_REGNUM, ptid); + static const 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 void -mn10300_write_pc (CORE_ADDR val, ptid_t ptid) +static struct type * +mn10300_register_type (struct gdbarch *gdbarch, int reg) { - return write_register_pid (E_PC_REGNUM, val, ptid); + return builtin_type (gdbarch)->builtin_int; } /* The breakpoint instruction must be the same size as the smallest @@ -270,584 +312,839 @@ mn10300_write_pc (CORE_ADDR val, ptid_t ptid) 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. */ +constexpr gdb_byte mn10300_break_insn[] = {0xff}; -const static unsigned char * -mn10300_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) -{ - static char breakpoint[] = {0xff}; - *bp_size = 1; - return breakpoint; -} - -/* - * Frame Extra Info: - * - * status -- actually frame type (SP, FP, or last frame) - * stack size -- offset to the next frame - * - * The former might ultimately be stored in the frame_base. - * Seems like there'd be a way to store the later too. - * - * Temporarily supply empty stub functions as place holders. - */ +typedef BP_MANIPULATION (mn10300_break_insn) mn10300_breakpoint; +/* Model the semantics of pushing a register onto the stack. This + is a helper function for mn10300_analyze_prologue, below. */ static void -my_frame_is_in_sp (struct frame_info *fi, void **this_cache) +push_reg (pv_t *regs, struct pv_area *stack, int regnum) { - struct trad_frame_cache *cache = mn10300_frame_unwind_cache (fi, this_cache); - trad_frame_set_this_base (cache, - frame_unwind_register_unsigned (fi, - E_SP_REGNUM)); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], -4); + stack->store (regs[E_SP_REGNUM], 4, regs[regnum]); } -static void -my_frame_is_in_fp (struct frame_info *fi, void **this_cache) +/* 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) { - struct trad_frame_cache *cache = mn10300_frame_unwind_cache (fi, this_cache); - trad_frame_set_this_base (cache, - frame_unwind_register_unsigned (fi, - E_A3_REGNUM)); + /* 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 -my_frame_is_last (struct frame_info *fi) +check_for_saved (void *result_untyped, pv_t addr, CORE_ADDR size, pv_t value) { -} + struct mn10300_prologue *result = (struct mn10300_prologue *) result_untyped; -static int -is_my_frame_in_sp (struct frame_info *fi) -{ - return 0; + 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; } -static int -is_my_frame_in_fp (struct frame_info *fi) +/* 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) { - return 0; -} + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); + CORE_ADDR pc; + int rn; + pv_t regs[MN10300_MAX_NUM_REGS]; + CORE_ADDR after_last_frame_setup_insn = start_pc; + int am33_mode = AM33_MODE (gdbarch); -static int -is_my_frame_last (struct frame_info *fi) -{ - return 0; -} + memset (result, 0, sizeof (*result)); + result->gdbarch = gdbarch; -static void -set_my_stack_size (struct frame_info *fi, CORE_ADDR size) -{ -} + for (rn = 0; rn < MN10300_MAX_NUM_REGS; rn++) + { + regs[rn] = pv_register (rn, 0); + result->reg_offset[rn] = 1; + } + pv_area stack (E_SP_REGNUM, gdbarch_addr_bit (gdbarch)); + + /* 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. */ + stack.store (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; -/* Set offsets of registers saved by movm instruction. - This is a helper function for mn10300_analyze_prologue. */ + /* 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; -static void -set_movm_offsets (struct frame_info *fi, - void **this_cache, - int movm_args) -{ - struct trad_frame_cache *cache; - int offset = 0; - CORE_ADDR base; + regs[E_A0_REGNUM + aN] = regs[E_SP_REGNUM]; - if (fi == NULL || this_cache == NULL) - return; + 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; - cache = mn10300_frame_unwind_cache (fi, this_cache); - if (cache == NULL) - return; + regs[E_A0_REGNUM + aN] = regs[E_A0_REGNUM + aM]; - base = trad_frame_get_this_base (cache); - if (movm_args & movm_other_bit) - { - /* 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. */ - trad_frame_set_reg_addr (cache, E_LAR_REGNUM, base + offset + 4); - trad_frame_set_reg_addr (cache, E_LIR_REGNUM, base + offset + 8); - trad_frame_set_reg_addr (cache, E_MDR_REGNUM, base + offset + 12); - trad_frame_set_reg_addr (cache, E_A0_REGNUM + 1, base + offset + 16); - trad_frame_set_reg_addr (cache, E_A0_REGNUM, base + offset + 20); - trad_frame_set_reg_addr (cache, E_D0_REGNUM + 1, base + offset + 24); - trad_frame_set_reg_addr (cache, E_D0_REGNUM, base + offset + 28); - offset += 32; - } + 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; - if (movm_args & movm_a3_bit) - { - trad_frame_set_reg_addr (cache, E_A3_REGNUM, base + offset); - offset += 4; - } - if (movm_args & movm_a2_bit) - { - trad_frame_set_reg_addr (cache, E_A2_REGNUM, base + offset); - offset += 4; - } - if (movm_args & movm_d3_bit) - { - trad_frame_set_reg_addr (cache, E_D3_REGNUM, base + offset); - offset += 4; - } - if (movm_args & movm_d2_bit) - { - trad_frame_set_reg_addr (cache, E_D2_REGNUM, base + offset); - offset += 4; - } - if (AM33_MODE) - { - if (movm_args & movm_exother_bit) - { - trad_frame_set_reg_addr (cache, E_MCVF_REGNUM, base + offset); - trad_frame_set_reg_addr (cache, E_MCRL_REGNUM, base + offset + 4); - trad_frame_set_reg_addr (cache, E_MCRH_REGNUM, base + offset + 8); - trad_frame_set_reg_addr (cache, E_MDRQ_REGNUM, base + offset + 12); - trad_frame_set_reg_addr (cache, E_E1_REGNUM, base + offset + 16); - trad_frame_set_reg_addr (cache, E_E0_REGNUM, base + offset + 20); - offset += 24; - } - if (movm_args & movm_exreg1_bit) - { - trad_frame_set_reg_addr (cache, E_E7_REGNUM, base + offset); - trad_frame_set_reg_addr (cache, E_E6_REGNUM, base + offset + 4); - trad_frame_set_reg_addr (cache, E_E5_REGNUM, base + offset + 8); - trad_frame_set_reg_addr (cache, E_E4_REGNUM, base + offset + 12); - offset += 16; - } - if (movm_args & movm_exreg0_bit) - { - trad_frame_set_reg_addr (cache, E_E3_REGNUM, base + offset); - trad_frame_set_reg_addr (cache, E_E2_REGNUM, base + offset + 4); - offset += 8; - } - } - /* The last (or first) thing on the stack will be the PC. */ - trad_frame_set_reg_addr (cache, E_PC_REGNUM, base + offset); - /* Save the SP in the 'traditional' way. - This will be the same location where the PC is saved. */ - trad_frame_set_reg_value (cache, E_SP_REGNUM, base + offset); -} + regs[E_D0_REGNUM + dN] = regs[E_D0_REGNUM + dM]; -/* The main purpose of this file is dealing with prologues to extract - information about stack frames and saved registers. + 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; - In gcc/config/mn13000/mn10300.c, the expand_prologue prologue - function is pretty readable, and has a nice explanation of how the - prologue is generated. The prologues generated by that code will - have the following form (NOTE: the current code doesn't handle all - this!): + regs[E_D0_REGNUM + dN] = regs[E_A0_REGNUM + aM]; - + If this is an old-style varargs function, then its arguments - need to be flushed back to the stack: - - mov d0,(4,sp) - mov d1,(4,sp) + 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; - + If we use any of the callee-saved registers, save them now. - - movm [some callee-saved registers],(sp) + regs[E_A0_REGNUM + aN] = regs[E_D0_REGNUM + dM]; - + If we have any floating-point registers to save: + pc += 2; + } + /* add imm8, SP */ + else if (instr[0] == 0xf8 && instr[1] == 0xfe) + { + gdb_byte buf[1]; + LONGEST imm8; - - Decrement the stack pointer to reserve space for the registers. - If the function doesn't need a frame pointer, we may combine - this with the adjustment that reserves space for the frame. - add -SIZE, sp + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; - - Save the floating-point registers. We have two possible - strategies: + imm8 = extract_signed_integer (buf, 1, byte_order); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm8); - . Save them at fixed offset from the SP: + 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; - fmov fsN,(OFFSETN,sp) - fmov fsM,(OFFSETM,sp) - ... + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; - Note that, if OFFSETN happens to be zero, you'll get the - different opcode: fmov fsN,(sp) + imm16 = extract_signed_integer (buf, 2, byte_order); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm16); - . Or, set a0 to the start of the save area, and then use - post-increment addressing to save the FP registers. + 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; - mov sp, a0 - add SIZE, a0 - fmov fsN,(a0+) - fmov fsM,(a0+) - ... + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; - + If the function needs a frame pointer, we set it here. - mov sp, a3 + imm32 = extract_signed_integer (buf, 4, byte_order); + regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], imm32); - + Now we reserve space for the stack frame proper. This could be - merged into the `add -SIZE, sp' instruction for FP saves up - above, unless we needed to set the frame pointer in the previous - step, or the frame is so large that allocating the whole thing at - once would put the FP register save slots out of reach of the - addressing mode (128 bytes). - - add -SIZE, sp + 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; - One day we might keep the stack pointer constant, that won't - change the code for prologues, but it will make the frame - pointerless case much more common. */ + aN = instr[0] & 0x03; + imm8 = extract_signed_integer (&instr[1], 1, byte_order); -/* Analyze the prologue to determine where registers are saved, - the end of the prologue, etc etc. Return the end of the prologue - scanned. + regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN], + imm8); - We store into FI (if non-null) several tidbits of information: + pc += 2; + } + /* add imm16, aN */ + else if (instr[0] == 0xfa && (instr[1] & 0xfc) == 0xd0) + { + int aN; + LONGEST imm16; + gdb_byte buf[2]; - * stack_size -- size of this stack frame. Note that if we stop in - certain parts of the prologue/epilogue we may claim the size of the - current frame is zero. This happens when the current frame has - not been allocated yet or has already been deallocated. + aN = instr[1] & 0x03; - * fsr -- Addresses of registers saved in the stack by this frame. + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; - * status -- A (relatively) generic status indicator. It's a bitmask - with the following bits: - MY_FRAME_IN_SP: The base of the current frame is actually in - the stack pointer. This can happen for frame pointerless - functions, or cases where we're stopped in the prologue/epilogue - itself. For these cases mn10300_analyze_prologue will need up - update fi->frame before returning or analyzing the register - save instructions. + imm16 = extract_signed_integer (buf, 2, byte_order); - MY_FRAME_IN_FP: The base of the current frame is in the - frame pointer register ($a3). + regs[E_A0_REGNUM + aN] = pv_add_constant (regs[E_A0_REGNUM + aN], + imm16); - NO_MORE_FRAMES: Set this if the current frame is "start" or - if the first instruction looks like mov ,sp. This tells - frame chain to not bother trying to unwind past this frame. */ + pc += 4; + } + /* add imm32, aN */ + else if (instr[0] == 0xfc && (instr[1] & 0xfc) == 0xd0) + { + int aN; + LONGEST imm32; + gdb_byte buf[4]; -static CORE_ADDR -mn10300_analyze_prologue (struct frame_info *fi, - void **this_cache, - CORE_ADDR pc) -{ - CORE_ADDR func_addr, func_end, addr, stop; - long stack_size; - int imm_size; - unsigned char buf[4]; - int status, movm_args = 0; - char *name; - - /* Use the PC in the frame if it's provided to look up the - start of this function. - - Note: kevinb/2003-07-16: We used to do the following here: - pc = (fi ? get_frame_pc (fi) : pc); - But this is (now) badly broken when called from analyze_dummy_frame(). - */ - if (fi) - { - pc = (pc ? pc : get_frame_pc (fi)); - /* At the start of a function our frame is in the stack pointer. */ - my_frame_is_in_sp (fi, this_cache); - } + aN = instr[1] & 0x03; - /* Find the start of this function. */ - status = find_pc_partial_function (pc, &name, &func_addr, &func_end); + status = target_read_memory (pc + 2, buf, 4); + if (status != 0) + break; - /* Do nothing if we couldn't find the start of this function + imm32 = extract_signed_integer (buf, 2, byte_order); - MVS: comment went on to say "or if we're stopped at the first - instruction in the prologue" -- but code doesn't reflect that, - and I don't want to do that anyway. */ - if (status == 0) - { - return pc; - } + 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]; - /* If we're in start, then give up. */ - if (strcmp (name, "start") == 0) - { - if (fi != NULL) - my_frame_is_last (fi); - return pc; - } + Y = (instr[1] & 0x02) >> 1; -#if 0 - /* Get the next two bytes into buf, we need two because rets is a two - byte insn and the first isn't enough to uniquely identify it. */ - status = deprecated_read_memory_nobpt (pc, buf, 2); - if (status != 0) - return pc; + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; - /* Note: kevinb/2003-07-16: We shouldn't be making these sorts of - changes to the frame in prologue examination code. */ - /* If we're physically on an "rets" instruction, then our frame has - already been deallocated. Note this can also be true for retf - and ret if they specify a size of zero. + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; - In this case fi->frame is bogus, we need to fix it. */ - if (fi && buf[0] == 0xf0 && buf[1] == 0xfc) - { - if (get_next_frame (fi) == NULL) - deprecated_update_frame_base_hack (fi, read_sp ()); - return get_frame_pc (fi); - } + stack.store (regs[translate_rreg (rN)], 4, + regs[E_FS0_REGNUM + fsM]); - /* Similarly if we're stopped on the first insn of a prologue as our - frame hasn't been allocated yet. */ - if (fi && get_frame_pc (fi) == func_addr) - { - if (get_next_frame (fi) == NULL) - deprecated_update_frame_base_hack (fi, read_sp ()); - return get_frame_pc (fi); - } -#endif + pc += 3; + } + /* fmov fsM, (sp) */ + else if (instr[0] == 0xf9 && (instr[1] & 0xfd) == 0x34) + { + int fsM, sM, Y; + gdb_byte buf[1]; - /* NOTE: from here on, we don't want to return without jumping to - finish_prologue. */ + Y = (instr[1] & 0x02) >> 1; + status = target_read_memory (pc + 2, buf, 1); + if (status != 0) + break; - /* Figure out where to stop scanning. */ - stop = fi ? pc : func_end; + sM = (buf[0] & 0xf0) >> 4; + fsM = (Y << 4) | sM; - /* Don't walk off the end of the function. */ - stop = stop > func_end ? func_end : stop; + stack.store (regs[E_SP_REGNUM], 4, + regs[E_FS0_REGNUM + fsM]); - /* Start scanning on the first instruction of this function. */ - addr = func_addr; + pc += 3; + } + /* fmov fsM, (rN, rI) */ + else if (instr[0] == 0xfb && instr[1] == 0x37) + { + int fsM, sM, Z, rN, rI; + gdb_byte buf[2]; - /* Suck in two bytes. */ - if (addr + 2 >= stop - || (status = deprecated_read_memory_nobpt (addr, buf, 2)) != 0) - goto finish_prologue; - /* First see if this insn sets the stack pointer from a register; if - so, it's probably the initialization of the stack pointer in _start, - so mark this as the bottom-most frame. */ - if (buf[0] == 0xf2 && (buf[1] & 0xf3) == 0xf0) - { - if (fi) - my_frame_is_last (fi); - goto finish_prologue; - } + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; - /* Now look for movm [regs],sp, which saves the callee saved registers. + rI = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + sM = (buf[1] & 0xf0) >> 4; + Z = (buf[1] & 0x02) >> 1; + fsM = (Z << 4) | sM; - At this time we don't know if fi->frame is valid, so we only note - that we encountered a movm instruction. Later, we'll set the entries - in fsr.regs as needed. */ - if (buf[0] == 0xcf) - { - /* Extract the register list for the movm instruction. */ - movm_args = buf[1]; + stack.store (pv_add (regs[translate_rreg (rN)], + regs[translate_rreg (rI)]), + 4, regs[E_FS0_REGNUM + fsM]); - addr += 2; + 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]; - /* Quit now if we're beyond the stop point. */ - if (addr >= stop) - goto finish_prologue; + Y = (instr[1] & 0x02) >> 1; - /* Get the next two bytes so the prologue scan can continue. */ - status = deprecated_read_memory_nobpt (addr, buf, 2); - if (status != 0) - goto finish_prologue; - } + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; - /* Now see if we set up a frame pointer via "mov sp,a3" */ - if (buf[0] == 0x3f) - { - addr += 1; + sM = (buf[0] & 0xf0) >> 4; + rN = buf[0] & 0x0f; + fsM = (Y << 4) | sM; + d8 = extract_signed_integer (&buf[1], 1, byte_order); + + stack.store (pv_add_constant (regs[translate_rreg (rN)], d8), + 4, regs[E_FS0_REGNUM + fsM]); - /* The frame pointer is now valid. */ - if (fi) + pc += 4; + } + /* fmov fsM, (d24, rN) */ + else if (instr[0] == 0xfd && (instr[1] & 0xfd) == 0x30) { - my_frame_is_in_fp (fi, this_cache); + 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); + + stack.store (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]; - /* Quit now if we're beyond the stop point. */ - if (addr >= stop) - goto finish_prologue; + Y = (instr[1] & 0x02) >> 1; - /* Get two more bytes so scanning can continue. */ - status = deprecated_read_memory_nobpt (addr, buf, 2); - if (status != 0) - goto finish_prologue; - } + 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); - /* Next we should allocate the local frame. No more prologue insns - are found after allocating the local frame. + stack.store (pv_add_constant (regs[translate_rreg (rN)], d32), + 4, regs[E_FS0_REGNUM + fsM]); - Search for add imm8,sp (0xf8feXX) - or add imm16,sp (0xfafeXXXX) - or add imm32,sp (0xfcfeXXXXXXXX). + 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]; - If none of the above was found, then this prologue has no - additional stack. */ + Y = (instr[1] & 0x02) >> 1; - imm_size = 0; - if (buf[0] == 0xf8 && buf[1] == 0xfe) - imm_size = 1; - else if (buf[0] == 0xfa && buf[1] == 0xfe) - imm_size = 2; - else if (buf[0] == 0xfc && buf[1] == 0xfe) - imm_size = 4; + status = target_read_memory (pc + 2, buf, 2); + if (status != 0) + break; - if (imm_size != 0) - { - /* Suck in imm_size more bytes, they'll hold the size of the - current frame. */ - status = deprecated_read_memory_nobpt (addr + 2, buf, imm_size); - if (status != 0) - goto finish_prologue; + sM = (buf[0] & 0xf0) >> 4; + fsM = (Y << 4) | sM; + d8 = extract_signed_integer (&buf[1], 1, byte_order); - /* Note the size of the stack in the frame info structure. */ - stack_size = extract_signed_integer (buf, imm_size); - if (fi) - set_my_stack_size (fi, stack_size); + stack.store (pv_add_constant (regs[E_SP_REGNUM], d8), + 4, regs[E_FS0_REGNUM + fsM]); - /* We just consumed 2 + imm_size bytes. */ - addr += 2 + imm_size; + 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); + + stack.store (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); + + stack.store (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); + + stack.store (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); + + stack.store (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); + + stack.store (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); + + stack.store (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; - /* No more prologue insns follow, so begin preparation to return. */ - goto finish_prologue; + 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; } - /* Do the essentials and get out of here. */ - finish_prologue: - /* Note if/where callee saved registers were saved. */ - if (fi) - set_movm_offsets (fi, this_cache, movm_args); - return addr; + + /* Record where all the registers were saved. */ + stack.scan (check_for_saved, (void *) result); + + result->prologue_end = after_last_frame_setup_insn; } /* 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) +mn10300_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { - return mn10300_analyze_prologue (NULL, NULL, pc); + const 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; } -/* 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) +/* 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) { - struct trad_frame_cache *cache; - CORE_ADDR pc, start, end; - - 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); - if (find_pc_partial_function (pc, NULL, &start, &end)) - trad_frame_set_id (cache, - frame_id_build (trad_frame_get_this_base (cache), - start)); - else - trad_frame_set_id (cache, - frame_id_build (trad_frame_get_this_base (cache), - frame_func_unwind (next_frame))); + if (!*this_prologue_cache) + { + CORE_ADDR func_start, stop_addr; + + *this_prologue_cache = FRAME_OBSTACK_ZALLOC (struct mn10300_prologue); - (*this_prologue_cache) = cache; - return cache; + 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, + ((struct mn10300_prologue *) + *this_prologue_cache)); + } + + return (struct mn10300_prologue *) *this_prologue_cache; } -/* Here is a dummy implementation. */ -static struct frame_id -mn10300_unwind_dummy_id (struct gdbarch *gdbarch, - struct frame_info *next_frame) +/* 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) { - return frame_id_build (frame_sp_unwind (next_frame), - frame_pc_unwind (next_frame)); + 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; + } } -/* Trad frame implementation. */ static void -mn10300_frame_this_id (struct frame_info *next_frame, +mn10300_frame_this_id (struct frame_info *this_frame, void **this_prologue_cache, struct frame_id *this_id) { - struct trad_frame_cache *cache = - mn10300_frame_unwind_cache (next_frame, this_prologue_cache); + *this_id = frame_id_build (mn10300_frame_base (this_frame, + this_prologue_cache), + get_frame_func (this_frame)); - 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, gdb_byte *bufferp) +static struct value * +mn10300_frame_prev_register (struct frame_info *this_frame, + void **this_prologue_cache, int regnum) { - 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); - */ + 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); + + 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, + default_frame_unwind_stop_reason, 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 + mn10300_frame_prev_register, + NULL, + default_frame_sniffer }; -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); + dwarf2_append_unwinders (gdbarch); + frame_unwind_append_unwinder (gdbarch, &mn10300_frame_unwind); } /* Function: push_dummy_call @@ -864,15 +1161,17 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR bp_addr, int nargs, struct value **args, CORE_ADDR sp, - int struct_return, + function_call_return_method return_method, 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]; + const gdb_byte *val; + gdb_byte valbuf[MN10300_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. */ @@ -882,7 +1181,7 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, XXX This doesn't appear to handle pass-by-invisible reference arguments. */ - regs_used = struct_return ? 1 : 0; + regs_used = (return_method == return_method_struct) ? 1 : 0; for (len = 0, argnum = 0; argnum < nargs; argnum++) { arg_len = (TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3; @@ -897,37 +1196,38 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, /* Allocate stack space. */ sp -= len; - if (struct_return) + if (return_method == return_method_struct) { regs_used = 1; - write_register (E_D0_REGNUM, struct_addr); + regcache_cooked_write_unsigned (regcache, E_D0_REGNUM, struct_addr); } else regs_used = 0; - /* Push all arguments onto the stack. */ + /* 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 + if (value_type (*args)->code () == TYPE_CODE_STRUCT && TYPE_LENGTH (value_type (*args)) > 8) { /* Change to pointer-to-type. */ arg_len = push_size; - store_unsigned_integer (valbuf, push_size, - VALUE_ADDRESS (*args)); + gdb_assert (push_size <= MN10300_MAX_REGISTER_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); + val = value_contents (*args); } while (regs_used < 2 && arg_len > 0) { - write_register (regs_used, - extract_unsigned_integer (val, push_size)); + regcache_cooked_write_unsigned (regcache, regs_used, + extract_unsigned_integer (val, push_size, byte_order)); val += push_size; arg_len -= push_size; regs_used++; @@ -949,12 +1249,87 @@ mn10300_push_dummy_call (struct gdbarch *gdbarch, /* Push the return address that contains the magic breakpoint. */ sp -= 4; - write_memory_unsigned_integer (sp, push_size, bp_addr); + 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 + = gdbarch_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[] = { + E_D0_REGNUM, E_D1_REGNUM, E_D2_REGNUM, E_D3_REGNUM, + E_A0_REGNUM, E_A1_REGNUM, E_A2_REGNUM, E_A3_REGNUM, + -1, E_SP_REGNUM, + + E_E0_REGNUM, E_E1_REGNUM, E_E2_REGNUM, E_E3_REGNUM, + E_E4_REGNUM, E_E5_REGNUM, E_E6_REGNUM, E_E7_REGNUM, + + E_FS0_REGNUM + 0, E_FS0_REGNUM + 1, E_FS0_REGNUM + 2, E_FS0_REGNUM + 3, + E_FS0_REGNUM + 4, E_FS0_REGNUM + 5, E_FS0_REGNUM + 6, E_FS0_REGNUM + 7, + + E_FS0_REGNUM + 8, E_FS0_REGNUM + 9, E_FS0_REGNUM + 10, E_FS0_REGNUM + 11, + E_FS0_REGNUM + 12, E_FS0_REGNUM + 13, E_FS0_REGNUM + 14, E_FS0_REGNUM + 15, + + E_FS0_REGNUM + 16, E_FS0_REGNUM + 17, E_FS0_REGNUM + 18, E_FS0_REGNUM + 19, + E_FS0_REGNUM + 20, E_FS0_REGNUM + 21, E_FS0_REGNUM + 22, E_FS0_REGNUM + 23, + + E_FS0_REGNUM + 24, E_FS0_REGNUM + 25, E_FS0_REGNUM + 26, E_FS0_REGNUM + 27, + E_FS0_REGNUM + 28, E_FS0_REGNUM + 29, E_FS0_REGNUM + 30, E_FS0_REGNUM + 31, + + E_MDR_REGNUM, E_PSW_REGNUM, E_PC_REGNUM + }; + + if (dwarf2 < 0 + || dwarf2 >= ARRAY_SIZE (dwarf2_to_gdb)) + return -1; + + return dwarf2_to_gdb[dwarf2]; +} static struct gdbarch * mn10300_gdbarch_init (struct gdbarch_info info, @@ -962,12 +1337,13 @@ mn10300_gdbarch_init (struct gdbarch_info info, { 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)); + tdep = XCNEW (struct gdbarch_tdep); gdbarch = gdbarch_alloc (&info, tdep); switch (info.bfd_arch_info->mach) @@ -976,10 +1352,18 @@ mn10300_gdbarch_init (struct gdbarch_info info, 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__, @@ -987,22 +1371,25 @@ mn10300_gdbarch_init (struct gdbarch_info info, break; } + /* By default, chars are unsigned. */ + set_gdbarch_char_signed (gdbarch, 0); + /* Registers. */ - set_gdbarch_num_regs (gdbarch, E_NUM_REGS); + 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); + set_gdbarch_breakpoint_kind_from_pc (gdbarch, + mn10300_breakpoint::kind_from_pc); + set_gdbarch_sw_breakpoint_from_kind (gdbarch, + mn10300_breakpoint::bp_from_kind); + /* decr_pc_after_break? */ /* Stage 2 */ set_gdbarch_return_value (gdbarch, mn10300_return_value); @@ -1020,18 +1407,19 @@ mn10300_gdbarch_init (struct gdbarch_info info, return gdbarch; } -/* Dump out the mn10300 specific architecture information. */ +/* Dump out the mn10300 specific architecture information. */ static void -mn10300_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file) +mn10300_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) { - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); fprintf_unfiltered (file, "mn10300_dump_tdep: am33_mode = %d\n", tdep->am33_mode); } +void _initialize_mn10300_tdep (); void -_initialize_mn10300_tdep (void) +_initialize_mn10300_tdep () { gdbarch_register (bfd_arch_mn10300, mn10300_gdbarch_init, mn10300_dump_tdep); }