+2004-11-13 Andrew Cagney <cagney@gnu.org>
+
+ * NEWS: List h8300*-*-*, mcore-*-*, mn10300-*-*, ns32k-*-*, and
+ v850-*-* under removed.
+ * configure.host: Delete ns32k-*-netbsd*.
+ * configure.tgt: Delete h8300-*-*, mcore*-*-*, mn10300-*-*,
+ ns32k-*-netbsd*, and v850*-*-*.
+ * MAINTAINERS: Mark h8300, mcore, mn10300, ns32k, v850 as
+ "Deleted"
+ * config/h8300/tm-h8300.h, config/h8300/h8300.mt: Delete.
+ * h8300-tdep.c, config/mcore/mcore.mt, mcore-rom.c: Delete.
+ * mcore-tdep.c, config/mn10300/mn10300.mt: Delete.
+ * mn10300-tdep.c, config/ns32k/nbsdaout.mh: Delete.
+ * config/ns32k/nbsdaout.mt, config/ns32k/nm-nbsd.h: Delete.
+ * config/ns32k/nm-nbsdaout.h, config/ns32k/tm-ns32k.h: Delete.
+ * ns32knbsd-nat.c, ns32knbsd-tdep.c, ns32k-tdep.c: Delete.
+ * ns32k-tdep.h, config/v850/v850.mt, v850ice.c: Delete.
+ * v850-tdep.c: Delete.
+
2004-11-13 Joel Brobecker <brobecker@gnat.com>
* irix5-nat.c (fetch_core_registers): Replace use of
frv --target=frv-elf ,-Werror
Maintenance only
- h8300 --target=h8300hms broken
- Maintenance only
+ h8300 Deleted
i386 --target=i386-elf ,-Werror
Mark Kettenis kettenis@gnu.org
m88k --target=m88k-openbsd ,-Werror
Mark Kettenis kettenis@gnu.org
- mcore --target=mcore-elf broken
- Maintenance only
+ mcore Deleted
mips --target=mips-elf ,-Werror
Andrew Cagney cagney@redhat.com
- mn10300 --target=mn10300-elf broken
- Maintenance only
+ mn10300 Deleted
- ns32k --target=ns32k-netbsd broken
- Maintenance only
+ ns32k Deleted
pa --target=hppa-elf ,-Werror
Maintenance only
sparc --target=sparc-elf ,-Werror
Maintenance only
- v850 --target=v850-elf broken
- Maintenance only
+ v850 Deleted
vax --target=vax-netbsd ,-Werror
Maintenance only
* REMOVED configurations and files
VxWorks and the XDR protocol *-*-vxworks
+Renesas H8/300S h8300*-*-*
+Motorola MCORE mcore-*-*
+Matsushita MN10300 w/simulator mn10300-*-*
+National Semiconductor NS32000 ns32k-*-*
+NEC V850 v850-*-*
*** Changes in GDB 6.3:
+++ /dev/null
-# Target: H8300 with HMS monitor, E7000 ICE and H8 simulator
-TDEPFILES= h8300-tdep.o remote-e7000.o ser-e7kpc.o monitor.o remote-hms.o dsrec.o
-DEPRECATED_TM_FILE= tm-h8300.h
-
-SIM_OBS = remote-sim.o
-SIM = ../sim/h8300/libsim.a
+++ /dev/null
-/* Parameters for execution on a H8/300 series machine.
- Copyright 1992, 1993, 1994, 1996, 1998, 1999, 2000
- 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. */
-/* Contributed by Steve Chamberlain sac@cygnus.com */
-
-/* Needed for remote.c */
-#define DEPRECATED_REMOTE_BREAKPOINT { 0x57, 0x30} /* trapa #3 */
-/* Needed for remote-hms.c */
-#define CCR_REGNUM 8
-/* Needed for remote-e7000.c */
-#define NUM_REALREGS ((TARGET_ARCHITECTURE->mach == bfd_mach_h8300s || \
- TARGET_ARCHITECTURE->mach == bfd_mach_h8300sn || \
- TARGET_ARCHITECTURE->mach == bfd_mach_h8300sx || \
- TARGET_ARCHITECTURE->mach == bfd_mach_h8300sxn) ? 11 : 10)
-
+++ /dev/null
-# Target: Motorola MCore processor
-TDEPFILES= mcore-tdep.o mcore-rom.o monitor.o dsrec.o
-SIM_OBS = remote-sim.o
-SIM = ../sim/mcore/libsim.a
+++ /dev/null
-# Target: Matsushita mn10300
-TDEPFILES= mn10300-tdep.o
-SIM_OBS = remote-sim.o
-SIM = ../sim/mn10300/libsim.a
+++ /dev/null
-# Host: PC532 running NetBSD
-NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o ns32knbsd-nat.o \
- solib.o solib-sunos.o
-NAT_FILE= nm-nbsdaout.h
+++ /dev/null
-# Target: PC532 running NetBSD
-TDEPFILES= ns32k-tdep.o ns32knbsd-tdep.o
-DEPRECATED_TM_FILE= tm-ns32k.h
+++ /dev/null
-/* Native-dependent definitions for ns32k running NetBSD, for GDB.
- Copyright 1986, 1987, 1989, 1992, 1994, 2000
- 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. */
-
-#ifndef NM_NBSD_H
-#define NM_NBSD_H
-
-/* Get generic NetBSD native definitions. */
-#include "config/nm-nbsd.h"
-
-#define REGISTER_U_ADDR(addr, blockend, regno) \
- (addr) = ns32k_register_u_addr ((blockend),(regno));
-
-extern int ns32k_register_u_addr (int, int);
-
-#endif /* NM_NBSD_H */
+++ /dev/null
-/* Native-dependent definitions for ns32k running NetBSD, for GDB.
- Copyright 1986, 1987, 1989, 1992, 1994, 2000, 2002
- 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. */
-
-#ifndef NM_NBSDAOUT_H
-#define NM_NBSDAOUT_H
-
-#include "ns32k/nm-nbsd.h"
-
-/* Get generic NetBSD native definitions. */
-#include "config/nm-nbsdaout.h"
-
-#endif /* NM_NBSDAOUT_H */
+++ /dev/null
-/* Definitions to make GDB run on an encore under umax 4.2
- Copyright 1987, 1989, 1991, 1993, 1994, 1998, 1999, 2000, 2001, 2002
- 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. */
-
-#ifndef TM_NS32K_H
-#define TM_NS32K_H
-
-/* Need to get function ends by adding this to epilogue address from .bf
- record, not using x_fsize field. */
-#define FUNCTION_EPILOGUE_SIZE 4
-
-/* Address of end of stack space. */
-
-#ifndef STACK_END_ADDR
-#define STACK_END_ADDR (0xfffff000)
-#endif
-
-#endif /* TM_NS32K_H */
+++ /dev/null
-# Target: NEC V850 processor
-TDEPFILES= v850-tdep.o
-SIM_OBS = remote-sim.o
-SIM = ../sim/v850/libsim.a
gdb_host=nbsd ;;
mips64*-*-openbsd*) gdb_host=obsd64 ;;
-ns32k-*-netbsd*) gdb_host=nbsdaout ;;
-
powerpc-*-aix*) gdb_host=aix ;;
powerpc-*-linux*) gdb_host=linux ;;
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
sh*) gdb_target_cpu=sh ;;
strongarm*) gdb_target_cpu=arm ;;
xscale*) gdb_target_cpu=arm ;;
-v850*) gdb_target_cpu=v850 ;;
x86_64*) gdb_target_cpu=i386 ;;
*) gdb_target_cpu=$target_cpu ;;
# OBSOLETE d10v-*-*) gdb_target=d10v ;;
-h8300-*-*) gdb_target=h8300 ;;
-
-
frv-*-*) gdb_target=frv ;;
hppa*64*-*-hpux11*) gdb_target=hppa64 ;;
m88*-*-openbsd*) gdb_target=obsd ;;
-mcore*-*-*) gdb_target=mcore ;;
-
mips*-*-pe) gdb_target=wince ;;
mips*-sgi-irix5*) gdb_target=irix5 ;;
mips*-sgi-irix6*) gdb_target=irix6 ;;
mips64*-*-openbsd*) gdb_target=obsd64 ;;
mips*-*-*) gdb_target=embed ;;
-mn10300-*-*) gdb_target=mn10300 ;;
-
-ns32k-*-netbsd*) gdb_target=nbsdaout ;;
-
powerpc-*-netbsd* | powerpc-*-knetbsd*-gnu)
gdb_target=nbsd ;;
powerpc-*-openbsd*) gdb_target=obsd ;;
vax-*-openbsd*) gdb_target=nbsd ;;
vax-*-*) gdb_target=vax ;;
-v850*-*-*) gdb_target=v850
- case ${gdb_host} in
- cygwin*)
- CONFIG_OBS="${CONFIG_OBS} v850ice.o" ;;
- * ) ;;
- esac
- ;;
-
x86_64-*-linux*) gdb_target=linux64
build_gdbserver=yes
;;
+++ /dev/null
-/* Target-machine dependent code for Renesas H8/300, for GDB.
-
- Copyright 1988, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998,
- 1999, 2000, 2001, 2002, 2003 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. */
-
-/*
- Contributed by Steve Chamberlain
- sac@cygnus.com
- */
-
-#include "defs.h"
-#include "value.h"
-#include "inferior.h"
-#include "symfile.h"
-#include "arch-utils.h"
-#include "regcache.h"
-#include "gdbcore.h"
-#include "objfiles.h"
-#include "gdbcmd.h"
-#include "gdb_assert.h"
-#include "dis-asm.h"
-
-/* Extra info which is saved in each frame_info. */
-struct frame_extra_info
-{
- CORE_ADDR from_pc;
-};
-
-enum
-{
- h8300_reg_size = 2,
- h8300h_reg_size = 4,
- h8300_max_reg_size = 4,
-};
-
-static int is_h8300hmode (struct gdbarch *gdbarch);
-static int is_h8300smode (struct gdbarch *gdbarch);
-static int is_h8300sxmode (struct gdbarch *gdbarch);
-static int is_h8300_normal_mode (struct gdbarch *gdbarch);
-
-#define BINWORD (is_h8300hmode (current_gdbarch) && \
- !is_h8300_normal_mode (current_gdbarch) ? h8300h_reg_size : h8300_reg_size)
-
-enum gdb_regnum
-{
- E_R0_REGNUM, E_ER0_REGNUM = E_R0_REGNUM, E_ARG0_REGNUM = E_R0_REGNUM,
- E_RET0_REGNUM = E_R0_REGNUM,
- E_R1_REGNUM, E_ER1_REGNUM = E_R1_REGNUM, E_RET1_REGNUM = E_R1_REGNUM,
- E_R2_REGNUM, E_ER2_REGNUM = E_R2_REGNUM, E_ARGLAST_REGNUM = E_R2_REGNUM,
- E_R3_REGNUM, E_ER3_REGNUM = E_R3_REGNUM,
- E_R4_REGNUM, E_ER4_REGNUM = E_R4_REGNUM,
- E_R5_REGNUM, E_ER5_REGNUM = E_R5_REGNUM,
- E_R6_REGNUM, E_ER6_REGNUM = E_R6_REGNUM, E_FP_REGNUM = E_R6_REGNUM,
- E_SP_REGNUM,
- E_CCR_REGNUM,
- E_PC_REGNUM,
- E_CYCLES_REGNUM,
- E_TICK_REGNUM, E_EXR_REGNUM = E_TICK_REGNUM,
- E_INST_REGNUM, E_TICKS_REGNUM = E_INST_REGNUM,
- E_INSTS_REGNUM,
- E_MACH_REGNUM,
- E_MACL_REGNUM,
- E_SBR_REGNUM,
- E_VBR_REGNUM
-};
-
-#define E_PSEUDO_CCR_REGNUM (NUM_REGS)
-#define E_PSEUDO_EXR_REGNUM (NUM_REGS+1)
-
-#define UNSIGNED_SHORT(X) ((X) & 0xffff)
-
-#define IS_PUSH(x) ((x & 0xfff0)==0x6df0)
-#define IS_PUSH_FP(x) (x == 0x6df6)
-#define IS_MOVE_FP(x) (x == 0x0d76 || x == 0x0ff6)
-#define IS_MOV_SP_FP(x) (x == 0x0d76 || x == 0x0ff6)
-#define IS_SUB2_SP(x) (x==0x1b87)
-#define IS_SUB4_SP(x) (x==0x1b97)
-#define IS_SUBL_SP(x) (x==0x7a37)
-#define IS_MOVK_R5(x) (x==0x7905)
-#define IS_SUB_R5SP(x) (x==0x1957)
-
-/* If the instruction at PC is an argument register spill, return its
- length. Otherwise, return zero.
-
- An argument register spill is an instruction that moves an argument
- from the register in which it was passed to the stack slot in which
- it really lives. It is a byte, word, or longword move from an
- argument register to a negative offset from the frame pointer.
-
- CV, 2003-06-16: Or, in optimized code or when the `register' qualifier
- is used, it could be a byte, word or long move to registers r3-r5. */
-
-static int
-h8300_is_argument_spill (CORE_ADDR pc)
-{
- int w = read_memory_unsigned_integer (pc, 2);
-
- if (((w & 0xff88) == 0x0c88 /* mov.b Rsl, Rdl */
- || (w & 0xff88) == 0x0d00 /* mov.w Rs, Rd */
- || (w & 0xff88) == 0x0f80) /* mov.l Rs, Rd */
- && (w & 0x70) <= 0x20 /* Rs is R0, R1 or R2 */
- && (w & 0x7) >= 0x3 && (w & 0x7) <= 0x5)/* Rd is R3, R4 or R5 */
- return 2;
-
- if ((w & 0xfff0) == 0x6ee0 /* mov.b Rs,@(d:16,er6) */
- && 8 <= (w & 0xf) && (w & 0xf) <= 10) /* Rs is R0L, R1L, or R2L */
- {
- int w2 = read_memory_integer (pc + 2, 2);
-
- /* ... and d:16 is negative. */
- if (w2 < 0)
- return 4;
- }
- else if (w == 0x7860)
- {
- int w2 = read_memory_integer (pc + 2, 2);
-
- if ((w2 & 0xfff0) == 0x6aa0) /* mov.b Rs, @(d:24,er6) */
- {
- LONGEST disp = read_memory_integer (pc + 4, 4);
-
- /* ... and d:24 is negative. */
- if (disp < 0 && disp > 0xffffff)
- return 8;
- }
- }
- else if ((w & 0xfff0) == 0x6fe0 /* mov.w Rs,@(d:16,er6) */
- && (w & 0xf) <= 2) /* Rs is R0, R1, or R2 */
- {
- int w2 = read_memory_integer (pc + 2, 2);
-
- /* ... and d:16 is negative. */
- if (w2 < 0)
- return 4;
- }
- else if (w == 0x78e0)
- {
- int w2 = read_memory_integer (pc + 2, 2);
-
- if ((w2 & 0xfff0) == 0x6ba0) /* mov.b Rs, @(d:24,er6) */
- {
- LONGEST disp = read_memory_integer (pc + 4, 4);
-
- /* ... and d:24 is negative. */
- if (disp < 0 && disp > 0xffffff)
- return 8;
- }
- }
- else if (w == 0x0100)
- {
- int w2 = read_memory_integer (pc + 2, 2);
-
- if ((w2 & 0xfff0) == 0x6fe0 /* mov.l Rs,@(d:16,er6) */
- && (w2 & 0xf) <= 2) /* Rs is ER0, ER1, or ER2 */
- {
- int w3 = read_memory_integer (pc + 4, 2);
-
- /* ... and d:16 is negative. */
- if (w3 < 0)
- return 6;
- }
- else if (w2 == 0x78e0)
- {
- int w3 = read_memory_integer (pc + 4, 2);
-
- if ((w3 & 0xfff0) == 0x6ba0) /* mov.l Rs, @(d:24,er6) */
- {
- LONGEST disp = read_memory_integer (pc + 6, 4);
-
- /* ... and d:24 is negative. */
- if (disp < 0 && disp > 0xffffff)
- return 10;
- }
- }
- }
-
- return 0;
-}
-
-static CORE_ADDR
-h8300_skip_prologue (CORE_ADDR start_pc)
-{
- short int w;
- int adjust = 0;
-
- /* Skip past all push and stm insns. */
- while (1)
- {
- w = read_memory_unsigned_integer (start_pc, 2);
- /* First look for push insns. */
- if (w == 0x0100 || w == 0x0110 || w == 0x0120 || w == 0x0130)
- {
- w = read_memory_unsigned_integer (start_pc + 2, 2);
- adjust = 2;
- }
-
- if (IS_PUSH (w))
- {
- start_pc += 2 + adjust;
- w = read_memory_unsigned_integer (start_pc, 2);
- continue;
- }
- adjust = 0;
- break;
- }
-
- /* Skip past a move to FP, either word or long sized */
- w = read_memory_unsigned_integer (start_pc, 2);
- if (w == 0x0100)
- {
- w = read_memory_unsigned_integer (start_pc + 2, 2);
- adjust += 2;
- }
-
- if (IS_MOVE_FP (w))
- {
- start_pc += 2 + adjust;
- w = read_memory_unsigned_integer (start_pc, 2);
- }
-
- /* Check for loading either a word constant into r5;
- long versions are handled by the SUBL_SP below. */
- if (IS_MOVK_R5 (w))
- {
- start_pc += 2;
- w = read_memory_unsigned_integer (start_pc, 2);
- }
-
- /* Now check for subtracting r5 from sp, word sized only. */
- if (IS_SUB_R5SP (w))
- {
- start_pc += 2 + adjust;
- w = read_memory_unsigned_integer (start_pc, 2);
- }
-
- /* Check for subs #2 and subs #4. */
- while (IS_SUB2_SP (w) || IS_SUB4_SP (w))
- {
- start_pc += 2 + adjust;
- w = read_memory_unsigned_integer (start_pc, 2);
- }
-
- /* Check for a 32bit subtract. */
- if (IS_SUBL_SP (w))
- start_pc += 6 + adjust;
-
- /* Skip past another possible stm insn for registers R3 to R5 (possibly used
- for register qualified arguments. */
- w = read_memory_unsigned_integer (start_pc, 2);
- /* First look for push insns. */
- if (w == 0x0110 || w == 0x0120 || w == 0x0130)
- {
- w = read_memory_unsigned_integer (start_pc + 2, 2);
- if (IS_PUSH (w) && (w & 0xf) >= 0x3 && (w & 0xf) <= 0x5)
- start_pc += 4;
- }
-
- /* Check for spilling an argument register to the stack frame.
- This could also be an initializing store from non-prologue code,
- but I don't think there's any harm in skipping that. */
- for (;;)
- {
- int spill_size = h8300_is_argument_spill (start_pc);
- if (spill_size == 0)
- break;
- start_pc += spill_size;
- }
-
- return start_pc;
-}
-
-/* Fetch the instruction at ADDR, returning 0 if ADDR is beyond LIM or
- is not the address of a valid instruction, the address of the next
- instruction beyond ADDR otherwise. *PWORD1 receives the first word
- of the instruction. */
-
-static CORE_ADDR
-h8300_next_prologue_insn (CORE_ADDR addr,
- CORE_ADDR lim,
- unsigned short* pword1)
-{
- char buf[2];
- if (addr < lim + 8)
- {
- read_memory (addr, buf, 2);
- *pword1 = extract_signed_integer (buf, 2);
-
- return addr + 2;
- }
- return 0;
-}
-
-/* Examine the prologue of a function. `ip' points to the first instruction.
- `limit' is the limit of the prologue (e.g. the addr of the first
- linenumber, or perhaps the program counter if we're stepping through).
- `frame_sp' is the stack pointer value in use in this frame.
- `fsr' is a pointer to a frame_saved_regs structure into which we put
- info about the registers saved by this frame.
- `fi' is a struct frame_info pointer; we fill in various fields in it
- to reflect the offsets of the arg pointer and the locals pointer. */
-
-/* Any function with a frame looks like this
- SECOND ARG
- FIRST ARG
- RET PC
- SAVED R2
- SAVED R3
- SAVED FP <-FP POINTS HERE
- LOCALS0
- LOCALS1 <-SP POINTS HERE
- */
-
-static CORE_ADDR
-h8300_examine_prologue (CORE_ADDR ip, CORE_ADDR limit,
- CORE_ADDR after_prolog_fp, CORE_ADDR *fsr,
- struct frame_info *fi)
-{
- CORE_ADDR next_ip;
- int r;
- int have_fp = 0;
- unsigned short insn_word;
- /* Number of things pushed onto stack, starts at 2/4, 'cause the
- PC is already there */
- unsigned int reg_save_depth = BINWORD;
-
- unsigned int auto_depth = 0; /* Number of bytes of autos */
-
- char in_frame[11]; /* One for each reg */
-
- int adjust = 0;
-
- memset (in_frame, 1, 11);
- for (r = 0; r < 8; r++)
- {
- fsr[r] = 0;
- }
- if (after_prolog_fp == 0)
- {
- after_prolog_fp = read_register (E_SP_REGNUM);
- }
-
- /* If the PC isn't valid, quit now. */
- if (ip == 0 || ip & (is_h8300hmode (current_gdbarch) &&
- !is_h8300_normal_mode (current_gdbarch) ? ~0xffffff : ~0xffff))
- return 0;
-
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
-
- if (insn_word == 0x0100) /* mov.l */
- {
- insn_word = read_memory_unsigned_integer (ip + 2, 2);
- adjust = 2;
- }
-
- /* Skip over any fp push instructions */
- fsr[E_FP_REGNUM] = after_prolog_fp;
- while (next_ip && IS_PUSH_FP (insn_word))
- {
- ip = next_ip + adjust;
-
- in_frame[insn_word & 0x7] = reg_save_depth;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- reg_save_depth += 2 + adjust;
- }
-
- /* Is this a move into the fp */
- if (next_ip && IS_MOV_SP_FP (insn_word))
- {
- ip = next_ip;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- have_fp = 1;
- }
-
- /* Skip over any stack adjustment, happens either with a number of
- sub#2,sp or a mov #x,r5 sub r5,sp */
-
- if (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
- {
- while (next_ip && (IS_SUB2_SP (insn_word) || IS_SUB4_SP (insn_word)))
- {
- auto_depth += IS_SUB2_SP (insn_word) ? 2 : 4;
- ip = next_ip;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- }
- }
- else
- {
- if (next_ip && IS_MOVK_R5 (insn_word))
- {
- ip = next_ip;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- auto_depth += insn_word;
-
- next_ip = h8300_next_prologue_insn (next_ip, limit, &insn_word);
- auto_depth += insn_word;
- }
- if (next_ip && IS_SUBL_SP (insn_word))
- {
- ip = next_ip;
- auto_depth += read_memory_unsigned_integer (ip, 4);
- ip += 4;
-
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- }
- }
-
- /* Now examine the push insns to determine where everything lives
- on the stack. */
- while (1)
- {
- adjust = 0;
- if (!next_ip)
- break;
-
- if (insn_word == 0x0100)
- {
- ip = next_ip;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- adjust = 2;
- }
-
- if (IS_PUSH (insn_word))
- {
- auto_depth += 2 + adjust;
- fsr[insn_word & 0x7] = after_prolog_fp - auto_depth;
- ip = next_ip;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- continue;
- }
-
- /* Now check for push multiple insns. */
- if (insn_word == 0x0110 || insn_word == 0x0120 || insn_word == 0x0130)
- {
- int count = ((insn_word >> 4) & 0xf) + 1;
- int start, i;
-
- ip = next_ip;
- next_ip = h8300_next_prologue_insn (ip, limit, &insn_word);
- start = insn_word & 0x7;
-
- for (i = start; i < start + count; i++)
- {
- auto_depth += 4;
- fsr[i] = after_prolog_fp - auto_depth;
- }
- }
- break;
- }
-
- /* The PC is at a known place */
- get_frame_extra_info (fi)->from_pc =
- read_memory_unsigned_integer (after_prolog_fp + BINWORD, BINWORD);
-
- /* Rememeber any others too */
- in_frame[E_PC_REGNUM] = 0;
-
- if (have_fp)
- /* We keep the old FP in the SP spot */
- fsr[E_SP_REGNUM] = read_memory_unsigned_integer (fsr[E_FP_REGNUM],
- BINWORD);
- else
- fsr[E_SP_REGNUM] = after_prolog_fp + auto_depth;
-
- return (ip);
-}
-
-static void
-h8300_frame_init_saved_regs (struct frame_info *fi)
-{
- CORE_ADDR func_addr, func_end;
-
- if (!deprecated_get_frame_saved_regs (fi))
- {
- frame_saved_regs_zalloc (fi);
-
- /* Find the beginning of this function, so we can analyze its
- prologue. */
- if (find_pc_partial_function (get_frame_pc (fi), NULL,
- &func_addr, &func_end))
- {
- struct symtab_and_line sal = find_pc_line (func_addr, 0);
- CORE_ADDR limit = (sal.end && sal.end < get_frame_pc (fi))
- ? sal.end : get_frame_pc (fi);
- /* This will fill in fields in fi. */
- h8300_examine_prologue (func_addr, limit, get_frame_base (fi),
- deprecated_get_frame_saved_regs (fi), fi);
- }
- /* Else we're out of luck (can't debug completely stripped code).
- FIXME. */
- }
-}
-
-/* Given a GDB frame, determine the address of the calling function's
- frame. This will be used to create a new GDB frame struct, and
- then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC
- will be called for the new frame.
-
- For us, the frame address is its stack pointer value, so we look up
- the function prologue to determine the caller's sp value, and
- return it. */
-
-static CORE_ADDR
-h8300_frame_chain (struct frame_info *thisframe)
-{
- if (deprecated_pc_in_call_dummy (get_frame_pc (thisframe)))
- { /* initialize the from_pc now */
- get_frame_extra_info (thisframe)->from_pc =
- deprecated_read_register_dummy (get_frame_pc (thisframe),
- get_frame_base (thisframe),
- E_PC_REGNUM);
- return get_frame_base (thisframe);
- }
- return deprecated_get_frame_saved_regs (thisframe)[E_SP_REGNUM];
-}
-
-/* Return the saved PC from this frame.
-
- If the frame has a memory copy of SRP_REGNUM, use that. If not,
- just use the register SRP_REGNUM itself. */
-
-static CORE_ADDR
-h8300_frame_saved_pc (struct frame_info *frame)
-{
- if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
- return deprecated_read_register_dummy (get_frame_pc (frame),
- get_frame_base (frame),
- E_PC_REGNUM);
- else
- return get_frame_extra_info (frame)->from_pc;
-}
-
-static void
-h8300_init_extra_frame_info (int fromleaf, struct frame_info *fi)
-{
- if (!get_frame_extra_info (fi))
- {
- frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
- get_frame_extra_info (fi)->from_pc = 0;
-
- if (!get_frame_pc (fi))
- {
- if (get_next_frame (fi))
- deprecated_update_frame_pc_hack (fi, h8300_frame_saved_pc (get_next_frame (fi)));
- }
- h8300_frame_init_saved_regs (fi);
- }
-}
-
-/* Function: push_dummy_call
- Setup the function arguments for calling a function in the inferior.
- In this discussion, a `word' is 16 bits on the H8/300s, and 32 bits
- on the H8/300H.
-
- There are actually two ABI's here: -mquickcall (the default) and
- -mno-quickcall. With -mno-quickcall, all arguments are passed on
- the stack after the return address, word-aligned. With
- -mquickcall, GCC tries to use r0 -- r2 to pass registers. Since
- GCC doesn't indicate in the object file which ABI was used to
- compile it, GDB only supports the default --- -mquickcall.
-
- Here are the rules for -mquickcall, in detail:
-
- Each argument, whether scalar or aggregate, is padded to occupy a
- whole number of words. Arguments smaller than a word are padded at
- the most significant end; those larger than a word are padded at
- the least significant end.
-
- The initial arguments are passed in r0 -- r2. Earlier arguments go in
- lower-numbered registers. Multi-word arguments are passed in
- consecutive registers, with the most significant end in the
- lower-numbered register.
-
- If an argument doesn't fit entirely in the remaining registers, it
- is passed entirely on the stack. Stack arguments begin just after
- the return address. Once an argument has overflowed onto the stack
- this way, all subsequent arguments are passed on the stack.
-
- The above rule has odd consequences. For example, on the h8/300s,
- if a function takes two longs and an int as arguments:
- - the first long will be passed in r0/r1,
- - the second long will be passed entirely on the stack, since it
- doesn't fit in r2,
- - and the int will be passed on the stack, even though it could fit
- in r2.
-
- A weird exception: if an argument is larger than a word, but not a
- whole number of words in length (before padding), it is passed on
- the stack following the rules for stack arguments above, even if
- there are sufficient registers available to hold it. Stranger
- still, the argument registers are still `used up' --- even though
- there's nothing in them.
-
- So, for example, on the h8/300s, if a function expects a three-byte
- structure and an int, the structure will go on the stack, and the
- int will go in r2, not r0.
-
- If the function returns an aggregate type (struct, union, or class)
- by value, the caller must allocate space to hold the return value,
- and pass the callee a pointer to this space as an invisible first
- argument, in R0.
-
- For varargs functions, the last fixed argument and all the variable
- arguments are always passed on the stack. This means that calls to
- varargs functions don't work properly unless there is a prototype
- in scope.
-
- Basically, this ABI is not good, for the following reasons:
- - You can't call vararg functions properly unless a prototype is in scope.
- - Structure passing is inconsistent, to no purpose I can see.
- - It often wastes argument registers, of which there are only three
- to begin with. */
-
-static CORE_ADDR
-h8300_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
- struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
- struct value **args, CORE_ADDR sp, int struct_return,
- CORE_ADDR struct_addr)
-{
- int stack_alloc = 0, stack_offset = 0;
- int wordsize = BINWORD;
- int reg = E_ARG0_REGNUM;
- int argument;
-
- /* First, make sure the stack is properly aligned. */
- sp = align_down (sp, wordsize);
-
- /* Now make sure there's space on the stack for the arguments. We
- may over-allocate a little here, but that won't hurt anything. */
- for (argument = 0; argument < nargs; argument++)
- stack_alloc += align_up (TYPE_LENGTH (value_type (args[argument])),
- wordsize);
- sp -= stack_alloc;
-
- /* Now load as many arguments as possible into registers, and push
- the rest onto the stack.
- If we're returning a structure by value, then we must pass a
- pointer to the buffer for the return value as an invisible first
- argument. */
- if (struct_return)
- regcache_cooked_write_unsigned (regcache, reg++, struct_addr);
-
- for (argument = 0; argument < nargs; argument++)
- {
- struct type *type = value_type (args[argument]);
- int len = TYPE_LENGTH (type);
- char *contents = (char *) VALUE_CONTENTS (args[argument]);
-
- /* Pad the argument appropriately. */
- int padded_len = align_up (len, wordsize);
- char *padded = alloca (padded_len);
-
- memset (padded, 0, padded_len);
- memcpy (len < wordsize ? padded + padded_len - len : padded,
- contents, len);
-
- /* Could the argument fit in the remaining registers? */
- if (padded_len <= (E_ARGLAST_REGNUM - reg + 1) * wordsize)
- {
- /* Are we going to pass it on the stack anyway, for no good
- reason? */
- if (len > wordsize && len % wordsize)
- {
- /* I feel so unclean. */
- write_memory (sp + stack_offset, padded, padded_len);
- stack_offset += padded_len;
-
- /* That's right --- even though we passed the argument
- on the stack, we consume the registers anyway! Love
- me, love my dog. */
- reg += padded_len / wordsize;
- }
- else
- {
- /* Heavens to Betsy --- it's really going in registers!
- It would be nice if we could use write_register_bytes
- here, but on the h8/300s, there are gaps between
- the registers in the register file. */
- int offset;
-
- for (offset = 0; offset < padded_len; offset += wordsize)
- {
- ULONGEST word = extract_unsigned_integer (padded + offset,
- wordsize);
- regcache_cooked_write_unsigned (regcache, reg++, word);
- }
- }
- }
- else
- {
- /* It doesn't fit in registers! Onto the stack it goes. */
- write_memory (sp + stack_offset, padded, padded_len);
- stack_offset += padded_len;
-
- /* Once one argument has spilled onto the stack, all
- subsequent arguments go on the stack. */
- reg = E_ARGLAST_REGNUM + 1;
- }
- }
-
- /* Store return address. */
- sp -= wordsize;
- write_memory_unsigned_integer (sp, wordsize, bp_addr);
-
- /* Update stack pointer. */
- regcache_cooked_write_unsigned (regcache, E_SP_REGNUM, sp);
-
- return sp;
-}
-
-/* Function: h8300_pop_frame
- Restore the machine to the state it had before the current frame
- was created. Usually used either by the "RETURN" command, or by
- call_function_by_hand after the dummy_frame is finished. */
-
-static void
-h8300_pop_frame (void)
-{
- unsigned regno;
- struct frame_info *frame = get_current_frame ();
-
- if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
- {
- deprecated_pop_dummy_frame ();
- }
- else
- {
- for (regno = 0; regno < 8; regno++)
- {
- /* Don't forget E_SP_REGNUM is a frame_saved_regs struct is the
- actual value we want, not the address of the value we want. */
- if (deprecated_get_frame_saved_regs (frame)[regno] && regno != E_SP_REGNUM)
- write_register (regno,
- read_memory_integer
- (deprecated_get_frame_saved_regs (frame)[regno], BINWORD));
- else if (deprecated_get_frame_saved_regs (frame)[regno] && regno == E_SP_REGNUM)
- write_register (regno, get_frame_base (frame) + 2 * BINWORD);
- }
-
- /* Don't forget to update the PC too! */
- write_register (E_PC_REGNUM, get_frame_extra_info (frame)->from_pc);
- }
- flush_cached_frames ();
-}
-
-/* Function: extract_return_value
- Figure out where in REGBUF the called function has left its return value.
- Copy that into VALBUF. Be sure to account for CPU type. */
-
-static void
-h8300_extract_return_value (struct type *type, struct regcache *regcache,
- void *valbuf)
-{
- int len = TYPE_LENGTH (type);
- ULONGEST c, addr;
-
- switch (len)
- {
- case 1:
- case 2:
- regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
- store_unsigned_integer (valbuf, len, c);
- break;
- case 4: /* Needs two registers on plain H8/300 */
- regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
- store_unsigned_integer (valbuf, 2, c);
- regcache_cooked_read_unsigned (regcache, E_RET1_REGNUM, &c);
- store_unsigned_integer ((void*)((char *)valbuf + 2), 2, c);
- break;
- case 8: /* long long is now 8 bytes. */
- if (TYPE_CODE (type) == TYPE_CODE_INT)
- {
- regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
- c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
- store_unsigned_integer (valbuf, len, c);
- }
- else
- {
- error ("I don't know how this 8 byte value is returned.");
- }
- break;
- }
-}
-
-static void
-h8300h_extract_return_value (struct type *type, struct regcache *regcache,
- void *valbuf)
-{
- int len = TYPE_LENGTH (type);
- ULONGEST c, addr;
-
- switch (len)
- {
- case 1:
- case 2:
- case 4:
- regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &c);
- store_unsigned_integer (valbuf, len, c);
- break;
- case 8: /* long long is now 8 bytes. */
- if (TYPE_CODE (type) == TYPE_CODE_INT)
- {
- regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
- c = read_memory_unsigned_integer ((CORE_ADDR) addr, len);
- store_unsigned_integer (valbuf, len, c);
- }
- else
- {
- error ("I don't know how this 8 byte value is returned.");
- }
- break;
- }
-}
-
-
-/* Function: store_return_value
- Place the appropriate value in the appropriate registers.
- Primarily used by the RETURN command. */
-
-static void
-h8300_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
-{
- int len = TYPE_LENGTH (type);
- ULONGEST val;
-
- switch (len)
- {
- case 1:
- case 2: /* short... */
- val = extract_unsigned_integer (valbuf, len);
- regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
- break;
- case 4: /* long, float */
- val = extract_unsigned_integer (valbuf, len);
- regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM,
- (val >> 16) &0xffff);
- regcache_cooked_write_unsigned (regcache, E_RET1_REGNUM, val & 0xffff);
- break;
- case 8: /* long long, double and long double are all defined
- as 4 byte types so far so this shouldn't happen. */
- error ("I don't know how to return an 8 byte value.");
- break;
- }
-}
-
-static void
-h8300h_store_return_value (struct type *type, struct regcache *regcache,
- const void *valbuf)
-{
- int len = TYPE_LENGTH (type);
- ULONGEST val;
-
- switch (len)
- {
- case 1:
- case 2:
- case 4: /* long, float */
- val = extract_unsigned_integer (valbuf, len);
- regcache_cooked_write_unsigned (regcache, E_RET0_REGNUM, val);
- break;
- case 8: /* long long, double and long double are all defined
- as 4 byte types so far so this shouldn't happen. */
- error ("I don't know how to return an 8 byte value.");
- break;
- }
-}
-
-static struct cmd_list_element *setmachinelist;
-
-static const char *
-h8300_register_name (int regno)
-{
- /* The register names change depending on which h8300 processor
- type is selected. */
- static char *register_names[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6",
- "sp", "","pc","cycles", "tick", "inst",
- "ccr", /* pseudo register */
- };
- if (regno < 0
- || regno >= (sizeof (register_names) / sizeof (*register_names)))
- internal_error (__FILE__, __LINE__,
- "h8300_register_name: illegal register number %d", regno);
- else
- return register_names[regno];
-}
-
-static const char *
-h8300s_register_name (int regno)
-{
- static char *register_names[] = {
- "er0", "er1", "er2", "er3", "er4", "er5", "er6",
- "sp", "", "pc", "cycles", "", "tick", "inst",
- "mach", "macl",
- "ccr", "exr" /* pseudo registers */
- };
- if (regno < 0
- || regno >= (sizeof (register_names) / sizeof (*register_names)))
- internal_error (__FILE__, __LINE__,
- "h8300s_register_name: illegal register number %d", regno);
- else
- return register_names[regno];
-}
-
-static const char *
-h8300sx_register_name (int regno)
-{
- static char *register_names[] = {
- "er0", "er1", "er2", "er3", "er4", "er5", "er6",
- "sp", "", "pc", "cycles", "", "tick", "inst",
- "mach", "macl", "sbr", "vbr",
- "ccr", "exr" /* pseudo registers */
- };
- if (regno < 0
- || regno >= (sizeof (register_names) / sizeof (*register_names)))
- internal_error (__FILE__, __LINE__,
- "h8300sx_register_name: illegal register number %d", regno);
- else
- return register_names[regno];
-}
-
-static void
-h8300_print_register (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regno)
-{
- LONGEST rval;
- const char *name = gdbarch_register_name (gdbarch, regno);
-
- if (!name || !*name)
- return;
-
- rval = get_frame_register_signed (frame, regno);
-
- fprintf_filtered (file, "%-14s ", name);
- if (regno == E_PSEUDO_CCR_REGNUM ||
- (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch)))
- {
- fprintf_filtered (file, "0x%02x ", (unsigned char)rval);
- print_longest (file, 'u', 1, rval);
- }
- else
- {
- fprintf_filtered (file, "0x%s ", phex ((ULONGEST)rval, BINWORD));
- print_longest (file, 'd', 1, rval);
- }
- if (regno == E_PSEUDO_CCR_REGNUM)
- {
- /* CCR register */
- int C, Z, N, V;
- unsigned char l = rval & 0xff;
- fprintf_filtered (file, "\t");
- fprintf_filtered (file, "I-%d ", (l & 0x80) != 0);
- fprintf_filtered (file, "UI-%d ", (l & 0x40) != 0);
- fprintf_filtered (file, "H-%d ", (l & 0x20) != 0);
- fprintf_filtered (file, "U-%d ", (l & 0x10) != 0);
- N = (l & 0x8) != 0;
- Z = (l & 0x4) != 0;
- V = (l & 0x2) != 0;
- C = (l & 0x1) != 0;
- fprintf_filtered (file, "N-%d ", N);
- fprintf_filtered (file, "Z-%d ", Z);
- fprintf_filtered (file, "V-%d ", V);
- fprintf_filtered (file, "C-%d ", C);
- if ((C | Z) == 0)
- fprintf_filtered (file, "u> ");
- if ((C | Z) == 1)
- fprintf_filtered (file, "u<= ");
- if ((C == 0))
- fprintf_filtered (file, "u>= ");
- if (C == 1)
- fprintf_filtered (file, "u< ");
- if (Z == 0)
- fprintf_filtered (file, "!= ");
- if (Z == 1)
- fprintf_filtered (file, "== ");
- if ((N ^ V) == 0)
- fprintf_filtered (file, ">= ");
- if ((N ^ V) == 1)
- fprintf_filtered (file, "< ");
- if ((Z | (N ^ V)) == 0)
- fprintf_filtered (file, "> ");
- if ((Z | (N ^ V)) == 1)
- fprintf_filtered (file, "<= ");
- }
- else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
- {
- /* EXR register */
- unsigned char l = rval & 0xff;
- fprintf_filtered (file, "\t");
- fprintf_filtered (file, "T-%d - - - ", (l & 0x80) != 0);
- fprintf_filtered (file, "I2-%d ", (l & 4) != 0);
- fprintf_filtered (file, "I1-%d ", (l & 2) != 0);
- fprintf_filtered (file, "I0-%d", (l & 1) != 0);
- }
- fprintf_filtered (file, "\n");
-}
-
-static void
-h8300_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, int regno, int cpregs)
-{
- if (regno < 0)
- {
- for (regno = E_R0_REGNUM; regno <= E_SP_REGNUM; ++regno)
- h8300_print_register (gdbarch, file, frame, regno);
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_PC_REGNUM);
- if (is_h8300smode (current_gdbarch))
- {
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
- if (is_h8300sxmode (current_gdbarch))
- {
- h8300_print_register (gdbarch, file, frame, E_SBR_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_VBR_REGNUM);
- }
- h8300_print_register (gdbarch, file, frame, E_MACH_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_MACL_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_TICKS_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_INSTS_REGNUM);
- }
- else
- {
- h8300_print_register (gdbarch, file, frame, E_CYCLES_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_TICK_REGNUM);
- h8300_print_register (gdbarch, file, frame, E_INST_REGNUM);
- }
- }
- else
- {
- if (regno == E_CCR_REGNUM)
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_CCR_REGNUM);
- else if (regno == E_PSEUDO_EXR_REGNUM && is_h8300smode (current_gdbarch))
- h8300_print_register (gdbarch, file, frame, E_PSEUDO_EXR_REGNUM);
- else
- h8300_print_register (gdbarch, file, frame, regno);
- }
-}
-
-static CORE_ADDR
-h8300_saved_pc_after_call (struct frame_info *ignore)
-{
- return read_memory_unsigned_integer (read_register (E_SP_REGNUM), BINWORD);
-}
-
-static struct type *
-h8300_register_type (struct gdbarch *gdbarch, int regno)
-{
- if (regno < 0 || regno >= NUM_REGS + NUM_PSEUDO_REGS)
- internal_error (__FILE__, __LINE__,
- "h8300_register_type: illegal register number %d",
- regno);
- else
- {
- switch (regno)
- {
- case E_PC_REGNUM:
- return builtin_type_void_func_ptr;
- case E_SP_REGNUM:
- case E_FP_REGNUM:
- return builtin_type_void_data_ptr;
- default:
- if (regno == E_PSEUDO_CCR_REGNUM)
- return builtin_type_uint8;
- else if (regno == E_PSEUDO_EXR_REGNUM)
- return builtin_type_uint8;
- else if (is_h8300hmode (current_gdbarch))
- return builtin_type_int32;
- else
- return builtin_type_int16;
- }
- }
-}
-
-static void
-h8300_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
- int regno, void *buf)
-{
- if (regno == E_PSEUDO_CCR_REGNUM)
- regcache_raw_read (regcache, E_CCR_REGNUM, buf);
- else if (regno == E_PSEUDO_EXR_REGNUM)
- regcache_raw_read (regcache, E_EXR_REGNUM, buf);
- else
- regcache_raw_read (regcache, regno, buf);
-}
-
-static void
-h8300_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
- int regno, const void *buf)
-{
- if (regno == E_PSEUDO_CCR_REGNUM)
- regcache_raw_write (regcache, E_CCR_REGNUM, buf);
- else if (regno == E_PSEUDO_EXR_REGNUM)
- regcache_raw_write (regcache, E_EXR_REGNUM, buf);
- else
- regcache_raw_write (regcache, regno, buf);
-}
-
-static int
-h8300_dbg_reg_to_regnum (int regno)
-{
- if (regno == E_CCR_REGNUM)
- return E_PSEUDO_CCR_REGNUM;
- return regno;
-}
-
-static int
-h8300s_dbg_reg_to_regnum (int regno)
-{
- if (regno == E_CCR_REGNUM)
- return E_PSEUDO_CCR_REGNUM;
- if (regno == E_EXR_REGNUM)
- return E_PSEUDO_EXR_REGNUM;
- return regno;
-}
-
-static CORE_ADDR
-h8300_extract_struct_value_address (struct regcache *regcache)
-{
- ULONGEST addr;
- regcache_cooked_read_unsigned (regcache, E_RET0_REGNUM, &addr);
- return addr;
-}
-
-const static unsigned char *
-h8300_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
-{
- /*static unsigned char breakpoint[] = { 0x7A, 0xFF };*/ /* ??? */
- static unsigned char breakpoint[] = { 0x01, 0x80 }; /* Sleep */
-
- *lenptr = sizeof (breakpoint);
- return breakpoint;
-}
-
-static CORE_ADDR
-h8300_push_dummy_code (struct gdbarch *gdbarch,
- CORE_ADDR sp, CORE_ADDR funaddr, int using_gcc,
- struct value **args, int nargs,
- struct type *value_type,
- CORE_ADDR *real_pc, CORE_ADDR *bp_addr)
-{
- /* Allocate space sufficient for a breakpoint. */
- sp = (sp - 2) & ~1;
- /* Store the address of that breakpoint */
- *bp_addr = sp;
- /* h8300 always starts the call at the callee's entry point. */
- *real_pc = funaddr;
- return sp;
-}
-
-static void
-h8300_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
- struct frame_info *frame, const char *args)
-{
- fprintf_filtered (file, "\
-No floating-point info available for this processor.\n");
-}
-
-static struct gdbarch *
-h8300_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-{
- struct gdbarch_tdep *tdep = NULL;
- struct gdbarch *gdbarch;
-
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
-#if 0
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
-#endif
-
- if (info.bfd_arch_info->arch != bfd_arch_h8300)
- return NULL;
-
- gdbarch = gdbarch_alloc (&info, 0);
-
- switch (info.bfd_arch_info->mach)
- {
- case bfd_mach_h8300:
- set_gdbarch_num_regs (gdbarch, 13);
- set_gdbarch_num_pseudo_regs (gdbarch, 1);
- set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_register_name (gdbarch, h8300_register_name);
- set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_extract_return_value (gdbarch, h8300_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, h8300_store_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300);
- break;
- case bfd_mach_h8300h:
- case bfd_mach_h8300hn:
- set_gdbarch_num_regs (gdbarch, 13);
- set_gdbarch_num_pseudo_regs (gdbarch, 1);
- set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_stab_reg_to_regnum (gdbarch, h8300_dbg_reg_to_regnum);
- set_gdbarch_register_name (gdbarch, h8300_register_name);
- if(info.bfd_arch_info->mach != bfd_mach_h8300hn)
- {
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- }
- else
- {
- set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- }
- set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300h);
- break;
- case bfd_mach_h8300s:
- case bfd_mach_h8300sn:
- set_gdbarch_num_regs (gdbarch, 16);
- set_gdbarch_num_pseudo_regs (gdbarch, 2);
- set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_register_name (gdbarch, h8300s_register_name);
- if(info.bfd_arch_info->mach != bfd_mach_h8300sn)
- {
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- }
- else
- {
- set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- }
- set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
- break;
- case bfd_mach_h8300sx:
- case bfd_mach_h8300sxn:
- set_gdbarch_num_regs (gdbarch, 18);
- set_gdbarch_num_pseudo_regs (gdbarch, 2);
- set_gdbarch_ecoff_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_dwarf_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_dwarf2_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_stab_reg_to_regnum (gdbarch, h8300s_dbg_reg_to_regnum);
- set_gdbarch_register_name (gdbarch, h8300sx_register_name);
- if(info.bfd_arch_info->mach != bfd_mach_h8300sxn)
- {
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- }
- else
- {
- set_gdbarch_ptr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- }
- set_gdbarch_extract_return_value (gdbarch, h8300h_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, h8300h_store_return_value);
- set_gdbarch_print_insn (gdbarch, print_insn_h8300s);
- break;
- }
-
- set_gdbarch_pseudo_register_read (gdbarch, h8300_pseudo_register_read);
- set_gdbarch_pseudo_register_write (gdbarch, h8300_pseudo_register_write);
-
- /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
- ready to unwind the PC first (see frame.c:get_prev_frame()). */
- set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
-
- /*
- * Basic register fields and methods.
- */
-
- set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
- set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
- set_gdbarch_register_type (gdbarch, h8300_register_type);
- set_gdbarch_print_registers_info (gdbarch, h8300_print_registers_info);
- set_gdbarch_print_float_info (gdbarch, h8300_print_float_info);
-
- /*
- * Frame Info
- */
- set_gdbarch_skip_prologue (gdbarch, h8300_skip_prologue);
-
- set_gdbarch_deprecated_frame_init_saved_regs (gdbarch,
- h8300_frame_init_saved_regs);
- set_gdbarch_deprecated_init_extra_frame_info (gdbarch,
- h8300_init_extra_frame_info);
- set_gdbarch_deprecated_frame_chain (gdbarch, h8300_frame_chain);
- set_gdbarch_deprecated_saved_pc_after_call (gdbarch,
- h8300_saved_pc_after_call);
- set_gdbarch_deprecated_frame_saved_pc (gdbarch, h8300_frame_saved_pc);
- set_gdbarch_deprecated_pop_frame (gdbarch, h8300_pop_frame);
-
- /*
- * Miscelany
- */
- /* Stack grows up. */
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-
- set_gdbarch_deprecated_extract_struct_value_address (gdbarch, h8300_extract_struct_value_address);
- set_gdbarch_deprecated_use_struct_convention (gdbarch, always_use_struct_convention);
- set_gdbarch_breakpoint_from_pc (gdbarch, h8300_breakpoint_from_pc);
- set_gdbarch_push_dummy_code (gdbarch, h8300_push_dummy_code);
- set_gdbarch_push_dummy_call (gdbarch, h8300_push_dummy_call);
-
- set_gdbarch_int_bit (gdbarch, 2 * TARGET_CHAR_BIT);
- set_gdbarch_long_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT);
- set_gdbarch_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_double_bit (gdbarch, 4 * TARGET_CHAR_BIT);
-
- set_gdbarch_believe_pcc_promotion (gdbarch, 1);
-
- /* Char is unsigned. */
- set_gdbarch_char_signed (gdbarch, 0);
-
- return gdbarch;
-}
-
-extern initialize_file_ftype _initialize_h8300_tdep; /* -Wmissing-prototypes */
-
-void
-_initialize_h8300_tdep (void)
-{
- register_gdbarch_init (bfd_arch_h8300, h8300_gdbarch_init);
-}
-
-static int
-is_h8300hmode (struct gdbarch *gdbarch)
-{
- return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300h
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
-}
-
-static int
-is_h8300smode (struct gdbarch *gdbarch)
-{
- return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300s
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn;
-}
-
-static int
-is_h8300sxmode (struct gdbarch *gdbarch)
-{
- return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sx
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn;
-}
-
-static int
-is_h8300_normal_mode (struct gdbarch *gdbarch)
-{
- return gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sxn
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300sn
- || gdbarch_bfd_arch_info (gdbarch)->mach == bfd_mach_h8300hn;
-}
-
+++ /dev/null
-/* Remote debugging interface to Motorola picobug monitor for gdb,
- the GNU debugger.
- Copyright 1999, 2000, 2001 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. */
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "target.h"
-#include "monitor.h"
-#include "gdb_string.h"
-#include "regcache.h"
-#include "serial.h"
-
-/* Functions used only in this file. */
-
-static void init_picobug_cmds (void);
-
-
-/* Functions exported from this file. */
-
-void _initialize_picobug_rom (void);
-
-void picobug_open (char *args, int from_tty);
-
-int picobug_dumpregs (void);
-
-
-static char *picobug_inits[] =
-{"\r", NULL};
-
-static struct target_ops picobug_ops;
-static struct monitor_ops picobug_cmds;
-
-/* Picobug only supports a subset of registers from MCore. In reality,
- it doesn't support ss1, either. */
-/* *INDENT-OFF* */
-static char *picobug_regnames[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- "psr", "vbr", "epsr", "fpsr", "epc", "fpc", 0, "ss1",
- "ss2", "ss3", "ss4", 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- "pc" };
-/* *INDENT-ON* */
-
-
-
-void
-picobug_open (char *args, int from_tty)
-{
- monitor_open (args, &picobug_cmds, from_tty);
-}
-/* *INDENT-OFF* */
-/* We choose to write our own dumpregs routine, since the output of
- the register dumping is rather difficult to encapsulate in a
- regexp:
-
-picobug> rd
- pc 2f00031e epc 2f00031e fpc 00000000
- psr 80000101 epsr 80000101 fpsr 00000000
-ss0-ss4 bad0beef 00000000 00000000 00000000 00000000 vbr 30005c00
- r0-r7 2f0fff4c 00000090 00000001 00000002 00000003 00000004 00000005 00000006
- r8-r15 2f0fff64 00000000 00000000 00000000 00000000 00000000 00000000 2f00031e */
-/* *INDENT-ON* */
-
-
-
-int
-picobug_dumpregs (void)
-{
- char buf[1024];
- int resp_len;
- char *p;
-
- /* Send the dump register command to the monitor and
- get the reply. */
- monitor_printf (picobug_cmds.dump_registers);
- resp_len = monitor_expect_prompt (buf, sizeof (buf));
-
- p = strtok (buf, " \t\r\n");
- while (p)
- {
- if (strchr (p, '-'))
- {
- /* got a range. either r0-r7, r8-r15 or ss0-ss4 */
- if (DEPRECATED_STREQN (p, "r0", 2) || DEPRECATED_STREQN (p, "r8", 2))
- {
- int rn = (p[1] == '0' ? 0 : 8);
- int i = 0;
-
- /* Get the next 8 values and record them. */
- while (i < 8)
- {
- p = strtok (NULL, " \t\r\n");
- if (p)
- monitor_supply_register (rn + i, p);
- i++;
- }
- }
- else if (DEPRECATED_STREQN (p, "ss", 2))
- {
- /* get the next five values, ignoring the first */
- int rn;
- p = strtok (NULL, " \t\r\n");
- for (rn = 39; rn < 43; rn++)
- {
- p = strtok (NULL, " \t\r\n");
- if (p)
- monitor_supply_register (rn, p);
- }
- }
- else
- {
- break;
- }
- }
- else
- {
- /* Simple register type, paired */
- char *name = p;
- int i;
-
- /* Get and record value */
- p = strtok (NULL, " \t\r\n");
- if (p)
- {
- for (i = 0; i < NUM_REGS; i++)
- {
- if (picobug_regnames[i] && DEPRECATED_STREQ (picobug_regnames[i], name))
- break;
- }
-
- if (i <= NUM_REGS)
- monitor_supply_register (i, p);
- }
- }
- p = strtok (NULL, " \t\r\n");
- }
-
- return 0;
-}
-
-static void
-init_picobug_cmds (void)
-{
- picobug_cmds.flags = MO_GETMEM_NEEDS_RANGE | MO_CLR_BREAK_USES_ADDR | MO_PRINT_PROGRAM_OUTPUT;
-
- picobug_cmds.init = picobug_inits; /* Init strings */
- picobug_cmds.cont = "g\n"; /* continue command */
- picobug_cmds.step = "s\n"; /* single step */
- picobug_cmds.set_break = "br %x\n"; /* set a breakpoint */
- picobug_cmds.clr_break = "nobr %x\n"; /* clear a breakpoint */
- picobug_cmds.clr_all_break = "nobr\n"; /* clear all breakpoints */
- picobug_cmds.setmem.cmdb = "mm %x %x ;b\n"; /* setmem.cmdb (addr, value) */
- picobug_cmds.setmem.cmdw = "mm %x %x ;h\n"; /* setmem.cmdw (addr, value) */
- picobug_cmds.setmem.cmdl = "mm %x %x ;w\n"; /* setmem.cmdl (addr, value) */
- picobug_cmds.getmem.cmdb = "md %x %x\n"; /* getmem.cmdb (start addr, end addr) */
- picobug_cmds.getmem.resp_delim = ":"; /* getmem.resp_delim */
- picobug_cmds.setreg.cmd = "rm %s %x\n"; /* setreg.cmd (name, value) */
- picobug_cmds.getreg.cmd = "rd %s\n"; /* getreg.cmd (name) */
- picobug_cmds.getreg.resp_delim = ":"; /* getreg.resp_delim */
- picobug_cmds.dump_registers = "rd\n"; /* dump_registers */
- picobug_cmds.dumpregs = picobug_dumpregs; /* dump registers parser */
- picobug_cmds.load = "lo\n"; /* download command */
- picobug_cmds.prompt = "picobug> "; /* monitor command prompt */
- picobug_cmds.line_term = "\n"; /* end-of-line terminator */
- picobug_cmds.target = &picobug_ops; /* target operations */
- picobug_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */
- picobug_cmds.regnames = picobug_regnames; /* registers names */
- picobug_cmds.num_breakpoints = 20; /* number of breakpoints */
- picobug_cmds.magic = MONITOR_OPS_MAGIC; /* magic */
-}
-
-void
-_initialize_picobug_rom (void)
-{
- int i;
-
- /* Initialize m32r RevC monitor target */
- init_picobug_cmds ();
- init_monitor_ops (&picobug_ops);
- picobug_ops.to_shortname = "picobug";
- picobug_ops.to_longname = "picobug monitor";
- picobug_ops.to_doc = "Debug via the picobug monitor.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).";
- picobug_ops.to_open = picobug_open;
-
- add_target (&picobug_ops);
-}
+++ /dev/null
-/* Target-machine dependent code for Motorola MCore for GDB, the GNU debugger
-
- Copyright 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. */
-
-#include "defs.h"
-#include "frame.h"
-#include "symtab.h"
-#include "value.h"
-#include "gdbcmd.h"
-#include "regcache.h"
-#include "objfiles.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "arch-utils.h"
-#include "gdb_string.h"
-#include "disasm.h"
-#include "dis-asm.h"
-
-static CORE_ADDR mcore_analyze_prologue (struct frame_info *fi, CORE_ADDR pc,
- int skip_prologue);
-static int get_insn (CORE_ADDR pc);
-
-#ifdef MCORE_DEBUG
-int mcore_debug = 0;
-#endif
-
-
-/* All registers are 4 bytes long. */
-#define MCORE_REG_SIZE 4
-#define MCORE_NUM_REGS 65
-
-/* Some useful register numbers. */
-#define PR_REGNUM 15
-#define FIRST_ARGREG 2
-#define LAST_ARGREG 7
-#define RETVAL_REGNUM 2
-
-
-/* Additional info that we use for managing frames */
-struct frame_extra_info
- {
- /* A generic status word */
- int status;
-
- /* Size of this frame */
- int framesize;
-
- /* The register that is acting as a frame pointer, if
- it is being used. This is undefined if status
- does not contain the flag MY_FRAME_IN_FP. */
- int fp_regnum;
- };
-
-/* frame_extra_info status flags */
-
-/* The base of the current frame is actually in the stack pointer.
- This happens when there is no frame pointer (MCore ABI does not
- require a frame pointer) or when we're stopped in the prologue or
- epilogue itself. In these cases, mcore_analyze_prologue will need
- to update fi->frame before returning or analyzing the register
- save instructions. */
-#define MY_FRAME_IN_SP 0x1
-
-/* The base of the current frame is in a frame pointer register.
- This register is noted in frame_extra_info->fp_regnum.
-
- Note that the existence of an FP might also indicate that the
- function has called alloca. */
-#define MY_FRAME_IN_FP 0x2
-
-/* This flag is set to indicate that this frame is the top-most
- frame. This tells frame chain not to bother trying to unwind
- beyond this frame. */
-#define NO_MORE_FRAMES 0x4
-
-/* Instruction macros used for analyzing the prologue */
-#define IS_SUBI0(x) (((x) & 0xfe0f) == 0x2400) /* subi r0,oimm5 */
-#define IS_STM(x) (((x) & 0xfff0) == 0x0070) /* stm rf-r15,r0 */
-#define IS_STWx0(x) (((x) & 0xf00f) == 0x9000) /* stw rz,(r0,disp) */
-#define IS_STWxy(x) (((x) & 0xf000) == 0x9000) /* stw rx,(ry,disp) */
-#define IS_MOVx0(x) (((x) & 0xfff0) == 0x1200) /* mov rn,r0 */
-#define IS_LRW1(x) (((x) & 0xff00) == 0x7100) /* lrw r1,literal */
-#define IS_MOVI1(x) (((x) & 0xf80f) == 0x6001) /* movi r1,imm7 */
-#define IS_BGENI1(x) (((x) & 0xfe0f) == 0x3201) /* bgeni r1,imm5 */
-#define IS_BMASKI1(x) (((x) & 0xfe0f) == 0x2C01) /* bmaski r1,imm5 */
-#define IS_ADDI1(x) (((x) & 0xfe0f) == 0x2001) /* addi r1,oimm5 */
-#define IS_SUBI1(x) (((x) & 0xfe0f) == 0x2401) /* subi r1,oimm5 */
-#define IS_RSUBI1(x) (((x) & 0xfe0f) == 0x2801) /* rsubi r1,imm5 */
-#define IS_NOT1(x) (((x) & 0xffff) == 0x01f1) /* not r1 */
-#define IS_ROTLI1(x) (((x) & 0xfe0f) == 0x3801) /* rotli r1,imm5 */
-#define IS_BSETI1(x) (((x) & 0xfe0f) == 0x3401) /* bseti r1,imm5 */
-#define IS_BCLRI1(x) (((x) & 0xfe0f) == 0x3001) /* bclri r1,imm5 */
-#define IS_IXH1(x) (((x) & 0xffff) == 0x1d11) /* ixh r1,r1 */
-#define IS_IXW1(x) (((x) & 0xffff) == 0x1511) /* ixw r1,r1 */
-#define IS_SUB01(x) (((x) & 0xffff) == 0x0510) /* subu r0,r1 */
-#define IS_RTS(x) (((x) & 0xffff) == 0x00cf) /* jmp r15 */
-
-#define IS_R1_ADJUSTER(x) \
- (IS_ADDI1(x) || IS_SUBI1(x) || IS_ROTLI1(x) || IS_BSETI1(x) \
- || IS_BCLRI1(x) || IS_RSUBI1(x) || IS_NOT1(x) \
- || IS_IXH1(x) || IS_IXW1(x))
-\f
-
-#ifdef MCORE_DEBUG
-static void
-mcore_dump_insn (char *commnt, CORE_ADDR pc, int insn)
-{
- if (mcore_debug)
- {
- printf_filtered ("MCORE: %s %08x %08x ",
- commnt, (unsigned int) pc, (unsigned int) insn);
- gdb_print_insn (pc, gdb_stdout);
- printf_filtered ("\n");
- }
-}
-#define mcore_insn_debug(args) { if (mcore_debug) printf_filtered args; }
-#else /* !MCORE_DEBUG */
-#define mcore_dump_insn(a,b,c) {}
-#define mcore_insn_debug(args) {}
-#endif
-
-
-static struct type *
-mcore_register_virtual_type (int regnum)
-{
- if (regnum < 0 || regnum >= MCORE_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "mcore_register_virtual_type: illegal register number %d",
- regnum);
- else
- return builtin_type_int;
-}
-
-static int
-mcore_register_byte (int regnum)
-{
- if (regnum < 0 || regnum >= MCORE_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "mcore_register_byte: illegal register number %d",
- regnum);
- else
- return (regnum * MCORE_REG_SIZE);
-}
-
-static int
-mcore_register_size (int regnum)
-{
-
- if (regnum < 0 || regnum >= MCORE_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "mcore_register_size: illegal register number %d",
- regnum);
- else
- return MCORE_REG_SIZE;
-}
-
-/* The registers of the Motorola MCore processors */
-
-static const char *
-mcore_register_name (int regnum)
-{
-
- static char *register_names[] = {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "ar0", "ar1", "ar2", "ar3", "ar4", "ar5", "ar6", "ar7",
- "ar8", "ar9", "ar10", "ar11", "ar12", "ar13", "ar14", "ar15",
- "psr", "vbr", "epsr", "fpsr", "epc", "fpc", "ss0", "ss1",
- "ss2", "ss3", "ss4", "gcr", "gsr", "cr13", "cr14", "cr15",
- "cr16", "cr17", "cr18", "cr19", "cr20", "cr21", "cr22", "cr23",
- "cr24", "cr25", "cr26", "cr27", "cr28", "cr29", "cr30", "cr31",
- "pc"
- };
-
- if (regnum < 0 ||
- regnum >= sizeof (register_names) / sizeof (register_names[0]))
- internal_error (__FILE__, __LINE__,
- "mcore_register_name: illegal register number %d",
- regnum);
- else
- return register_names[regnum];
-}
-
-/* Given the address at which to insert a breakpoint (BP_ADDR),
- what will that breakpoint be?
-
- For MCore, we have a breakpoint instruction. Since all MCore
- instructions are 16 bits, this is all we need, regardless of
- address. bpkt = 0x0000 */
-
-static const unsigned char *
-mcore_breakpoint_from_pc (CORE_ADDR * bp_addr, int *bp_size)
-{
- static char breakpoint[] =
- {0x00, 0x00};
- *bp_size = 2;
- return breakpoint;
-}
-
-static CORE_ADDR
-mcore_saved_pc_after_call (struct frame_info *frame)
-{
- return read_register (PR_REGNUM);
-}
-
-/* This is currently handled by init_extra_frame_info. */
-static void
-mcore_frame_init_saved_regs (struct frame_info *frame)
-{
-
-}
-
-/* This is currently handled by mcore_push_arguments */
-static void
-mcore_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
-
-}
-
-static int
-mcore_reg_struct_has_addr (int gcc_p, struct type *type)
-{
- return 0;
-}
-
-
-/* Helper function for several routines below. This funtion simply
- sets up a fake, aka dummy, frame (not a _call_ dummy frame) that
- we can analyze with mcore_analyze_prologue. */
-
-static struct frame_info *
-analyze_dummy_frame (CORE_ADDR pc, CORE_ADDR frame)
-{
- struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
- struct frame_info *dummy
- = deprecated_frame_xmalloc_with_cleanup (SIZEOF_FRAME_SAVED_REGS,
- sizeof (struct frame_extra_info));
- deprecated_update_frame_pc_hack (dummy, pc);
- deprecated_update_frame_base_hack (dummy, frame);
- get_frame_extra_info (dummy)->status = 0;
- get_frame_extra_info (dummy)->framesize = 0;
- mcore_analyze_prologue (dummy, 0, 0);
- do_cleanups (old_chain);
- return dummy;
-}
-
-/* Function prologues on the Motorola MCore processors consist of:
-
- - adjustments to the stack pointer (r1 used as scratch register)
- - store word/multiples that use r0 as the base address
- - making a copy of r0 into another register (a "frame" pointer)
-
- Note that the MCore really doesn't have a real frame pointer.
- Instead, the compiler may copy the SP into a register (usually
- r8) to act as an arg pointer. For our target-dependent purposes,
- the frame info's "frame" member will be the beginning of the
- frame. The SP could, in fact, point below this.
-
- The prologue ends when an instruction fails to meet either of
- the first two criteria or when an FP is made. We make a special
- exception for gcc. When compiling unoptimized code, gcc will
- setup stack slots. We need to make sure that we skip the filling
- of these stack slots as much as possible. This is only done
- when SKIP_PROLOGUE is set, so that it does not mess up
- backtraces. */
-
-/* Analyze the prologue of frame FI to determine where registers are saved,
- the end of the prologue, etc. Return the address of the first line
- of "real" code (i.e., the end of the prologue). */
-
-static CORE_ADDR
-mcore_analyze_prologue (struct frame_info *fi, CORE_ADDR pc, int skip_prologue)
-{
- CORE_ADDR func_addr, func_end, addr, stop;
- CORE_ADDR stack_size;
- int insn, rn;
- int status;
- int fp_regnum = 0; /* dummy, valid when (flags & MY_FRAME_IN_FP) */
- int flags;
- int framesize;
- int register_offsets[NUM_REGS];
- char *name;
-
- /* If provided, use the PC in the frame to look up the
- start of this function. */
- pc = (fi == NULL ? pc : get_frame_pc (fi));
-
- /* Find the start of this function. */
- status = find_pc_partial_function (pc, &name, &func_addr, &func_end);
-
- /* If the start of this function could not be found or if the debbuger
- is stopped at the first instruction of the prologue, do nothing. */
- if (status == 0)
- return pc;
-
- /* If the debugger is entry function, give up. */
- if (func_addr == entry_point_address ())
- {
- if (fi != NULL)
- get_frame_extra_info (fi)->status |= NO_MORE_FRAMES;
- return pc;
- }
-
- /* At the start of a function, our frame is in the stack pointer. */
- flags = MY_FRAME_IN_SP;
-
- /* Start decoding the prologue. We start by checking two special cases:
-
- 1. We're about to return
- 2. We're at the first insn of the prologue.
-
- If we're about to return, our frame has already been deallocated.
- If we are stopped at the first instruction of a prologue,
- then our frame has not yet been set up. */
-
- /* Get the first insn from memory (all MCore instructions are 16 bits) */
- mcore_insn_debug (("MCORE: starting prologue decoding\n"));
- insn = get_insn (pc);
- mcore_dump_insn ("got 1: ", pc, insn);
-
- /* Check for return. */
- if (fi != NULL && IS_RTS (insn))
- {
- mcore_insn_debug (("MCORE: got jmp r15"));
- if (get_next_frame (fi) == NULL)
- deprecated_update_frame_base_hack (fi, read_sp ());
- return get_frame_pc (fi);
- }
-
- /* Check for first insn of prologue */
- if (fi != NULL && 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);
- }
-
- /* Figure out where to stop scanning */
- stop = (fi ? get_frame_pc (fi) : func_end);
-
- /* Don't walk off the end of the function */
- stop = (stop > func_end ? func_end : stop);
-
- /* REGISTER_OFFSETS will contain offsets, from the top of the frame
- (NOT the frame pointer), for the various saved registers or -1
- if the register is not saved. */
- for (rn = 0; rn < NUM_REGS; rn++)
- register_offsets[rn] = -1;
-
- /* Analyze the prologue. Things we determine from analyzing the
- prologue include:
- * the size of the frame
- * where saved registers are located (and which are saved)
- * FP used? */
- mcore_insn_debug (("MCORE: Scanning prologue: func_addr=0x%x, stop=0x%x\n",
- (unsigned int) func_addr, (unsigned int) stop));
-
- framesize = 0;
- for (addr = func_addr; addr < stop; addr += 2)
- {
- /* Get next insn */
- insn = get_insn (addr);
- mcore_dump_insn ("got 2: ", addr, insn);
-
- if (IS_SUBI0 (insn))
- {
- int offset = 1 + ((insn >> 4) & 0x1f);
- mcore_insn_debug (("MCORE: got subi r0,%d; continuing\n", offset));
- framesize += offset;
- continue;
- }
- else if (IS_STM (insn))
- {
- /* Spill register(s) */
- int offset;
- int start_register;
-
- /* BIG WARNING! The MCore ABI does not restrict functions
- to taking only one stack allocation. Therefore, when
- we save a register, we record the offset of where it was
- saved relative to the current framesize. This will
- then give an offset from the SP upon entry to our
- function. Remember, framesize is NOT constant until
- we're done scanning the prologue. */
- start_register = (insn & 0xf);
- mcore_insn_debug (("MCORE: got stm r%d-r15,(r0)\n", start_register));
-
- for (rn = start_register, offset = 0; rn <= 15; rn++, offset += 4)
- {
- register_offsets[rn] = framesize - offset;
- mcore_insn_debug (("MCORE: r%d saved at 0x%x (offset %d)\n", rn,
- register_offsets[rn], offset));
- }
- mcore_insn_debug (("MCORE: continuing\n"));
- continue;
- }
- else if (IS_STWx0 (insn))
- {
- /* Spill register: see note for IS_STM above. */
- int imm;
-
- rn = (insn >> 8) & 0xf;
- imm = (insn >> 4) & 0xf;
- register_offsets[rn] = framesize - (imm << 2);
- mcore_insn_debug (("MCORE: r%d saved at offset 0x%x\n", rn, register_offsets[rn]));
- mcore_insn_debug (("MCORE: continuing\n"));
- continue;
- }
- else if (IS_MOVx0 (insn))
- {
- /* We have a frame pointer, so this prologue is over. Note
- the register which is acting as the frame pointer. */
- flags |= MY_FRAME_IN_FP;
- flags &= ~MY_FRAME_IN_SP;
- fp_regnum = insn & 0xf;
- mcore_insn_debug (("MCORE: Found a frame pointer: r%d\n", fp_regnum));
-
- /* If we found an FP, we're at the end of the prologue. */
- mcore_insn_debug (("MCORE: end of prologue\n"));
- if (skip_prologue)
- continue;
-
- /* If we're decoding prologue, stop here. */
- addr += 2;
- break;
- }
- else if (IS_STWxy (insn) && (flags & MY_FRAME_IN_FP) && ((insn & 0xf) == fp_regnum))
- {
- /* Special case. Skip over stack slot allocs, too. */
- mcore_insn_debug (("MCORE: push arg onto stack.\n"));
- continue;
- }
- else if (IS_LRW1 (insn) || IS_MOVI1 (insn)
- || IS_BGENI1 (insn) || IS_BMASKI1 (insn))
- {
- int adjust = 0;
- int offset = 0;
- int insn2;
-
- mcore_insn_debug (("MCORE: looking at large frame\n"));
- if (IS_LRW1 (insn))
- {
- adjust =
- read_memory_integer ((addr + 2 + ((insn & 0xff) << 2)) & 0xfffffffc, 4);
- }
- else if (IS_MOVI1 (insn))
- adjust = (insn >> 4) & 0x7f;
- else if (IS_BGENI1 (insn))
- adjust = 1 << ((insn >> 4) & 0x1f);
- else /* IS_BMASKI (insn) */
- adjust = (1 << (adjust >> 4) & 0x1f) - 1;
-
- mcore_insn_debug (("MCORE: base framesize=0x%x\n", adjust));
-
- /* May have zero or more insns which modify r1 */
- mcore_insn_debug (("MCORE: looking for r1 adjusters...\n"));
- offset = 2;
- insn2 = get_insn (addr + offset);
- while (IS_R1_ADJUSTER (insn2))
- {
- int imm;
-
- imm = (insn2 >> 4) & 0x1f;
- mcore_dump_insn ("got 3: ", addr + offset, insn);
- if (IS_ADDI1 (insn2))
- {
- adjust += (imm + 1);
- mcore_insn_debug (("MCORE: addi r1,%d\n", imm + 1));
- }
- else if (IS_SUBI1 (insn2))
- {
- adjust -= (imm + 1);
- mcore_insn_debug (("MCORE: subi r1,%d\n", imm + 1));
- }
- else if (IS_RSUBI1 (insn2))
- {
- adjust = imm - adjust;
- mcore_insn_debug (("MCORE: rsubi r1,%d\n", imm + 1));
- }
- else if (IS_NOT1 (insn2))
- {
- adjust = ~adjust;
- mcore_insn_debug (("MCORE: not r1\n"));
- }
- else if (IS_ROTLI1 (insn2))
- {
- adjust <<= imm;
- mcore_insn_debug (("MCORE: rotli r1,%d\n", imm + 1));
- }
- else if (IS_BSETI1 (insn2))
- {
- adjust |= (1 << imm);
- mcore_insn_debug (("MCORE: bseti r1,%d\n", imm));
- }
- else if (IS_BCLRI1 (insn2))
- {
- adjust &= ~(1 << imm);
- mcore_insn_debug (("MCORE: bclri r1,%d\n", imm));
- }
- else if (IS_IXH1 (insn2))
- {
- adjust *= 3;
- mcore_insn_debug (("MCORE: ix.h r1,r1\n"));
- }
- else if (IS_IXW1 (insn2))
- {
- adjust *= 5;
- mcore_insn_debug (("MCORE: ix.w r1,r1\n"));
- }
-
- offset += 2;
- insn2 = get_insn (addr + offset);
- };
-
- mcore_insn_debug (("MCORE: done looking for r1 adjusters\n"));
-
- /* If the next insn adjusts the stack pointer, we keep everything;
- if not, we scrap it and we've found the end of the prologue. */
- if (IS_SUB01 (insn2))
- {
- addr += offset;
- framesize += adjust;
- mcore_insn_debug (("MCORE: found stack adjustment of 0x%x bytes.\n", adjust));
- mcore_insn_debug (("MCORE: skipping to new address 0x%x\n", addr));
- mcore_insn_debug (("MCORE: continuing\n"));
- continue;
- }
-
- /* None of these instructions are prologue, so don't touch
- anything. */
- mcore_insn_debug (("MCORE: no subu r1,r0, NOT altering framesize.\n"));
- break;
- }
-
- /* This is not a prologue insn, so stop here. */
- mcore_insn_debug (("MCORE: insn is not a prologue insn -- ending scan\n"));
- break;
- }
-
- mcore_insn_debug (("MCORE: done analyzing prologue\n"));
- mcore_insn_debug (("MCORE: prologue end = 0x%x\n", addr));
-
- /* Save everything we have learned about this frame into FI. */
- if (fi != NULL)
- {
- get_frame_extra_info (fi)->framesize = framesize;
- get_frame_extra_info (fi)->fp_regnum = fp_regnum;
- get_frame_extra_info (fi)->status = flags;
-
- /* Fix the frame pointer. When gcc uses r8 as a frame pointer,
- it is really an arg ptr. We adjust fi->frame to be a "real"
- frame pointer. */
- if (get_next_frame (fi) == NULL)
- {
- if (get_frame_extra_info (fi)->status & MY_FRAME_IN_SP)
- deprecated_update_frame_base_hack (fi, read_sp () + framesize);
- else
- deprecated_update_frame_base_hack (fi, read_register (fp_regnum) + framesize);
- }
-
- /* Note where saved registers are stored. The offsets in REGISTER_OFFSETS
- are computed relative to the top of the frame. */
- for (rn = 0; rn < NUM_REGS; rn++)
- {
- if (register_offsets[rn] >= 0)
- {
- deprecated_get_frame_saved_regs (fi)[rn] = get_frame_base (fi) - register_offsets[rn];
- mcore_insn_debug (("Saved register %s stored at 0x%08x, value=0x%08x\n",
- mcore_register_names[rn], fi->saved_regs[rn],
- read_memory_integer (fi->saved_regs[rn], 4)));
- }
- }
- }
-
- /* Return addr of first non-prologue insn. */
- return addr;
-}
-
-/* Given a GDB frame, determine the address of the calling function's
- frame. This will be used to create a new GDB frame struct, and
- then DEPRECATED_INIT_EXTRA_FRAME_INFO and DEPRECATED_INIT_FRAME_PC
- will be called for the new frame. */
-
-static CORE_ADDR
-mcore_frame_chain (struct frame_info * fi)
-{
- struct frame_info *dummy;
- CORE_ADDR callers_addr;
-
- /* Analyze the prologue of this function. */
- if (get_frame_extra_info (fi)->status == 0)
- mcore_analyze_prologue (fi, 0, 0);
-
- /* If mcore_analyze_prologue set NO_MORE_FRAMES, quit now. */
- if (get_frame_extra_info (fi)->status & NO_MORE_FRAMES)
- return 0;
-
- /* Now that we've analyzed our prologue, we can start to ask
- for information about our caller. The easiest way to do
- this is to analyze our caller's prologue.
-
- If our caller has a frame pointer, then we need to find
- the value of that register upon entry to our frame.
- This value is either in fi->saved_regs[rn] if it's saved,
- or it's still in a register.
-
- If our caller does not have a frame pointer, then his frame base
- is <our base> + -<caller's frame size>. */
- dummy = analyze_dummy_frame (DEPRECATED_FRAME_SAVED_PC (fi), get_frame_base (fi));
-
- if (get_frame_extra_info (dummy)->status & MY_FRAME_IN_FP)
- {
- int fp = get_frame_extra_info (dummy)->fp_regnum;
-
- /* Our caller has a frame pointer. */
- if (deprecated_get_frame_saved_regs (fi)[fp] != 0)
- {
- /* The "FP" was saved on the stack. Don't forget to adjust
- the "FP" with the framesize to get a real FP. */
- callers_addr = read_memory_integer (deprecated_get_frame_saved_regs (fi)[fp],
- DEPRECATED_REGISTER_SIZE)
- + get_frame_extra_info (dummy)->framesize;
- }
- else
- {
- /* It's still in the register. Don't forget to adjust
- the "FP" with the framesize to get a real FP. */
- callers_addr = read_register (fp) + get_frame_extra_info (dummy)->framesize;
- }
- }
- else
- {
- /* Our caller does not have a frame pointer. */
- callers_addr = get_frame_base (fi) + get_frame_extra_info (dummy)->framesize;
- }
-
- return callers_addr;
-}
-
-/* Skip the prologue of the function at PC. */
-
-static CORE_ADDR
-mcore_skip_prologue (CORE_ADDR pc)
-{
- CORE_ADDR func_addr, func_end;
- struct symtab_and_line sal;
-
- /* If we have line debugging information, then the end of the
- prologue should be the first assembly instruction of the first
- source line */
- if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
- {
- sal = find_pc_line (func_addr, 0);
- if (sal.end && sal.end < func_end)
- return sal.end;
- }
-
- return mcore_analyze_prologue (NULL, pc, 1);
-}
-
-/* Return the address at which function arguments are offset. */
-static CORE_ADDR
-mcore_frame_args_address (struct frame_info * fi)
-{
- return get_frame_base (fi) - get_frame_extra_info (fi)->framesize;
-}
-
-static CORE_ADDR
-mcore_frame_locals_address (struct frame_info * fi)
-{
- return get_frame_base (fi) - get_frame_extra_info (fi)->framesize;
-}
-
-/* Return the frame pointer in use at address PC. */
-
-static void
-mcore_virtual_frame_pointer (CORE_ADDR pc, int *reg, LONGEST *offset)
-{
- struct frame_info *dummy = analyze_dummy_frame (pc, 0);
- if (get_frame_extra_info (dummy)->status & MY_FRAME_IN_SP)
- {
- *reg = SP_REGNUM;
- *offset = 0;
- }
- else
- {
- *reg = get_frame_extra_info (dummy)->fp_regnum;
- *offset = 0;
- }
-}
-
-/* Find the value of register REGNUM in frame FI. */
-
-static CORE_ADDR
-mcore_find_callers_reg (struct frame_info *fi, int regnum)
-{
- for (; fi != NULL; fi = get_next_frame (fi))
- {
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- return deprecated_read_register_dummy (get_frame_pc (fi),
- get_frame_base (fi), regnum);
- else if (deprecated_get_frame_saved_regs (fi)[regnum] != 0)
- return read_memory_integer (deprecated_get_frame_saved_regs (fi)[regnum],
- DEPRECATED_REGISTER_SIZE);
- }
-
- return read_register (regnum);
-}
-
-/* Find the saved pc in frame FI. */
-
-static CORE_ADDR
-mcore_frame_saved_pc (struct frame_info * fi)
-{
-
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- return deprecated_read_register_dummy (get_frame_pc (fi),
- get_frame_base (fi), PC_REGNUM);
- else
- return mcore_find_callers_reg (fi, PR_REGNUM);
-}
-\f
-/* INFERIOR FUNCTION CALLS */
-
-/* This routine gets called when either the user uses the "return"
- command, or the call dummy breakpoint gets hit. */
-
-static void
-mcore_pop_frame (void)
-{
- int rn;
- struct frame_info *fi = get_current_frame ();
-
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- deprecated_pop_dummy_frame ();
- else
- {
- /* Write out the PC we saved. */
- write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (fi));
-
- /* Restore any saved registers. */
- for (rn = 0; rn < NUM_REGS; rn++)
- {
- if (deprecated_get_frame_saved_regs (fi)[rn] != 0)
- {
- ULONGEST value;
-
- value = read_memory_unsigned_integer (deprecated_get_frame_saved_regs (fi)[rn],
- DEPRECATED_REGISTER_SIZE);
- write_register (rn, value);
- }
- }
-
- /* Actually cut back the stack. */
- write_register (SP_REGNUM, get_frame_base (fi));
- }
-
- /* Finally, throw away any cached frame information. */
- flush_cached_frames ();
-}
-
-/* Setup arguments and PR for a call to the target. First six arguments
- go in FIRST_ARGREG -> LAST_ARGREG, subsequent args go on to the stack.
-
- - Types with lengths greater than DEPRECATED_REGISTER_SIZE may not
- be split between registers and the stack, and they must start in an
- even-numbered register. Subsequent args will go onto the stack.
-
- * Structs may be split between registers and stack, left-aligned.
-
- * If the function returns a struct which will not fit into registers (it's
- more than eight bytes), we must allocate for that, too. Gdb will tell
- us where this buffer is (STRUCT_ADDR), and we simply place it into
- FIRST_ARGREG, since the MCORE treats struct returns (of less than eight
- bytes) as hidden first arguments. */
-
-static CORE_ADDR
-mcore_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
-{
- int argreg;
- int argnum;
- struct stack_arg
- {
- int len;
- char *val;
- }
- *stack_args;
- int nstack_args = 0;
-
- stack_args = (struct stack_arg *) alloca (nargs * sizeof (struct stack_arg));
-
- argreg = FIRST_ARGREG;
-
- /* Align the stack. This is mostly a nop, but not always. It will be needed
- if we call a function which has argument overflow. */
- sp &= ~3;
-
- /* If this function returns a struct which does not fit in the
- return registers, we must pass a buffer to the function
- which it can use to save the return value. */
- if (struct_return)
- write_register (argreg++, struct_addr);
-
- /* FIXME: what about unions? */
- for (argnum = 0; argnum < nargs; argnum++)
- {
- char *val = (char *) VALUE_CONTENTS (args[argnum]);
- int len = TYPE_LENGTH (value_type (args[argnum]));
- struct type *type = value_type (args[argnum]);
- int olen;
-
- mcore_insn_debug (("MCORE PUSH: argreg=%d; len=%d; %s\n",
- argreg, len, TYPE_CODE (type) == TYPE_CODE_STRUCT ? "struct" : "not struct"));
- /* Arguments larger than a register must start in an even
- numbered register. */
- olen = len;
-
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT && len > DEPRECATED_REGISTER_SIZE && argreg % 2)
- {
- mcore_insn_debug (("MCORE PUSH: %d > DEPRECATED_REGISTER_SIZE: and %s is not even\n",
- len, mcore_register_names[argreg]));
- argreg++;
- }
-
- if ((argreg <= LAST_ARGREG && len <= (LAST_ARGREG - argreg + 1) * DEPRECATED_REGISTER_SIZE)
- || (TYPE_CODE (type) == TYPE_CODE_STRUCT))
- {
- /* Something that will fit entirely into registers (or a struct
- which may be split between registers and stack). */
- mcore_insn_debug (("MCORE PUSH: arg %d going into regs\n", argnum));
-
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT && olen < DEPRECATED_REGISTER_SIZE)
- {
- /* Small structs must be right aligned within the register,
- the most significant bits are undefined. */
- write_register (argreg, extract_unsigned_integer (val, len));
- argreg++;
- len = 0;
- }
-
- while (len > 0 && argreg <= LAST_ARGREG)
- {
- write_register (argreg, extract_unsigned_integer (val, DEPRECATED_REGISTER_SIZE));
- argreg++;
- val += DEPRECATED_REGISTER_SIZE;
- len -= DEPRECATED_REGISTER_SIZE;
- }
-
- /* Any remainder for the stack is noted below... */
- }
- else if (TYPE_CODE (value_type (args[argnum])) != TYPE_CODE_STRUCT
- && len > DEPRECATED_REGISTER_SIZE)
- {
- /* All subsequent args go onto the stack. */
- mcore_insn_debug (("MCORE PUSH: does not fit into regs, going onto stack\n"));
- argnum = LAST_ARGREG + 1;
- }
-
- if (len > 0)
- {
- /* Note that this must be saved onto the stack */
- mcore_insn_debug (("MCORE PUSH: adding arg %d to stack\n", argnum));
- stack_args[nstack_args].val = val;
- stack_args[nstack_args].len = len;
- nstack_args++;
- }
-
- }
-
- /* We're done with registers and stack allocation. Now do the actual
- stack pushes. */
- while (nstack_args--)
- {
- sp -= stack_args[nstack_args].len;
- write_memory (sp, stack_args[nstack_args].val, stack_args[nstack_args].len);
- }
-
- /* Return adjusted stack pointer. */
- return sp;
-}
-
-/* Store the return address for the call dummy. For MCore, we've opted
- to use generic call dummies, so we simply store the entry-point
- address into the PR register (r15). */
-
-static CORE_ADDR
-mcore_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
-{
- write_register (PR_REGNUM, entry_point_address ());
- return sp;
-}
-
-/* Setting/getting return values from functions.
-
- The Motorola MCore processors use r2/r3 to return anything
- not larger than 32 bits. Everything else goes into a caller-
- supplied buffer, which is passed in via a hidden first
- argument.
-
- For gdb, this leaves us two routes, based on what
- DEPRECATED_USE_STRUCT_CONVENTION (mcore_use_struct_convention)
- returns. If this macro returns 1, gdb will call
- STORE_STRUCT_RETURN to store the return value.
-
- If DEPRECATED_USE_STRUCT_CONVENTION returns 0, then gdb uses
- STORE_RETURN_VALUE and EXTRACT_RETURN_VALUE to store/fetch the
- functions return value. */
-
-static int
-mcore_use_struct_convention (int gcc_p, struct type *type)
-{
- return (TYPE_LENGTH (type) > 8);
-}
-
-/* Given a function which returns a value of type TYPE, extract the
- the function's return value and place the result into VALBUF.
- REGBUF is the register contents of the target. */
-
-static void
-mcore_extract_return_value (struct type *type, char *regbuf, char *valbuf)
-{
- /* Copy the return value (starting) in RETVAL_REGNUM to VALBUF. */
- /* Only getting the first byte! if len = 1, we need the last byte of
- the register, not the first. */
- memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (RETVAL_REGNUM) +
- (TYPE_LENGTH (type) < 4 ? 4 - TYPE_LENGTH (type) : 0), TYPE_LENGTH (type));
-}
-
-/* Store the return value in VALBUF (of type TYPE) where the caller
- expects to see it.
-
- Values less than 32 bits are stored in r2, right justified and
- sign or zero extended.
-
- Values between 32 and 64 bits are stored in r2 (most
- significant word) and r3 (least significant word, left justified).
- Note that this includes structures of less than eight bytes, too. */
-
-static void
-mcore_store_return_value (struct type *type, char *valbuf)
-{
- int value_size;
- int return_size;
- int offset;
- char *zeros;
-
- value_size = TYPE_LENGTH (type);
-
- /* Return value fits into registers. */
- return_size = (value_size + DEPRECATED_REGISTER_SIZE - 1) & ~(DEPRECATED_REGISTER_SIZE - 1);
- offset = DEPRECATED_REGISTER_BYTE (RETVAL_REGNUM) + (return_size - value_size);
- zeros = alloca (return_size);
- memset (zeros, 0, return_size);
-
- deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (RETVAL_REGNUM), zeros,
- return_size);
- deprecated_write_register_bytes (offset, valbuf, value_size);
-}
-
-/* Initialize our target-dependent "stuff" for this newly created frame.
-
- This includes allocating space for saved registers and analyzing
- the prologue of this frame. */
-
-static void
-mcore_init_extra_frame_info (int fromleaf, struct frame_info *fi)
-{
- if (fi && get_next_frame (fi))
- deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
-
- frame_saved_regs_zalloc (fi);
-
- frame_extra_info_zalloc (fi, sizeof (struct frame_extra_info));
- get_frame_extra_info (fi)->status = 0;
- get_frame_extra_info (fi)->framesize = 0;
-
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- {
- /* We need to setup fi->frame here because call_function_by_hand
- gets it wrong by assuming it's always FP. */
- deprecated_update_frame_base_hack (fi, deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), SP_REGNUM));
- }
- else
- mcore_analyze_prologue (fi, 0, 0);
-}
-
-/* Get an insturction from memory. */
-
-static int
-get_insn (CORE_ADDR pc)
-{
- char buf[4];
- int status = deprecated_read_memory_nobpt (pc, buf, 2);
- if (status != 0)
- return 0;
-
- return extract_unsigned_integer (buf, 2);
-}
-
-static struct gdbarch *
-mcore_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-{
- struct gdbarch_tdep *tdep = NULL;
- struct gdbarch *gdbarch;
-
- /* find a candidate among the list of pre-declared architectures. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return (arches->gdbarch);
-
- gdbarch = gdbarch_alloc (&info, 0);
-
- /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
- ready to unwind the PC first (see frame.c:get_prev_frame()). */
- set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
-
- /* Registers: */
-
- /* All registers are 32 bits */
- set_gdbarch_deprecated_register_size (gdbarch, MCORE_REG_SIZE);
- set_gdbarch_register_name (gdbarch, mcore_register_name);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, mcore_register_virtual_type);
- set_gdbarch_deprecated_register_virtual_size (gdbarch, mcore_register_size);
- set_gdbarch_deprecated_register_raw_size (gdbarch, mcore_register_size);
- set_gdbarch_deprecated_register_byte (gdbarch, mcore_register_byte);
- set_gdbarch_num_regs (gdbarch, MCORE_NUM_REGS);
- set_gdbarch_pc_regnum (gdbarch, 64);
- set_gdbarch_sp_regnum (gdbarch, 0);
- set_gdbarch_deprecated_fp_regnum (gdbarch, 0);
-
- /* Call Dummies: */
-
- set_gdbarch_deprecated_saved_pc_after_call (gdbarch, mcore_saved_pc_after_call);
- set_gdbarch_breakpoint_from_pc (gdbarch, mcore_breakpoint_from_pc);
- set_gdbarch_deprecated_push_return_address (gdbarch, mcore_push_return_address);
- set_gdbarch_deprecated_push_arguments (gdbarch, mcore_push_arguments);
-
- /* Frames: */
-
- set_gdbarch_deprecated_init_extra_frame_info (gdbarch, mcore_init_extra_frame_info);
- set_gdbarch_deprecated_frame_chain (gdbarch, mcore_frame_chain);
- set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, mcore_frame_init_saved_regs);
- set_gdbarch_deprecated_frame_saved_pc (gdbarch, mcore_frame_saved_pc);
- set_gdbarch_deprecated_store_return_value (gdbarch, mcore_store_return_value);
- set_gdbarch_deprecated_extract_return_value (gdbarch,
- mcore_extract_return_value);
- set_gdbarch_deprecated_store_struct_return (gdbarch, mcore_store_struct_return);
- set_gdbarch_skip_prologue (gdbarch, mcore_skip_prologue);
- set_gdbarch_deprecated_frame_args_address (gdbarch, mcore_frame_args_address);
- set_gdbarch_deprecated_frame_locals_address (gdbarch, mcore_frame_locals_address);
- set_gdbarch_deprecated_pop_frame (gdbarch, mcore_pop_frame);
- set_gdbarch_virtual_frame_pointer (gdbarch, mcore_virtual_frame_pointer);
-
- /* Misc.: */
-
- /* Stack grows down. */
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
- set_gdbarch_deprecated_use_struct_convention (gdbarch, mcore_use_struct_convention);
- set_gdbarch_believe_pcc_promotion (gdbarch, 1);
- /* MCore will never pass a sturcture by reference. It will always be split
- between registers and stack. */
- set_gdbarch_deprecated_reg_struct_has_addr
- (gdbarch, mcore_reg_struct_has_addr);
-
- /* Should be using push_dummy_call. */
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
-
- set_gdbarch_print_insn (gdbarch, print_insn_mcore);
-
- return gdbarch;
-}
-
-static void
-mcore_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
-{
-
-}
-
-extern initialize_file_ftype _initialize_mcore_tdep; /* -Wmissing-prototypes */
-
-void
-_initialize_mcore_tdep (void)
-{
- gdbarch_register (bfd_arch_mcore, mcore_gdbarch_init, mcore_dump_tdep);
-
-#ifdef MCORE_DEBUG
- deprecated_add_show_from_set
- (add_set_cmd ("mcoredebug", no_class,
- var_boolean, (char *) &mcore_debug,
- "Set mcore debugging.\n", &setlist),
- &showlist);
-#endif
-}
+++ /dev/null
-/* 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 "frame.h"
-#include "frame-unwind.h"
-#include "frame-base.h"
-#include "trad-frame.h"
-#include "symtab.h"
-#include "dwarf2-frame.h"
-#include "regcache.h"
-
-enum {
- E_D0_REGNUM = 0,
- E_D1_REGNUM = 1,
- E_D2_REGNUM = 2,
- E_D3_REGNUM = 3,
- E_A0_REGNUM = 4,
- E_A1_REGNUM = 5,
- E_A2_REGNUM = 6,
- E_A3_REGNUM = 7,
- E_SP_REGNUM = 8,
- E_PC_REGNUM = 9,
- E_MDR_REGNUM = 10,
- E_PSW_REGNUM = 11,
- E_LIR_REGNUM = 12,
- E_LAR_REGNUM = 13,
- E_MDRQ_REGNUM = 14,
- E_E0_REGNUM = 15,
- E_MCRH_REGNUM = 26,
- E_MCRL_REGNUM = 27,
- E_MCVF_REGNUM = 28,
- E_NUM_REGS = 32
-};
-
-
-/* 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 scan_prologue_using_sal. */
- return skip_prologue_using_sal (pc);
-}
-
-/* Simple frame_unwind_cache.
- This finds the "extra info" for the frame. */
-static struct trad_frame_cache *
-mn10300_frame_unwind_cache (struct frame_info *next_frame,
- void **this_prologue_cache)
-{
- struct trad_frame_cache *cache;
-
- if (*this_prologue_cache)
- return (*this_prologue_cache);
-
- cache = trad_frame_cache_zalloc (next_frame);
- trad_frame_set_id (cache,
- frame_id_build (gdbarch_unwind_sp (current_gdbarch,
- next_frame),
- gdbarch_unwind_pc (current_gdbarch,
- next_frame)));
-
- /* FIXME: The SP isn't the frame base, so this is 0th approximation. */
- /* FIXME: The A3 reg isn't always the frame register either, so this
- is 1st approximation. */
- trad_frame_set_this_base (cache,
- frame_unwind_register_signed (next_frame,
- E_A3_REGNUM));
- (*this_prologue_cache) = cache;
- return cache;
-}
-
-/* Here is a dummy implementation. */
-static struct frame_id
-mn10300_dummy_unwind_dummy_id (struct gdbarch *gdbarch,
- struct frame_info *next_frame)
-{
- return frame_id_build (0, 0);
-}
-
-/* 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_dummy_unwind_dummy_id);
- set_gdbarch_unwind_pc (gdbarch, mn10300_unwind_pc);
- set_gdbarch_unwind_sp (gdbarch, mn10300_unwind_sp);
-}
-
-static struct gdbarch *
-mn10300_gdbarch_init (struct gdbarch_info info,
- struct gdbarch_list *arches)
-{
- struct gdbarch *gdbarch;
-
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
- gdbarch = gdbarch_alloc (&info, NULL);
-
- switch (info.bfd_arch_info->mach)
- {
- case 0:
- case bfd_mach_mn10300:
- set_gdbarch_register_name (gdbarch, mn10300_generic_register_name);
- break;
- case bfd_mach_am33:
- set_gdbarch_register_name (gdbarch, am33_register_name);
- 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);
-
- mn10300_frame_unwind_init (gdbarch);
-
- return gdbarch;
-}
-
-void
-_initialize_mn10300_tdep (void)
-{
- register_gdbarch_init (bfd_arch_mn10300, mn10300_gdbarch_init);
-}
-
+++ /dev/null
-/* Target dependent code for the NS32000, for GDB.
-
- Copyright 1986, 1988, 1991, 1992, 1994, 1995, 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. */
-
-#include "defs.h"
-#include "frame.h"
-#include "gdbtypes.h"
-#include "gdbcore.h"
-#include "inferior.h"
-#include "regcache.h"
-#include "target.h"
-#include "arch-utils.h"
-#include "osabi.h"
-#include "dis-asm.h"
-
-#include "ns32k-tdep.h"
-#include "gdb_string.h"
-
-static int sign_extend (int value, int bits);
-static CORE_ADDR ns32k_get_enter_addr (CORE_ADDR);
-static int ns32k_localcount (CORE_ADDR enter_pc);
-static void flip_bytes (void *, int);
-
-static const char *
-ns32k_register_name_32082 (int regno)
-{
- static char *register_names[] =
- {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "sp", "fp", "pc", "ps",
- "l0", "l1", "l2", "l3", "xx",
- };
-
- if (regno < 0)
- return NULL;
- if (regno >= sizeof (register_names) / sizeof (*register_names))
- return NULL;
-
- return (register_names[regno]);
-}
-
-static const char *
-ns32k_register_name_32382 (int regno)
-{
- static char *register_names[] =
- {
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
- "sp", "fp", "pc", "ps",
- "fsr",
- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", "xx",
- };
-
- if (regno < 0)
- return NULL;
- if (regno >= sizeof (register_names) / sizeof (*register_names))
- return NULL;
-
- return (register_names[regno]);
-}
-
-static int
-ns32k_register_byte_32082 (int regno)
-{
- if (regno >= NS32K_LP0_REGNUM)
- return (NS32K_LP0_REGNUM * 4) + ((regno - NS32K_LP0_REGNUM) * 8);
-
- return (regno * 4);
-}
-
-static int
-ns32k_register_byte_32382 (int regno)
-{
- /* This is a bit yuk. The even numbered double precision floating
- point long registers occupy the same space as the even:odd numbered
- single precision floating point registers, but the extra 32381 FPU
- registers are at the end. Doing it this way is compatible for both
- 32081 and 32381 equipped machines. */
-
- return ((regno < NS32K_LP0_REGNUM ? regno
- : (regno - NS32K_LP0_REGNUM) & 1 ? regno - 1
- : (regno - NS32K_LP0_REGNUM + FP0_REGNUM)) * 4);
-}
-
-static int
-ns32k_register_raw_size (int regno)
-{
- /* All registers are 4 bytes, except for the doubled floating
- registers. */
-
- return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
-}
-
-static int
-ns32k_register_virtual_size (int regno)
-{
- return ((regno >= NS32K_LP0_REGNUM) ? 8 : 4);
-}
-
-static struct type *
-ns32k_register_virtual_type (int regno)
-{
- if (regno < FP0_REGNUM)
- return (builtin_type_int);
-
- if (regno < FP0_REGNUM + 8)
- return (builtin_type_float);
-
- if (regno < NS32K_LP0_REGNUM)
- return (builtin_type_int);
-
- return (builtin_type_double);
-}
-
-/* Immediately after a function call, return the saved PC. Can't
- always go through the frames for this because on some systems,
- the new frame is not set up until the new function executes some
- instructions. */
-
-static CORE_ADDR
-ns32k_saved_pc_after_call (struct frame_info *frame)
-{
- return (read_memory_integer (read_register (SP_REGNUM), 4));
-}
-
-/* Advance PC across any function entry prologue instructions
- to reach some "real" code. */
-
-static CORE_ADDR
-umax_skip_prologue (CORE_ADDR pc)
-{
- unsigned char op = read_memory_integer (pc, 1);
- if (op == 0x82)
- {
- op = read_memory_integer (pc + 2, 1);
- if ((op & 0x80) == 0)
- pc += 3;
- else if ((op & 0xc0) == 0x80)
- pc += 4;
- else
- pc += 6;
- }
- return pc;
-}
-\f
-static const unsigned char *
-ns32k_breakpoint_from_pc (CORE_ADDR *pcp, int *lenp)
-{
- static const unsigned char breakpoint_insn[] = { 0xf2 };
-
- *lenp = sizeof (breakpoint_insn);
- return breakpoint_insn;
-}
-
-/* Return number of args passed to a frame.
- Can return -1, meaning no way to tell.
- Encore's C compiler often reuses same area on stack for args,
- so this will often not work properly. If the arg names
- are known, it's likely most of them will be printed. */
-
-static int
-umax_frame_num_args (struct frame_info *fi)
-{
- int numargs;
- CORE_ADDR pc;
- CORE_ADDR enter_addr;
- unsigned int insn;
- unsigned int addr_mode;
- int width;
-
- numargs = -1;
- enter_addr = ns32k_get_enter_addr (get_frame_pc (fi));
- if (enter_addr > 0)
- {
- pc = ((enter_addr == 1)
- ? DEPRECATED_SAVED_PC_AFTER_CALL (fi)
- : DEPRECATED_FRAME_SAVED_PC (fi));
- insn = read_memory_integer (pc, 2);
- addr_mode = (insn >> 11) & 0x1f;
- insn = insn & 0x7ff;
- if ((insn & 0x7fc) == 0x57c
- && addr_mode == 0x14) /* immediate */
- {
- if (insn == 0x57c) /* adjspb */
- width = 1;
- else if (insn == 0x57d) /* adjspw */
- width = 2;
- else if (insn == 0x57f) /* adjspd */
- width = 4;
- else
- internal_error (__FILE__, __LINE__, "bad else");
- numargs = read_memory_integer (pc + 2, width);
- if (width > 1)
- flip_bytes (&numargs, width);
- numargs = -sign_extend (numargs, width * 8) / 4;
- }
- }
- return numargs;
-}
-
-static int
-sign_extend (int value, int bits)
-{
- value = value & ((1 << bits) - 1);
- return (value & (1 << (bits - 1))
- ? value | (~((1 << bits) - 1))
- : value);
-}
-
-static void
-flip_bytes (void *p, int count)
-{
- char tmp;
- char *ptr = 0;
-
- while (count > 0)
- {
- tmp = *ptr;
- ptr[0] = ptr[count - 1];
- ptr[count - 1] = tmp;
- ptr++;
- count -= 2;
- }
-}
-
-/* Return the number of locals in the current frame given a
- pc pointing to the enter instruction. This is used by
- ns32k_frame_init_saved_regs. */
-
-static int
-ns32k_localcount (CORE_ADDR enter_pc)
-{
- unsigned char localtype;
- int localcount;
-
- localtype = read_memory_integer (enter_pc + 2, 1);
- if ((localtype & 0x80) == 0)
- localcount = localtype;
- else if ((localtype & 0xc0) == 0x80)
- localcount = (((localtype & 0x3f) << 8)
- | (read_memory_integer (enter_pc + 3, 1) & 0xff));
- else
- localcount = (((localtype & 0x3f) << 24)
- | ((read_memory_integer (enter_pc + 3, 1) & 0xff) << 16)
- | ((read_memory_integer (enter_pc + 4, 1) & 0xff) << 8)
- | (read_memory_integer (enter_pc + 5, 1) & 0xff));
- return localcount;
-}
-
-
-/* Nonzero if instruction at PC is a return instruction. */
-
-static int
-ns32k_about_to_return (CORE_ADDR pc)
-{
- return (read_memory_integer (pc, 1) == 0x12);
-}
-
-/* Get the address of the enter opcode for this function, if it is active.
- Returns positive address > 1 if pc is between enter/exit,
- 1 if pc before enter or after exit, 0 otherwise. */
-static CORE_ADDR
-ns32k_get_enter_addr (CORE_ADDR pc)
-{
- CORE_ADDR enter_addr;
- unsigned char op;
-
- if (pc == 0)
- return 0;
-
- if (ns32k_about_to_return (pc))
- return 1; /* after exit */
-
- enter_addr = get_pc_function_start (pc);
-
- if (pc == enter_addr)
- return 1; /* before enter */
-
- op = read_memory_integer (enter_addr, 1);
-
- if (op != 0x82)
- return 0; /* function has no enter/exit */
-
- return enter_addr; /* pc is between enter and exit */
-}
-
-static CORE_ADDR
-ns32k_frame_chain (struct frame_info *frame)
-{
- /* In the case of the NS32000 series, the frame's nominal address is the
- FP value, and that address is saved at the previous FP value as a
- 4-byte word. */
- return (read_memory_integer (get_frame_base (frame), 4));
-}
-
-
-static CORE_ADDR
-ns32k_sigtramp_saved_pc (struct frame_info *frame)
-{
- CORE_ADDR sigcontext_addr;
- char *buf;
- int ptrbytes = TYPE_LENGTH (builtin_type_void_func_ptr);
- int sigcontext_offs = (2 * TARGET_INT_BIT) / TARGET_CHAR_BIT;
-
- buf = alloca (ptrbytes);
- /* Get sigcontext address, it is the third parameter on the stack. */
- if (get_next_frame (frame))
- sigcontext_addr = read_memory_typed_address
- (DEPRECATED_FRAME_ARGS_ADDRESS (get_next_frame (frame)) + FRAME_ARGS_SKIP + sigcontext_offs,
- builtin_type_void_data_ptr);
- else
- sigcontext_addr = read_memory_typed_address
- (read_register (SP_REGNUM) + sigcontext_offs, builtin_type_void_data_ptr);
-
- /* Offset to saved PC in sigcontext, from <machine/signal.h>. Don't
- cause a memory_error when accessing sigcontext in case the stack
- layout has changed or the stack is corrupt. */
- target_read_memory (sigcontext_addr + 20, buf, ptrbytes);
- return extract_typed_address (buf, builtin_type_void_func_ptr);
-}
-
-static CORE_ADDR
-ns32k_frame_saved_pc (struct frame_info *frame)
-{
- if ((get_frame_type (frame) == SIGTRAMP_FRAME))
- return (ns32k_sigtramp_saved_pc (frame)); /* XXXJRT */
-
- return (read_memory_integer (get_frame_base (frame) + 4, 4));
-}
-
-static CORE_ADDR
-ns32k_frame_args_address (struct frame_info *frame)
-{
- if (ns32k_get_enter_addr (get_frame_pc (frame)) > 1)
- return (get_frame_base (frame));
-
- return (read_register (SP_REGNUM) - 4);
-}
-
-/* Code to initialize the addresses of the saved registers of frame described
- by FRAME_INFO. This includes special registers such as pc and fp saved in
- special ways in the stack frame. sp is even more special: the address we
- return for it IS the sp for the next frame. */
-
-static void
-ns32k_frame_init_saved_regs (struct frame_info *frame)
-{
- int regmask, regnum;
- int localcount;
- CORE_ADDR enter_addr, next_addr;
-
- if (deprecated_get_frame_saved_regs (frame))
- return;
-
- frame_saved_regs_zalloc (frame);
-
- enter_addr = ns32k_get_enter_addr (get_frame_pc (frame));
- if (enter_addr > 1)
- {
- regmask = read_memory_integer (enter_addr + 1, 1) & 0xff;
- localcount = ns32k_localcount (enter_addr);
- next_addr = get_frame_base (frame) + localcount;
-
- for (regnum = 0; regnum < 8; regnum++)
- {
- if (regmask & (1 << regnum))
- deprecated_get_frame_saved_regs (frame)[regnum] = next_addr -= 4;
- }
-
- deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = get_frame_base (frame) + 4;
- deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = get_frame_base (frame) + 4;
- deprecated_get_frame_saved_regs (frame)[DEPRECATED_FP_REGNUM] = read_memory_integer (get_frame_base (frame), 4);
- }
- else if (enter_addr == 1)
- {
- CORE_ADDR sp = read_register (SP_REGNUM);
- deprecated_get_frame_saved_regs (frame)[PC_REGNUM] = sp;
- deprecated_get_frame_saved_regs (frame)[SP_REGNUM] = sp + 4;
- }
-}
-
-static void
-ns32k_pop_frame (void)
-{
- struct frame_info *frame = get_current_frame ();
- CORE_ADDR fp;
- int regnum;
-
- fp = get_frame_base (frame);
- DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
-
- for (regnum = 0; regnum < 8; regnum++)
- if (deprecated_get_frame_saved_regs (frame)[regnum])
- write_register (regnum,
- read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum], 4));
-
- write_register (DEPRECATED_FP_REGNUM, read_memory_integer (fp, 4));
- write_register (PC_REGNUM, read_memory_integer (fp + 4, 4));
- write_register (SP_REGNUM, fp + 8);
- flush_cached_frames ();
-}
-
-static CORE_ADDR
-ns32k_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
-{
- /* ASSERT ( !struct_return); */
- int i;
- for (i = nargs - 1; i >= 0; i--)
- {
- struct value *arg = args[i];
- int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
- int container_len = len;
- int offset;
-
- /* Are we going to put it at the high or low end of the
- container? */
- if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
- offset = container_len - len;
- else
- offset = 0;
-
- /* Stack grows downward. */
- sp -= container_len;
- write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
- }
- return sp;
-}
-
-\f
-static void
-ns32k_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
- /* On this machine, this is a no-op (Encore Umax didn't use GCC). */
-}
-
-static void
-ns32k_extract_return_value (struct type *valtype, char *regbuf, char *valbuf)
-{
- memcpy (valbuf,
- regbuf + DEPRECATED_REGISTER_BYTE (TYPE_CODE (valtype) == TYPE_CODE_FLT ?
- FP0_REGNUM : 0), TYPE_LENGTH (valtype));
-}
-
-static void
-ns32k_store_return_value (struct type *valtype, char *valbuf)
-{
- deprecated_write_register_bytes (TYPE_CODE (valtype) == TYPE_CODE_FLT
- ? FP0_REGNUM : 0, valbuf,
- TYPE_LENGTH (valtype));
-}
-
-void
-ns32k_gdbarch_init_32082 (struct gdbarch *gdbarch)
-{
- set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32082);
-
- set_gdbarch_register_name (gdbarch, ns32k_register_name_32082);
- set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32082);
-}
-
-void
-ns32k_gdbarch_init_32382 (struct gdbarch *gdbarch)
-{
- set_gdbarch_num_regs (gdbarch, NS32K_NUM_REGS_32382);
-
- set_gdbarch_register_name (gdbarch, ns32k_register_name_32382);
- set_gdbarch_deprecated_register_byte (gdbarch, ns32k_register_byte_32382);
-}
-
-/* Initialize the current architecture based on INFO. If possible, re-use an
- architecture from ARCHES, which is a list of architectures already created
- during this debugging session.
-
- Called e.g. at program startup, when reading a core file, and when reading
- a binary file. */
-
-static struct gdbarch *
-ns32k_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-{
- struct gdbarch *gdbarch;
-
- /* If there is already a candidate, use it. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return arches->gdbarch;
-
- gdbarch = gdbarch_alloc (&info, NULL);
-
- /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
- ready to unwind the PC first (see frame.c:get_prev_frame()). */
- set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
-
- /* Register info */
- ns32k_gdbarch_init_32082 (gdbarch);
- set_gdbarch_num_regs (gdbarch, NS32K_SP_REGNUM);
- set_gdbarch_num_regs (gdbarch, NS32K_FP_REGNUM);
- set_gdbarch_num_regs (gdbarch, NS32K_PC_REGNUM);
- set_gdbarch_num_regs (gdbarch, NS32K_PS_REGNUM);
-
- set_gdbarch_deprecated_register_size (gdbarch, NS32K_REGISTER_SIZE);
- set_gdbarch_deprecated_register_raw_size (gdbarch, ns32k_register_raw_size);
- set_gdbarch_deprecated_register_virtual_size (gdbarch, ns32k_register_virtual_size);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, ns32k_register_virtual_type);
-
- /* Frame and stack info */
- set_gdbarch_skip_prologue (gdbarch, umax_skip_prologue);
- set_gdbarch_deprecated_saved_pc_after_call (gdbarch, ns32k_saved_pc_after_call);
-
- set_gdbarch_frame_num_args (gdbarch, umax_frame_num_args);
-
- set_gdbarch_deprecated_frame_chain (gdbarch, ns32k_frame_chain);
- set_gdbarch_deprecated_frame_saved_pc (gdbarch, ns32k_frame_saved_pc);
-
- set_gdbarch_deprecated_frame_args_address (gdbarch, ns32k_frame_args_address);
-
- set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, ns32k_frame_init_saved_regs);
-
- set_gdbarch_frame_args_skip (gdbarch, 8);
-
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-
- /* Return value info */
- set_gdbarch_deprecated_store_struct_return (gdbarch, ns32k_store_struct_return);
- set_gdbarch_deprecated_extract_return_value (gdbarch, ns32k_extract_return_value);
- set_gdbarch_deprecated_store_return_value (gdbarch, ns32k_store_return_value);
-
- /* Call dummy info */
- set_gdbarch_deprecated_pop_frame (gdbarch, ns32k_pop_frame);
- set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
- set_gdbarch_deprecated_push_arguments (gdbarch, ns32k_push_arguments);
-
- /* Breakpoint info */
- set_gdbarch_breakpoint_from_pc (gdbarch, ns32k_breakpoint_from_pc);
-
- /* Should be using push_dummy_call. */
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
-
- set_gdbarch_print_insn (gdbarch, print_insn_ns32k);
-
- /* Hook in OS ABI-specific overrides, if they have been registered. */
- gdbarch_init_osabi (info, gdbarch);
-
- return (gdbarch);
-}
-
-extern initialize_file_ftype _initialize_ns32k_tdep; /* -Wmissing-prototypes */
-
-void
-_initialize_ns32k_tdep (void)
-{
- gdbarch_register (bfd_arch_ns32k, ns32k_gdbarch_init, NULL);
-
-}
+++ /dev/null
-/* Target-dependent definitions for GDB on NS32000 systems.
- Copyright 1987, 1989, 1991, 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003
- 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. */
-
-#ifndef NS32K_TDEP_H
-#define NS32K_TDEP_H
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define NS32K_R0_REGNUM 0 /* General register 0 */
-#define NS32K_FP0_REGNUM 8 /* Floating point register 0 */
-#define NS32K_SP_REGNUM 16 /* Contains address of top of stack */
-#define NS32K_AP_REGNUM NS32K_FP_REGNUM
-#define NS32K_FP_REGNUM 17 /* Contains address of executing stack frame */
-#define NS32K_PC_REGNUM 18 /* Contains program counter */
-#define NS32K_PS_REGNUM 19 /* Contains processor status */
-#define NS32K_FPS_REGNUM 20 /* Floating point status register */
-#define NS32K_LP0_REGNUM 21 /* Double register 0 (same as FP0) */
-
-#define NS32K_NUM_REGS_32082 25
-#define NS32K_REGISTER_BYTES_32082 \
- ((NS32K_NUM_REGS_32082 - 4) * 4 /* size of general purpose regs */ \
- + 4 * 8 /* size of floating point regs */)
-
-#define NS32K_NUM_REGS_32382 29
-#define NS32K_REGISTER_BYTES_32382 \
- ((NS32K_NUM_REGS_32382 - 4) * 4 /* size of general purpose regs */ \
- + 8 * 8 /* size of floating point regs */)
-
-#define NS32K_REGISTER_SIZE 4
-
-void ns32k_gdbarch_init_32082 (struct gdbarch *);
-void ns32k_gdbarch_init_32382 (struct gdbarch *);
-
-#endif /* NS32K_TDEP_H */
+++ /dev/null
-/* Functions specific to running gdb native on an ns32k running NetBSD
-
- Copyright 1989, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001,
- 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. */
-
-#include <sys/types.h>
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-#include <machine/frame.h>
-#include <machine/pcb.h>
-
-#include "defs.h"
-#include "inferior.h"
-#include "target.h"
-#include "gdbcore.h"
-#include "regcache.h"
-
-#define RF(dst, src) \
- memcpy(&deprecated_registers[DEPRECATED_REGISTER_BYTE(dst)], &src, sizeof(src))
-
-#define RS(src, dst) \
- memcpy(&dst, &deprecated_registers[DEPRECATED_REGISTER_BYTE(src)], sizeof(dst))
-
-void
-fetch_inferior_registers (int regno)
-{
- struct reg inferior_registers;
- struct fpreg inferior_fpregisters;
-
- ptrace (PT_GETREGS, PIDGET (inferior_ptid),
- (PTRACE_TYPE_ARG3) & inferior_registers, 0);
- ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
- (PTRACE_TYPE_ARG3) & inferior_fpregisters, 0);
-
- RF (R0_REGNUM + 0, inferior_registers.r_r0);
- RF (R0_REGNUM + 1, inferior_registers.r_r1);
- RF (R0_REGNUM + 2, inferior_registers.r_r2);
- RF (R0_REGNUM + 3, inferior_registers.r_r3);
- RF (R0_REGNUM + 4, inferior_registers.r_r4);
- RF (R0_REGNUM + 5, inferior_registers.r_r5);
- RF (R0_REGNUM + 6, inferior_registers.r_r6);
- RF (R0_REGNUM + 7, inferior_registers.r_r7);
-
- RF (SP_REGNUM, inferior_registers.r_sp);
- RF (DEPRECATED_FP_REGNUM, inferior_registers.r_fp);
- RF (PC_REGNUM, inferior_registers.r_pc);
- RF (PS_REGNUM, inferior_registers.r_psr);
-
- RF (FPS_REGNUM, inferior_fpregisters.r_fsr);
- RF (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
- RF (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
- RF (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
- RF (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
- RF (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
- RF (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
- RF (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
- RF (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
- deprecated_registers_fetched ();
-}
-
-void
-store_inferior_registers (int regno)
-{
- struct reg inferior_registers;
- struct fpreg inferior_fpregisters;
-
- RS (R0_REGNUM + 0, inferior_registers.r_r0);
- RS (R0_REGNUM + 1, inferior_registers.r_r1);
- RS (R0_REGNUM + 2, inferior_registers.r_r2);
- RS (R0_REGNUM + 3, inferior_registers.r_r3);
- RS (R0_REGNUM + 4, inferior_registers.r_r4);
- RS (R0_REGNUM + 5, inferior_registers.r_r5);
- RS (R0_REGNUM + 6, inferior_registers.r_r6);
- RS (R0_REGNUM + 7, inferior_registers.r_r7);
-
- RS (SP_REGNUM, inferior_registers.r_sp);
- RS (DEPRECATED_FP_REGNUM, inferior_registers.r_fp);
- RS (PC_REGNUM, inferior_registers.r_pc);
- RS (PS_REGNUM, inferior_registers.r_psr);
-
- RS (FPS_REGNUM, inferior_fpregisters.r_fsr);
- RS (FP0_REGNUM + 0, inferior_fpregisters.r_freg[0]);
- RS (FP0_REGNUM + 2, inferior_fpregisters.r_freg[2]);
- RS (FP0_REGNUM + 4, inferior_fpregisters.r_freg[4]);
- RS (FP0_REGNUM + 6, inferior_fpregisters.r_freg[6]);
- RS (LP0_REGNUM + 1, inferior_fpregisters.r_freg[1]);
- RS (LP0_REGNUM + 3, inferior_fpregisters.r_freg[3]);
- RS (LP0_REGNUM + 5, inferior_fpregisters.r_freg[5]);
- RS (LP0_REGNUM + 7, inferior_fpregisters.r_freg[7]);
-
- ptrace (PT_SETREGS, PIDGET (inferior_ptid),
- (PTRACE_TYPE_ARG3) & inferior_registers, 0);
- ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
- (PTRACE_TYPE_ARG3) & inferior_fpregisters, 0);
-}
-\f
-
-/* XXX - Add this to machine/regs.h instead? */
-struct coreregs
-{
- struct reg intreg;
- struct fpreg freg;
-};
-
-/* Get registers from a core file. REG_ADDR is unused. */
-static void
-fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
- unsigned int reg_addr)
-{
- struct coreregs *core_reg;
-
- core_reg = (struct coreregs *) core_reg_sect;
-
- /*
- * We have *all* registers
- * in the first core section.
- * Ignore which.
- */
-
- if (core_reg_size < sizeof (*core_reg))
- {
- fprintf_unfiltered (gdb_stderr, "Couldn't read regs from core file\n");
- return;
- }
-
- /* Integer registers */
- RF (R0_REGNUM + 0, core_reg->intreg.r_r0);
- RF (R0_REGNUM + 1, core_reg->intreg.r_r1);
- RF (R0_REGNUM + 2, core_reg->intreg.r_r2);
- RF (R0_REGNUM + 3, core_reg->intreg.r_r3);
- RF (R0_REGNUM + 4, core_reg->intreg.r_r4);
- RF (R0_REGNUM + 5, core_reg->intreg.r_r5);
- RF (R0_REGNUM + 6, core_reg->intreg.r_r6);
- RF (R0_REGNUM + 7, core_reg->intreg.r_r7);
-
- RF (SP_REGNUM, core_reg->intreg.r_sp);
- RF (DEPRECATED_FP_REGNUM, core_reg->intreg.r_fp);
- RF (PC_REGNUM, core_reg->intreg.r_pc);
- RF (PS_REGNUM, core_reg->intreg.r_psr);
-
- /* Floating point registers */
- RF (FPS_REGNUM, core_reg->freg.r_fsr);
- RF (FP0_REGNUM + 0, core_reg->freg.r_freg[0]);
- RF (FP0_REGNUM + 2, core_reg->freg.r_freg[2]);
- RF (FP0_REGNUM + 4, core_reg->freg.r_freg[4]);
- RF (FP0_REGNUM + 6, core_reg->freg.r_freg[6]);
- RF (LP0_REGNUM + 1, core_reg->freg.r_freg[1]);
- RF (LP0_REGNUM + 3, core_reg->freg.r_freg[3]);
- RF (LP0_REGNUM + 5, core_reg->freg.r_freg[5]);
- RF (LP0_REGNUM + 7, core_reg->freg.r_freg[7]);
- deprecated_registers_fetched ();
-}
-
-/* Register that we are able to handle ns32knbsd core file formats.
- FIXME: is this really bfd_target_unknown_flavour? */
-
-static struct core_fns nat_core_fns =
-{
- bfd_target_unknown_flavour, /* core_flavour */
- default_check_format, /* check_format */
- default_core_sniffer, /* core_sniffer */
- fetch_core_registers, /* core_read_registers */
- NULL /* next */
-};
-
-void
-_initialize_ns32knbsd_nat (void)
-{
- deprecated_add_core_fns (&nat_core_fns);
-}
-\f
-
-/*
- * kernel_u_size() is not helpful on NetBSD because
- * the "u" struct is NOT in the core dump file.
- */
-
-#ifdef FETCH_KCORE_REGISTERS
-/*
- * Get registers from a kernel crash dump or live kernel.
- * Called by kcore-nbsd.c:get_kcore_registers().
- */
-void
-fetch_kcore_registers (struct pcb *pcb)
-{
- struct switchframe sf;
- struct reg intreg;
- int dummy;
-
- /* Integer registers */
- if (target_read_memory ((CORE_ADDR) pcb->pcb_ksp, (char *) &sf, sizeof sf))
- error ("Cannot read integer registers.");
-
- /* We use the psr at kernel entry */
- if (target_read_memory ((CORE_ADDR) pcb->pcb_onstack, (char *) &intreg, sizeof intreg))
- error ("Cannot read processor status register.");
-
- dummy = 0;
- RF (R0_REGNUM + 0, dummy);
- RF (R0_REGNUM + 1, dummy);
- RF (R0_REGNUM + 2, dummy);
- RF (R0_REGNUM + 3, sf.sf_r3);
- RF (R0_REGNUM + 4, sf.sf_r4);
- RF (R0_REGNUM + 5, sf.sf_r5);
- RF (R0_REGNUM + 6, sf.sf_r6);
- RF (R0_REGNUM + 7, sf.sf_r7);
-
- dummy = pcb->pcb_kfp + 8;
- RF (SP_REGNUM, dummy);
- RF (DEPRECATED_FP_REGNUM, sf.sf_fp);
- RF (PC_REGNUM, sf.sf_pc);
- RF (PS_REGNUM, intreg.r_psr);
-
- /* Floating point registers */
- RF (FPS_REGNUM, pcb->pcb_fsr);
- RF (FP0_REGNUM + 0, pcb->pcb_freg[0]);
- RF (FP0_REGNUM + 2, pcb->pcb_freg[2]);
- RF (FP0_REGNUM + 4, pcb->pcb_freg[4]);
- RF (FP0_REGNUM + 6, pcb->pcb_freg[6]);
- RF (LP0_REGNUM + 1, pcb->pcb_freg[1]);
- RF (LP0_REGNUM + 3, pcb->pcb_freg[3]);
- RF (LP0_REGNUM + 5, pcb->pcb_freg[5]);
- RF (LP0_REGNUM + 7, pcb->pcb_freg[7]);
- deprecated_registers_fetched ();
-}
-#endif /* FETCH_KCORE_REGISTERS */
-
-void
-clear_regs (void)
-{
- double zero = 0.0;
- int null = 0;
-
- /* Integer registers */
- RF (R0_REGNUM + 0, null);
- RF (R0_REGNUM + 1, null);
- RF (R0_REGNUM + 2, null);
- RF (R0_REGNUM + 3, null);
- RF (R0_REGNUM + 4, null);
- RF (R0_REGNUM + 5, null);
- RF (R0_REGNUM + 6, null);
- RF (R0_REGNUM + 7, null);
-
- RF (SP_REGNUM, null);
- RF (DEPRECATED_FP_REGNUM, null);
- RF (PC_REGNUM, null);
- RF (PS_REGNUM, null);
-
- /* Floating point registers */
- RF (FPS_REGNUM, zero);
- RF (FP0_REGNUM + 0, zero);
- RF (FP0_REGNUM + 2, zero);
- RF (FP0_REGNUM + 4, zero);
- RF (FP0_REGNUM + 6, zero);
- RF (LP0_REGNUM + 0, zero);
- RF (LP0_REGNUM + 1, zero);
- RF (LP0_REGNUM + 2, zero);
- RF (LP0_REGNUM + 3, zero);
- return;
-}
-
-/* Return number of args passed to a frame.
- Can return -1, meaning no way to tell. */
-
-int
-frame_num_args (struct frame_info *fi)
-{
- CORE_ADDR enter_addr;
- CORE_ADDR argp;
- int inst;
- int args;
- int i;
-
- if (read_memory_integer (fi->frame, 4) == 0 && fi->pc < 0x10000)
- {
- /* main is always called with three args */
- return (3);
- }
- enter_addr = ns32k_get_enter_addr (fi->pc);
- if (enter_addr = 0)
- return (-1);
- argp = (enter_addr == 1
- ? DEPRECATED_SAVED_PC_AFTER_CALL (fi)
- : DEPRECATED_FRAME_SAVED_PC (fi));
- for (i = 0; i < 16; i++)
- {
- /*
- * After a bsr gcc may emit the following instructions
- * to remove the arguments from the stack:
- * cmpqd 0,tos - to remove 4 bytes from the stack
- * cmpd tos,tos - to remove 8 bytes from the stack
- * adjsp[bwd] -n - to remove n bytes from the stack
- * Gcc sometimes delays emitting these instructions and
- * may even throw a branch between our feet.
- */
- inst = read_memory_integer (argp, 4);
- args = read_memory_integer (argp + 2, 4);
- if ((inst & 0xff) == 0xea)
- { /* br */
- args = ((inst >> 8) & 0xffffff) | (args << 24);
- if (args & 0x80)
- {
- if (args & 0x40)
- {
- args = ntohl (args);
- }
- else
- {
- args = ntohs (args & 0xffff);
- if (args & 0x2000)
- args |= 0xc000;
- }
- }
- else
- {
- args = args & 0xff;
- if (args & 0x40)
- args |= 0x80;
- }
- argp += args;
- continue;
- }
- if ((inst & 0xffff) == 0xb81f) /* cmpqd 0,tos */
- return (1);
- else if ((inst & 0xffff) == 0xbdc7) /* cmpd tos,tos */
- return (2);
- else if ((inst & 0xfffc) == 0xa57c)
- { /* adjsp[bwd] */
- switch (inst & 3)
- {
- case 0:
- args = ((args & 0xff) + 0x80);
- break;
- case 1:
- args = ((ntohs (args) & 0xffff) + 0x8000);
- break;
- case 3:
- args = -ntohl (args);
- break;
- default:
- return (-1);
- }
- if (args / 4 > 10 || (args & 3) != 0)
- continue;
- return (args / 4);
- }
- argp += 1;
- }
- return (-1);
-}
+++ /dev/null
-/* Target-dependent code for NS32000 systems running NetBSD.
- Copyright 2002, 2003 Free Software Foundation, Inc.
- Contributed by Wasabi Systems, 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. */
-
-#include "defs.h"
-#include "osabi.h"
-
-#include "ns32k-tdep.h"
-#include "gdb_string.h"
-
-static void
-ns32knbsd_init_abi_common (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- /* We only support machines with the 32382 FPU. */
- ns32k_gdbarch_init_32382 (gdbarch);
-}
-
-static void
-ns32knbsd_init_abi_aout (struct gdbarch_info info,
- struct gdbarch *gdbarch)
-{
- ns32knbsd_init_abi_common (info, gdbarch);
-}
-
-static enum gdb_osabi
-ns32knbsd_aout_osabi_sniffer (bfd *abfd)
-{
- if (strcmp (bfd_get_target (abfd), "a.out-ns32k-netbsd") == 0)
- return GDB_OSABI_NETBSD_AOUT;
-
- return GDB_OSABI_UNKNOWN;
-}
-
-extern initialize_file_ftype _initialize_ns32knbsd_tdep; /* -Wmissing-prototypes */
-
-void
-_initialize_ns32knbsd_tdep (void)
-{
- gdbarch_register_osabi_sniffer (bfd_arch_ns32k, bfd_target_aout_flavour,
- ns32knbsd_aout_osabi_sniffer);
-
- gdbarch_register_osabi (bfd_arch_ns32k, 0, GDB_OSABI_NETBSD_AOUT,
- ns32knbsd_init_abi_aout);
-}
+++ /dev/null
-/* Target-dependent code for the NEC V850 for GDB, the GNU debugger.
-
- Copyright 1996, 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. */
-
-#include "defs.h"
-#include "frame.h"
-#include "inferior.h"
-#include "target.h"
-#include "value.h"
-#include "bfd.h"
-#include "gdb_string.h"
-#include "gdbcore.h"
-#include "objfiles.h"
-#include "arch-utils.h"
-#include "regcache.h"
-#include "symtab.h"
-#include "dis-asm.h"
-
-struct gdbarch_tdep
-{
- /* gdbarch target dependent data here. Currently unused for v850. */
-};
-
-/* Extra info which is saved in each frame_info. */
-struct frame_extra_info
-{
-};
-
-enum {
- E_R0_REGNUM,
- E_R1_REGNUM,
- E_R2_REGNUM, E_SAVE1_START_REGNUM = E_R2_REGNUM, E_SAVE1_END_REGNUM = E_R2_REGNUM,
- E_R3_REGNUM, E_SP_REGNUM = E_R3_REGNUM,
- E_R4_REGNUM,
- E_R5_REGNUM,
- E_R6_REGNUM, E_ARG0_REGNUM = E_R6_REGNUM,
- E_R7_REGNUM,
- E_R8_REGNUM,
- E_R9_REGNUM, E_ARGLAST_REGNUM = E_R9_REGNUM,
- E_R10_REGNUM, E_V0_REGNUM = E_R10_REGNUM,
- E_R11_REGNUM, E_V1_REGNUM = E_R11_REGNUM,
- E_R12_REGNUM,
- E_R13_REGNUM,
- E_R14_REGNUM,
- E_R15_REGNUM,
- E_R16_REGNUM,
- E_R17_REGNUM,
- E_R18_REGNUM,
- E_R19_REGNUM,
- E_R20_REGNUM, E_SAVE2_START_REGNUM = E_R20_REGNUM,
- E_R21_REGNUM,
- E_R22_REGNUM,
- E_R23_REGNUM,
- E_R24_REGNUM,
- E_R25_REGNUM,
- E_R26_REGNUM,
- E_R27_REGNUM,
- E_R28_REGNUM,
- E_R29_REGNUM, E_SAVE2_END_REGNUM = E_R29_REGNUM, E_FP_RAW_REGNUM = E_R29_REGNUM,
- E_R30_REGNUM, E_EP_REGNUM = E_R30_REGNUM,
- E_R31_REGNUM, E_SAVE3_START_REGNUM = E_R31_REGNUM, E_SAVE3_END_REGNUM = E_R31_REGNUM, E_RP_REGNUM = E_R31_REGNUM,
- E_R32_REGNUM, E_SR0_REGNUM = E_R32_REGNUM,
- E_R33_REGNUM,
- E_R34_REGNUM,
- E_R35_REGNUM,
- E_R36_REGNUM,
- E_R37_REGNUM, E_PS_REGNUM = E_R37_REGNUM,
- E_R38_REGNUM,
- E_R39_REGNUM,
- E_R40_REGNUM,
- E_R41_REGNUM,
- E_R42_REGNUM,
- E_R43_REGNUM,
- E_R44_REGNUM,
- E_R45_REGNUM,
- E_R46_REGNUM,
- E_R47_REGNUM,
- E_R48_REGNUM,
- E_R49_REGNUM,
- E_R50_REGNUM,
- E_R51_REGNUM,
- E_R52_REGNUM, E_CTBP_REGNUM = E_R52_REGNUM,
- E_R53_REGNUM,
- E_R54_REGNUM,
- E_R55_REGNUM,
- E_R56_REGNUM,
- E_R57_REGNUM,
- E_R58_REGNUM,
- E_R59_REGNUM,
- E_R60_REGNUM,
- E_R61_REGNUM,
- E_R62_REGNUM,
- E_R63_REGNUM,
- E_R64_REGNUM, E_PC_REGNUM = E_R64_REGNUM,
- E_R65_REGNUM, E_FP_REGNUM = E_R65_REGNUM,
- E_NUM_REGS
-};
-
-enum
-{
- v850_reg_size = 4
-};
-
-/* Size of all registers as a whole. */
-enum
-{
- E_ALL_REGS_SIZE = (E_NUM_REGS) * v850_reg_size
-};
-
-/* Size of return datatype which fits into all return registers. */
-enum
-{
- E_MAX_RETTYPE_SIZE_IN_REGS = 2 * v850_reg_size
-};
-
-static LONGEST call_dummy_nil[] = {0};
-
-static char *v850_generic_reg_names[] =
-{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
- "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
- "sr16", "sr17", "sr18", "sr19", "sr20", "sr21", "sr22", "sr23",
- "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
- "pc", "fp"
-};
-
-static char *v850e_reg_names[] =
-{
- "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
- "eipc", "eipsw", "fepc", "fepsw", "ecr", "psw", "sr6", "sr7",
- "sr8", "sr9", "sr10", "sr11", "sr12", "sr13", "sr14", "sr15",
- "ctpc", "ctpsw", "dbpc", "dbpsw", "ctbp", "sr21", "sr22", "sr23",
- "sr24", "sr25", "sr26", "sr27", "sr28", "sr29", "sr30", "sr31",
- "pc", "fp"
-};
-
-char **v850_register_names = v850_generic_reg_names;
-
-struct
- {
- char **regnames;
- int mach;
- }
-v850_processor_type_table[] =
-{
- {
- v850_generic_reg_names, bfd_mach_v850
- }
- ,
- {
- v850e_reg_names, bfd_mach_v850e
- }
- ,
- {
- v850e_reg_names, bfd_mach_v850e1
- }
- ,
- {
- NULL, 0
- }
-};
-
-/* Info gleaned from scanning a function's prologue. */
-
-struct pifsr /* Info about one saved reg */
- {
- int framereg; /* Frame reg (SP or FP) */
- int offset; /* Offset from framereg */
- int cur_frameoffset; /* Current frameoffset */
- int reg; /* Saved register number */
- };
-
-struct prologue_info
- {
- int framereg;
- int frameoffset;
- int start_function;
- struct pifsr *pifsrs;
- };
-
-static CORE_ADDR v850_scan_prologue (CORE_ADDR pc, struct prologue_info *fs);
-
-/* Function: v850_register_name
- Returns the name of the v850/v850e register N. */
-
-static const char *
-v850_register_name (int regnum)
-{
- if (regnum < 0 || regnum >= E_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "v850_register_name: illegal register number %d",
- regnum);
- else
- return v850_register_names[regnum];
-
-}
-
-/* Function: v850_register_byte
- Returns the byte position in the register cache for register N. */
-
-static int
-v850_register_byte (int regnum)
-{
- if (regnum < 0 || regnum >= E_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "v850_register_byte: illegal register number %d",
- regnum);
- else
- return regnum * v850_reg_size;
-}
-
-/* Function: v850_register_raw_size
- Returns the number of bytes occupied by the register on the target. */
-
-static int
-v850_register_raw_size (int regnum)
-{
- if (regnum < 0 || regnum >= E_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "v850_register_raw_size: illegal register number %d",
- regnum);
- /* Only the PC has 4 Byte, all other registers 2 Byte. */
- else
- return v850_reg_size;
-}
-
-/* Function: v850_reg_virtual_type
- Returns the default type for register N. */
-
-static struct type *
-v850_reg_virtual_type (int regnum)
-{
- if (regnum < 0 || regnum >= E_NUM_REGS)
- internal_error (__FILE__, __LINE__,
- "v850_register_virtual_type: illegal register number %d",
- regnum);
- else if (regnum == E_PC_REGNUM)
- return builtin_type_uint32;
- else
- return builtin_type_int32;
-}
-
-static int
-v850_type_is_scalar (struct type *t)
-{
- return (TYPE_CODE (t) != TYPE_CODE_STRUCT
- && TYPE_CODE (t) != TYPE_CODE_UNION
- && TYPE_CODE (t) != TYPE_CODE_ARRAY);
-}
-
-/* Should call_function allocate stack space for a struct return? */
-static int
-v850_use_struct_convention (int gcc_p, struct type *type)
-{
- /* According to ABI:
- * return TYPE_LENGTH (type) > 8);
- */
-
- /* Current implementation in gcc: */
-
- int i;
- struct type *fld_type, *tgt_type;
-
- /* 1. The value is greater than 8 bytes -> returned by copying */
- if (TYPE_LENGTH (type) > 8)
- return 1;
-
- /* 2. The value is a single basic type -> returned in register */
- if (v850_type_is_scalar (type))
- return 0;
-
- /* The value is a structure or union with a single element
- * and that element is either a single basic type or an array of
- * a single basic type whoes size is greater than or equal to 4
- * -> returned in register */
- if ((TYPE_CODE (type) == TYPE_CODE_STRUCT
- || TYPE_CODE (type) == TYPE_CODE_UNION)
- && TYPE_NFIELDS (type) == 1)
- {
- fld_type = TYPE_FIELD_TYPE (type, 0);
- if (v850_type_is_scalar (fld_type) && TYPE_LENGTH (fld_type) >= 4)
- return 0;
-
- if (TYPE_CODE (fld_type) == TYPE_CODE_ARRAY)
- {
- tgt_type = TYPE_TARGET_TYPE (fld_type);
- if (v850_type_is_scalar (tgt_type) && TYPE_LENGTH (tgt_type) >= 4)
- return 0;
- }
- }
-
- /* The value is a structure whose first element is an integer or
- * a float, and which contains no arrays of more than two elements
- * -> returned in register */
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT
- && v850_type_is_scalar (TYPE_FIELD_TYPE (type, 0))
- && TYPE_LENGTH (TYPE_FIELD_TYPE (type, 0)) == 4)
- {
- for (i = 1; i < TYPE_NFIELDS (type); ++i)
- {
- fld_type = TYPE_FIELD_TYPE (type, 0);
- if (TYPE_CODE (fld_type) == TYPE_CODE_ARRAY)
- {
- tgt_type = TYPE_TARGET_TYPE (fld_type);
- if (TYPE_LENGTH (fld_type) >= 0 && TYPE_LENGTH (tgt_type) >= 0
- && TYPE_LENGTH (fld_type) / TYPE_LENGTH (tgt_type) > 2)
- return 1;
- }
- }
- return 0;
- }
-
- /* The value is a union which contains at least one field which
- * would be returned in registers according to these rules
- * -> returned in register */
- if (TYPE_CODE (type) == TYPE_CODE_UNION)
- {
- for (i = 0; i < TYPE_NFIELDS (type); ++i)
- {
- fld_type = TYPE_FIELD_TYPE (type, 0);
- if (!v850_use_struct_convention (0, fld_type))
- return 0;
- }
- }
-
- return 1;
-}
-\f
-
-
-/* Structure for mapping bits in register lists to register numbers. */
-struct reg_list
-{
- long mask;
- int regno;
-};
-
-/* Helper function for v850_scan_prologue to handle prepare instruction. */
-
-static void
-handle_prepare (int insn, int insn2, CORE_ADDR * current_pc_ptr,
- struct prologue_info *pi, struct pifsr **pifsr_ptr)
-{
- CORE_ADDR current_pc = *current_pc_ptr;
- struct pifsr *pifsr = *pifsr_ptr;
- long next = insn2 & 0xffff;
- long list12 = ((insn & 1) << 16) + (next & 0xffe0);
- long offset = (insn & 0x3e) << 1;
- static struct reg_list reg_table[] =
- {
- {0x00800, 20}, /* r20 */
- {0x00400, 21}, /* r21 */
- {0x00200, 22}, /* r22 */
- {0x00100, 23}, /* r23 */
- {0x08000, 24}, /* r24 */
- {0x04000, 25}, /* r25 */
- {0x02000, 26}, /* r26 */
- {0x01000, 27}, /* r27 */
- {0x00080, 28}, /* r28 */
- {0x00040, 29}, /* r29 */
- {0x10000, 30}, /* ep */
- {0x00020, 31}, /* lp */
- {0, 0} /* end of table */
- };
- int i;
-
- if ((next & 0x1f) == 0x0b) /* skip imm16 argument */
- current_pc += 2;
- else if ((next & 0x1f) == 0x13) /* skip imm16 argument */
- current_pc += 2;
- else if ((next & 0x1f) == 0x1b) /* skip imm32 argument */
- current_pc += 4;
-
- /* Calculate the total size of the saved registers, and add it
- it to the immediate value used to adjust SP. */
- for (i = 0; reg_table[i].mask != 0; i++)
- if (list12 & reg_table[i].mask)
- offset += v850_register_raw_size (reg_table[i].regno);
- pi->frameoffset -= offset;
-
- /* Calculate the offsets of the registers relative to the value
- the SP will have after the registers have been pushed and the
- imm5 value has been subtracted from it. */
- if (pifsr)
- {
- for (i = 0; reg_table[i].mask != 0; i++)
- {
- if (list12 & reg_table[i].mask)
- {
- int reg = reg_table[i].regno;
- offset -= v850_register_raw_size (reg);
- pifsr->reg = reg;
- pifsr->offset = offset;
- pifsr->cur_frameoffset = pi->frameoffset;
-#ifdef DEBUG
- printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
-#endif
- pifsr++;
- }
- }
- }
-#ifdef DEBUG
- printf_filtered ("\tfound ctret after regsave func");
-#endif
-
- /* Set result parameters. */
- *current_pc_ptr = current_pc;
- *pifsr_ptr = pifsr;
-}
-
-
-/* Helper function for v850_scan_prologue to handle pushm/pushl instructions.
- FIXME: the SR bit of the register list is not supported; must check
- that the compiler does not ever generate this bit. */
-
-static void
-handle_pushm (int insn, int insn2, struct prologue_info *pi,
- struct pifsr **pifsr_ptr)
-{
- struct pifsr *pifsr = *pifsr_ptr;
- long list12 = ((insn & 0x0f) << 16) + (insn2 & 0xfff0);
- long offset = 0;
- static struct reg_list pushml_reg_table[] =
- {
- {0x80000, E_PS_REGNUM}, /* PSW */
- {0x40000, 1}, /* r1 */
- {0x20000, 2}, /* r2 */
- {0x10000, 3}, /* r3 */
- {0x00800, 4}, /* r4 */
- {0x00400, 5}, /* r5 */
- {0x00200, 6}, /* r6 */
- {0x00100, 7}, /* r7 */
- {0x08000, 8}, /* r8 */
- {0x04000, 9}, /* r9 */
- {0x02000, 10}, /* r10 */
- {0x01000, 11}, /* r11 */
- {0x00080, 12}, /* r12 */
- {0x00040, 13}, /* r13 */
- {0x00020, 14}, /* r14 */
- {0x00010, 15}, /* r15 */
- {0, 0} /* end of table */
- };
- static struct reg_list pushmh_reg_table[] =
- {
- {0x80000, 16}, /* r16 */
- {0x40000, 17}, /* r17 */
- {0x20000, 18}, /* r18 */
- {0x10000, 19}, /* r19 */
- {0x00800, 20}, /* r20 */
- {0x00400, 21}, /* r21 */
- {0x00200, 22}, /* r22 */
- {0x00100, 23}, /* r23 */
- {0x08000, 24}, /* r24 */
- {0x04000, 25}, /* r25 */
- {0x02000, 26}, /* r26 */
- {0x01000, 27}, /* r27 */
- {0x00080, 28}, /* r28 */
- {0x00040, 29}, /* r29 */
- {0x00010, 30}, /* r30 */
- {0x00020, 31}, /* r31 */
- {0, 0} /* end of table */
- };
- struct reg_list *reg_table;
- int i;
-
- /* Is this a pushml or a pushmh? */
- if ((insn2 & 7) == 1)
- reg_table = pushml_reg_table;
- else
- reg_table = pushmh_reg_table;
-
- /* Calculate the total size of the saved registers, and add it
- it to the immediate value used to adjust SP. */
- for (i = 0; reg_table[i].mask != 0; i++)
- if (list12 & reg_table[i].mask)
- offset += v850_register_raw_size (reg_table[i].regno);
- pi->frameoffset -= offset;
-
- /* Calculate the offsets of the registers relative to the value
- the SP will have after the registers have been pushed and the
- imm5 value is subtracted from it. */
- if (pifsr)
- {
- for (i = 0; reg_table[i].mask != 0; i++)
- {
- if (list12 & reg_table[i].mask)
- {
- int reg = reg_table[i].regno;
- offset -= v850_register_raw_size (reg);
- pifsr->reg = reg;
- pifsr->offset = offset;
- pifsr->cur_frameoffset = pi->frameoffset;
-#ifdef DEBUG
- printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
-#endif
- pifsr++;
- }
- }
- }
-#ifdef DEBUG
- printf_filtered ("\tfound ctret after regsave func");
-#endif
-
- /* Set result parameters. */
- *pifsr_ptr = pifsr;
-}
-\f
-
-
-
-/* Function: scan_prologue
- Scan the prologue of the function that contains PC, and record what
- we find in PI. Returns the pc after the prologue. Note that the
- addresses saved in frame->saved_regs are just frame relative (negative
- offsets from the frame pointer). This is because we don't know the
- actual value of the frame pointer yet. In some circumstances, the
- frame pointer can't be determined till after we have scanned the
- prologue. */
-
-static CORE_ADDR
-v850_scan_prologue (CORE_ADDR pc, struct prologue_info *pi)
-{
- CORE_ADDR func_addr, prologue_end, current_pc;
- struct pifsr *pifsr, *pifsr_tmp;
- int fp_used;
- int ep_used;
- int reg;
- CORE_ADDR save_pc, save_end;
- int regsave_func_p;
- int r12_tmp;
-
- /* First, figure out the bounds of the prologue so that we can limit the
- search to something reasonable. */
-
- if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
- {
- struct symtab_and_line sal;
-
- sal = find_pc_line (func_addr, 0);
-
- if (func_addr == entry_point_address ())
- pi->start_function = 1;
- else
- pi->start_function = 0;
-
-#if 0
- if (sal.line == 0)
- prologue_end = pc;
- else
- prologue_end = sal.end;
-#else
- prologue_end = pc;
-#endif
- }
- else
- { /* We're in the boondocks */
- func_addr = pc - 100;
- prologue_end = pc;
- }
-
- prologue_end = min (prologue_end, pc);
-
- /* Now, search the prologue looking for instructions that setup fp, save
- rp, adjust sp and such. We also record the frame offset of any saved
- registers. */
-
- pi->frameoffset = 0;
- pi->framereg = E_SP_REGNUM;
- fp_used = 0;
- ep_used = 0;
- pifsr = pi->pifsrs;
- regsave_func_p = 0;
- save_pc = 0;
- save_end = 0;
- r12_tmp = 0;
-
-#ifdef DEBUG
- printf_filtered ("Current_pc = 0x%.8lx, prologue_end = 0x%.8lx\n",
- (long) func_addr, (long) prologue_end);
-#endif
-
- for (current_pc = func_addr; current_pc < prologue_end;)
- {
- int insn;
- int insn2 = -1; /* dummy value */
-
-#ifdef DEBUG
- fprintf_filtered (gdb_stdlog, "0x%.8lx ", (long) current_pc);
- gdb_print_insn (current_pc, gdb_stdlog);
-#endif
-
- insn = read_memory_unsigned_integer (current_pc, 2);
- current_pc += 2;
- if ((insn & 0x0780) >= 0x0600) /* Four byte instruction? */
- {
- insn2 = read_memory_unsigned_integer (current_pc, 2);
- current_pc += 2;
- }
-
- if ((insn & 0xffc0) == ((10 << 11) | 0x0780) && !regsave_func_p)
- { /* jarl <func>,10 */
- long low_disp = insn2 & ~(long) 1;
- long disp = (((((insn & 0x3f) << 16) + low_disp)
- & ~(long) 1) ^ 0x00200000) - 0x00200000;
-
- save_pc = current_pc;
- save_end = prologue_end;
- regsave_func_p = 1;
- current_pc += disp - 4;
- prologue_end = (current_pc
- + (2 * 3) /* moves to/from ep */
- + 4 /* addi <const>,sp,sp */
- + 2 /* jmp [r10] */
- + (2 * 12) /* sst.w to save r2, r20-r29, r31 */
- + 20); /* slop area */
-
-#ifdef DEBUG
- printf_filtered ("\tfound jarl <func>,r10, disp = %ld, low_disp = %ld, new pc = 0x%.8lx\n",
- disp, low_disp, (long) current_pc + 2);
-#endif
- continue;
- }
- else if ((insn & 0xffc0) == 0x0200 && !regsave_func_p)
- { /* callt <imm6> */
- long ctbp = read_register (E_CTBP_REGNUM);
- long adr = ctbp + ((insn & 0x3f) << 1);
-
- save_pc = current_pc;
- save_end = prologue_end;
- regsave_func_p = 1;
- current_pc = ctbp + (read_memory_unsigned_integer (adr, 2) & 0xffff);
- prologue_end = (current_pc
- + (2 * 3) /* prepare list2,imm5,sp/imm */
- + 4 /* ctret */
- + 20); /* slop area */
-
-#ifdef DEBUG
- printf_filtered ("\tfound callt, ctbp = 0x%.8lx, adr = %.8lx, new pc = 0x%.8lx\n",
- ctbp, adr, (long) current_pc);
-#endif
- continue;
- }
- else if ((insn & 0xffc0) == 0x0780) /* prepare list2,imm5 */
- {
- handle_prepare (insn, insn2, ¤t_pc, pi, &pifsr);
- continue;
- }
- else if (insn == 0x07e0 && regsave_func_p && insn2 == 0x0144)
- { /* ctret after processing register save function */
- current_pc = save_pc;
- prologue_end = save_end;
- regsave_func_p = 0;
-#ifdef DEBUG
- printf_filtered ("\tfound ctret after regsave func");
-#endif
- continue;
- }
- else if ((insn & 0xfff0) == 0x07e0 && (insn2 & 5) == 1)
- { /* pushml, pushmh */
- handle_pushm (insn, insn2, pi, &pifsr);
- continue;
- }
- else if ((insn & 0xffe0) == 0x0060 && regsave_func_p)
- { /* jmp after processing register save function */
- current_pc = save_pc;
- prologue_end = save_end;
- regsave_func_p = 0;
-#ifdef DEBUG
- printf_filtered ("\tfound jmp after regsave func");
-#endif
- continue;
- }
- else if ((insn & 0x07c0) == 0x0780 /* jarl or jr */
- || (insn & 0xffe0) == 0x0060 /* jmp */
- || (insn & 0x0780) == 0x0580) /* branch */
- {
-#ifdef DEBUG
- printf_filtered ("\n");
-#endif
- break; /* Ran into end of prologue */
- }
-
- else if ((insn & 0xffe0) == ((E_SP_REGNUM << 11) | 0x0240)) /* add <imm>,sp */
- pi->frameoffset += ((insn & 0x1f) ^ 0x10) - 0x10;
- else if (insn == ((E_SP_REGNUM << 11) | 0x0600 | E_SP_REGNUM)) /* addi <imm>,sp,sp */
- pi->frameoffset += insn2;
- else if (insn == ((E_FP_RAW_REGNUM << 11) | 0x0000 | E_SP_REGNUM)) /* mov sp,fp */
- {
- fp_used = 1;
- pi->framereg = E_FP_RAW_REGNUM;
- }
-
- else if (insn == ((E_R12_REGNUM << 11) | 0x0640 | E_R0_REGNUM)) /* movhi hi(const),r0,r12 */
- r12_tmp = insn2 << 16;
- else if (insn == ((E_R12_REGNUM << 11) | 0x0620 | E_R12_REGNUM)) /* movea lo(const),r12,r12 */
- r12_tmp += insn2;
- else if (insn == ((E_SP_REGNUM << 11) | 0x01c0 | E_R12_REGNUM) && r12_tmp) /* add r12,sp */
- pi->frameoffset = r12_tmp;
- else if (insn == ((E_EP_REGNUM << 11) | 0x0000 | E_SP_REGNUM)) /* mov sp,ep */
- ep_used = 1;
- else if (insn == ((E_EP_REGNUM << 11) | 0x0000 | E_R1_REGNUM)) /* mov r1,ep */
- ep_used = 0;
- else if (((insn & 0x07ff) == (0x0760 | E_SP_REGNUM) /* st.w <reg>,<offset>[sp] */
- || (fp_used
- && (insn & 0x07ff) == (0x0760 | E_FP_RAW_REGNUM))) /* st.w <reg>,<offset>[fp] */
- && pifsr
- && (((reg = (insn >> 11) & 0x1f) >= E_SAVE1_START_REGNUM && reg <= E_SAVE1_END_REGNUM)
- || (reg >= E_SAVE2_START_REGNUM && reg <= E_SAVE2_END_REGNUM)
- || (reg >= E_SAVE3_START_REGNUM && reg <= E_SAVE3_END_REGNUM)))
- {
- pifsr->reg = reg;
- pifsr->offset = insn2 & ~1;
- pifsr->cur_frameoffset = pi->frameoffset;
-#ifdef DEBUG
- printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
-#endif
- pifsr++;
- }
-
- else if (ep_used /* sst.w <reg>,<offset>[ep] */
- && ((insn & 0x0781) == 0x0501)
- && pifsr
- && (((reg = (insn >> 11) & 0x1f) >= E_SAVE1_START_REGNUM && reg <= E_SAVE1_END_REGNUM)
- || (reg >= E_SAVE2_START_REGNUM && reg <= E_SAVE2_END_REGNUM)
- || (reg >= E_SAVE3_START_REGNUM && reg <= E_SAVE3_END_REGNUM)))
- {
- pifsr->reg = reg;
- pifsr->offset = (insn & 0x007e) << 1;
- pifsr->cur_frameoffset = pi->frameoffset;
-#ifdef DEBUG
- printf_filtered ("\tSaved register r%d, offset %d", reg, pifsr->offset);
-#endif
- pifsr++;
- }
-
-#ifdef DEBUG
- printf_filtered ("\n");
-#endif
- }
-
- if (pifsr)
- pifsr->framereg = 0; /* Tie off last entry */
-
- /* Fix up any offsets to the final offset. If a frame pointer was created, use it
- instead of the stack pointer. */
- for (pifsr_tmp = pi->pifsrs; pifsr_tmp && pifsr_tmp != pifsr; pifsr_tmp++)
- {
- pifsr_tmp->offset -= pi->frameoffset - pifsr_tmp->cur_frameoffset;
- pifsr_tmp->framereg = pi->framereg;
-
-#ifdef DEBUG
- printf_filtered ("Saved register r%d, offset = %d, framereg = r%d\n",
- pifsr_tmp->reg, pifsr_tmp->offset, pifsr_tmp->framereg);
-#endif
- }
-
-#ifdef DEBUG
- printf_filtered ("Framereg = r%d, frameoffset = %d\n", pi->framereg, pi->frameoffset);
-#endif
-
- return current_pc;
-}
-
-/* Function: find_callers_reg
- Find REGNUM on the stack. Otherwise, it's in an active register.
- One thing we might want to do here is to check REGNUM against the
- clobber mask, and somehow flag it as invalid if it isn't saved on
- the stack somewhere. This would provide a graceful failure mode
- when trying to get the value of caller-saves registers for an inner
- frame. */
-
-static CORE_ADDR
-v850_find_callers_reg (struct frame_info *fi, int regnum)
-{
- for (; fi; fi = get_next_frame (fi))
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- return deprecated_read_register_dummy (get_frame_pc (fi),
- get_frame_base (fi), regnum);
- else if (deprecated_get_frame_saved_regs (fi)[regnum] != 0)
- return read_memory_unsigned_integer (deprecated_get_frame_saved_regs (fi)[regnum],
- v850_register_raw_size (regnum));
-
- return read_register (regnum);
-}
-
-/* Function: frame_chain
- Figure out the frame prior to FI. Unfortunately, this involves
- scanning the prologue of the caller, which will also be done
- shortly by v850_init_extra_frame_info. For the dummy frame, we
- just return the stack pointer that was in use at the time the
- function call was made. */
-
-static CORE_ADDR
-v850_frame_chain (struct frame_info *fi)
-{
- struct prologue_info pi;
- CORE_ADDR callers_pc, fp;
-
- /* First, find out who called us */
- callers_pc = DEPRECATED_FRAME_SAVED_PC (fi);
- /* If caller is a call-dummy, then our FP bears no relation to his FP! */
- fp = v850_find_callers_reg (fi, E_FP_RAW_REGNUM);
- if (deprecated_pc_in_call_dummy (callers_pc))
- return fp; /* caller is call-dummy: return oldest value of FP */
-
- /* Caller is NOT a call-dummy, so everything else should just work.
- Even if THIS frame is a call-dummy! */
- pi.pifsrs = NULL;
-
- v850_scan_prologue (callers_pc, &pi);
-
- if (pi.start_function)
- return 0; /* Don't chain beyond the start function */
-
- if (pi.framereg == E_FP_RAW_REGNUM)
- return v850_find_callers_reg (fi, pi.framereg);
-
- return get_frame_base (fi) - pi.frameoffset;
-}
-
-/* Function: skip_prologue
- Return the address of the first code past the prologue of the function. */
-
-static CORE_ADDR
-v850_skip_prologue (CORE_ADDR pc)
-{
- CORE_ADDR func_addr, func_end;
-
- /* See what the symbol table says */
-
- if (find_pc_partial_function (pc, NULL, &func_addr, &func_end))
- {
- struct symtab_and_line sal;
-
- sal = find_pc_line (func_addr, 0);
-
- if (sal.line != 0 && sal.end < func_end)
- return sal.end;
- else
- /* Either there's no line info, or the line after the prologue is after
- the end of the function. In this case, there probably isn't a
- prologue. */
- return pc;
- }
-
-/* We can't find the start of this function, so there's nothing we can do. */
- return pc;
-}
-
-/* Function: pop_frame
- This routine gets called when either the user uses the `return'
- command, or the call dummy breakpoint gets hit. */
-
-static void
-v850_pop_frame (void)
-{
- struct frame_info *frame = get_current_frame ();
- int regnum;
-
- if (deprecated_pc_in_call_dummy (get_frame_pc (frame)))
- deprecated_pop_dummy_frame ();
- else
- {
- write_register (E_PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
-
- for (regnum = 0; regnum < E_NUM_REGS; regnum++)
- if (deprecated_get_frame_saved_regs (frame)[regnum] != 0)
- write_register (regnum,
- read_memory_unsigned_integer (deprecated_get_frame_saved_regs (frame)[regnum],
- v850_register_raw_size (regnum)));
-
- write_register (E_SP_REGNUM, get_frame_base (frame));
- }
-
- flush_cached_frames ();
-}
-
-/* Function: push_arguments
- Setup arguments and RP for a call to the target. First four args
- go in R6->R9, subsequent args go into sp + 16 -> sp + ... Structs
- are passed by reference. 64 bit quantities (doubles and long
- longs) may be split between the regs and the stack. When calling a
- function that returns a struct, a pointer to the struct is passed
- in as a secret first argument (always in R6).
-
- Stack space for the args has NOT been allocated: that job is up to us.
- */
-
-static CORE_ADDR
-v850_push_arguments (int nargs, struct value **args, CORE_ADDR sp,
- int struct_return, CORE_ADDR struct_addr)
-{
- int argreg;
- int argnum;
- int len = 0;
- int stack_offset;
-
- /* First, just for safety, make sure stack is aligned */
- sp &= ~3;
-
- /* The offset onto the stack at which we will start copying parameters
- (after the registers are used up) begins at 16 rather than at zero.
- I don't really know why, that's just the way it seems to work. */
- stack_offset = 16;
-
- /* Now make space on the stack for the args. */
- for (argnum = 0; argnum < nargs; argnum++)
- len += ((TYPE_LENGTH (value_type (args[argnum])) + 3) & ~3);
- sp -= len + stack_offset; /* possibly over-allocating, but it works... */
- /* (you might think we could allocate 16 bytes */
- /* less, but the ABI seems to use it all! ) */
-
- argreg = E_ARG0_REGNUM;
- /* the struct_return pointer occupies the first parameter-passing reg */
- if (struct_return)
- argreg++;
-
- /* Now load as many as possible of the first arguments into
- registers, and push the rest onto the stack. There are 16 bytes
- in four registers available. Loop thru args from first to last. */
- for (argnum = 0; argnum < nargs; argnum++)
- {
- int len;
- char *val;
- char valbuf[v850_register_raw_size (E_ARG0_REGNUM)];
-
- if (!v850_type_is_scalar (value_type (*args))
- && TYPE_LENGTH (value_type (*args)) > E_MAX_RETTYPE_SIZE_IN_REGS)
- {
- store_unsigned_integer (valbuf, 4, VALUE_ADDRESS (*args));
- len = 4;
- val = valbuf;
- }
- else
- {
- len = TYPE_LENGTH (value_type (*args));
- val = (char *) VALUE_CONTENTS (*args);
- }
-
- while (len > 0)
- if (argreg <= E_ARGLAST_REGNUM)
- {
- CORE_ADDR regval;
-
- regval = extract_unsigned_integer (val, v850_register_raw_size (argreg));
- write_register (argreg, regval);
-
- len -= v850_register_raw_size (argreg);
- val += v850_register_raw_size (argreg);
- argreg++;
- }
- else
- {
- write_memory (sp + stack_offset, val, 4);
-
- len -= 4;
- val += 4;
- stack_offset += 4;
- }
- args++;
- }
- return sp;
-}
-
-/* Function: push_return_address (pc)
- Set up the return address for the inferior function call.
- Needed for targets where we don't actually execute a JSR/BSR instruction */
-
-static CORE_ADDR
-v850_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
-{
- write_register (E_RP_REGNUM, entry_point_address ());
- return sp;
-}
-
-/* Function: frame_saved_pc
- Find the caller of this frame. We do this by seeing if E_RP_REGNUM
- is saved in the stack anywhere, otherwise we get it from the
- registers. If the inner frame is a dummy frame, return its PC
- instead of RP, because that's where "caller" of the dummy-frame
- will be found. */
-
-static CORE_ADDR
-v850_frame_saved_pc (struct frame_info *fi)
-{
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- return deprecated_read_register_dummy (get_frame_pc (fi),
- get_frame_base (fi), E_PC_REGNUM);
- else
- return v850_find_callers_reg (fi, E_RP_REGNUM);
-}
-
-
-static CORE_ADDR
-v850_saved_pc_after_call (struct frame_info *ignore)
-{
- return read_register (E_RP_REGNUM);
-}
-
-static void
-v850_extract_return_value (struct type *type, char *regbuf, char *valbuf)
-{
- CORE_ADDR return_buffer;
-
- if (!v850_use_struct_convention (0, type))
- {
- /* Scalar return values of <= 8 bytes are returned in
- E_V0_REGNUM to E_V1_REGNUM. */
- memcpy (valbuf,
- ®buf[DEPRECATED_REGISTER_BYTE (E_V0_REGNUM)],
- TYPE_LENGTH (type));
- }
- else
- {
- /* Aggregates and return values > 8 bytes are returned in memory,
- pointed to by R6. */
- return_buffer =
- extract_unsigned_integer (regbuf + DEPRECATED_REGISTER_BYTE (E_V0_REGNUM),
- register_size (current_gdbarch, E_V0_REGNUM));
-
- read_memory (return_buffer, valbuf, TYPE_LENGTH (type));
- }
-}
-
-const static unsigned char *
-v850_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
-{
- static unsigned char breakpoint[] = { 0x85, 0x05 };
- *lenptr = sizeof (breakpoint);
- return breakpoint;
-}
-
-static void
-v850_store_return_value (struct type *type, char *valbuf)
-{
- CORE_ADDR return_buffer;
-
- if (!v850_use_struct_convention (0, type))
- deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (E_V0_REGNUM), valbuf,
- TYPE_LENGTH (type));
- else
- {
- return_buffer = read_register (E_V0_REGNUM);
- write_memory (return_buffer, valbuf, TYPE_LENGTH (type));
- }
-}
-
-static void
-v850_frame_init_saved_regs (struct frame_info *fi)
-{
- struct prologue_info pi;
- struct pifsr pifsrs[E_NUM_REGS + 1], *pifsr;
- CORE_ADDR func_addr, func_end;
-
- if (!deprecated_get_frame_saved_regs (fi))
- {
- frame_saved_regs_zalloc (fi);
-
- /* The call dummy doesn't save any registers on the stack, so we
- can return now. */
- if (deprecated_pc_in_call_dummy (get_frame_pc (fi)))
- return;
-
- /* Find the beginning of this function, so we can analyze its
- prologue. */
- if (find_pc_partial_function (get_frame_pc (fi), NULL, &func_addr, &func_end))
- {
- pi.pifsrs = pifsrs;
-
- v850_scan_prologue (get_frame_pc (fi), &pi);
-
- if (!get_next_frame (fi) && pi.framereg == E_SP_REGNUM)
- deprecated_update_frame_base_hack (fi, read_register (pi.framereg) - pi.frameoffset);
-
- for (pifsr = pifsrs; pifsr->framereg; pifsr++)
- {
- deprecated_get_frame_saved_regs (fi)[pifsr->reg] = pifsr->offset + get_frame_base (fi);
-
- if (pifsr->framereg == E_SP_REGNUM)
- deprecated_get_frame_saved_regs (fi)[pifsr->reg] += pi.frameoffset;
- }
- }
- /* Else we're out of luck (can't debug completely stripped code).
- FIXME. */
- }
-}
-
-/* Function: init_extra_frame_info
- Setup the frame's frame pointer, pc, and frame addresses for saved
- registers. Most of the work is done in scan_prologue().
-
- Note that when we are called for the last frame (currently active frame),
- that get_frame_pc (fi) and fi->frame will already be setup. However, fi->frame will
- be valid only if this routine uses FP. For previous frames, fi-frame will
- always be correct (since that is derived from v850_frame_chain ()).
-
- We can be called with the PC in the call dummy under two
- circumstances. First, during normal backtracing, second, while
- figuring out the frame pointer just prior to calling the target
- function (see call_function_by_hand). */
-
-static void
-v850_init_extra_frame_info (int fromleaf, struct frame_info *fi)
-{
- struct prologue_info pi;
-
- if (get_next_frame (fi))
- deprecated_update_frame_pc_hack (fi, DEPRECATED_FRAME_SAVED_PC (get_next_frame (fi)));
-
- v850_frame_init_saved_regs (fi);
-}
-
-static void
-v850_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
- write_register (E_ARG0_REGNUM, addr);
-}
-
-static CORE_ADDR
-v850_target_read_fp (void)
-{
- return read_register (E_FP_RAW_REGNUM);
-}
-
-static struct gdbarch *
-v850_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
-{
- struct gdbarch_tdep *tdep = NULL;
- struct gdbarch *gdbarch;
- int i;
-
- /* find a candidate among the list of pre-declared architectures. */
- arches = gdbarch_list_lookup_by_info (arches, &info);
- if (arches != NULL)
- return (arches->gdbarch);
-
-#if 0
- tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
-#endif
-
- /* Change the register names based on the current machine type. */
- if (info.bfd_arch_info->arch != bfd_arch_v850)
- return 0;
-
- gdbarch = gdbarch_alloc (&info, 0);
-
- /* NOTE: cagney/2002-12-06: This can be deleted when this arch is
- ready to unwind the PC first (see frame.c:get_prev_frame()). */
- set_gdbarch_deprecated_init_frame_pc (gdbarch, deprecated_init_frame_pc_default);
-
- for (i = 0; v850_processor_type_table[i].regnames != NULL; i++)
- {
- if (v850_processor_type_table[i].mach == info.bfd_arch_info->mach)
- {
- v850_register_names = v850_processor_type_table[i].regnames;
- break;
- }
- }
-
- /*
- * Basic register fields and methods.
- */
- set_gdbarch_num_regs (gdbarch, E_NUM_REGS);
- set_gdbarch_num_pseudo_regs (gdbarch, 0);
- set_gdbarch_sp_regnum (gdbarch, E_SP_REGNUM);
- set_gdbarch_deprecated_fp_regnum (gdbarch, E_FP_REGNUM);
- set_gdbarch_pc_regnum (gdbarch, E_PC_REGNUM);
- set_gdbarch_register_name (gdbarch, v850_register_name);
- set_gdbarch_deprecated_register_size (gdbarch, v850_reg_size);
- set_gdbarch_deprecated_register_byte (gdbarch, v850_register_byte);
- set_gdbarch_deprecated_register_raw_size (current_gdbarch, gdbarch, v850_register_raw_size);
- set_gdbarch_deprecated_register_virtual_size (gdbarch, v850_register_raw_size);
- set_gdbarch_deprecated_register_virtual_type (gdbarch, v850_reg_virtual_type);
-
- set_gdbarch_deprecated_target_read_fp (gdbarch, v850_target_read_fp);
-
- /*
- * Frame Info
- */
- set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, v850_frame_init_saved_regs);
- set_gdbarch_deprecated_init_extra_frame_info (gdbarch, v850_init_extra_frame_info);
- set_gdbarch_deprecated_frame_chain (gdbarch, v850_frame_chain);
- set_gdbarch_deprecated_saved_pc_after_call (gdbarch, v850_saved_pc_after_call);
- set_gdbarch_deprecated_frame_saved_pc (gdbarch, v850_frame_saved_pc);
- set_gdbarch_skip_prologue (gdbarch, v850_skip_prologue);
-
- /*
- * Miscelany
- */
- /* Stack grows up. */
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-
- /*
- * Call Dummies
- *
- * These values and methods are used when gdb calls a target function. */
- set_gdbarch_deprecated_push_return_address (gdbarch, v850_push_return_address);
- set_gdbarch_deprecated_extract_return_value (gdbarch, v850_extract_return_value);
- set_gdbarch_deprecated_push_arguments (gdbarch, v850_push_arguments);
- set_gdbarch_deprecated_pop_frame (gdbarch, v850_pop_frame);
- set_gdbarch_deprecated_store_struct_return (gdbarch, v850_store_struct_return);
- set_gdbarch_deprecated_store_return_value (gdbarch, v850_store_return_value);
- set_gdbarch_deprecated_use_struct_convention (gdbarch, v850_use_struct_convention);
- set_gdbarch_breakpoint_from_pc (gdbarch, v850_breakpoint_from_pc);
-
- set_gdbarch_int_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_ptr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_addr_bit (gdbarch, 4 * TARGET_CHAR_BIT);
- set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT);
-
- /* Should be using push_dummy_call. */
- set_gdbarch_deprecated_dummy_write_sp (gdbarch, deprecated_write_sp);
-
- set_gdbarch_print_insn (gdbarch, print_insn_v850);
-
- return gdbarch;
-}
-
-extern initialize_file_ftype _initialize_v850_tdep; /* -Wmissing-prototypes */
-
-void
-_initialize_v850_tdep (void)
-{
- register_gdbarch_init (bfd_arch_v850, v850_gdbarch_init);
-}
+++ /dev/null
-/* ICE interface for the NEC V850 for GDB, the GNU debugger.
- Copyright 1996, 1997, 1998, 1999, 2000, 2001
- 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. */
-
-#include "defs.h"
-#include "gdb_string.h"
-#include "frame.h"
-#include "symtab.h"
-#include "inferior.h"
-#include "breakpoint.h"
-#include "symfile.h"
-#include "target.h"
-#include "objfiles.h"
-#include "gdbcore.h"
-#include "value.h"
-#include "command.h"
-#include "regcache.h"
-
-#include <tcl.h>
-#include <windows.h>
-#include <winuser.h> /* for WM_USER */
-
-extern unsigned long int strtoul (const char *nptr, char **endptr,
- int base);
-
-/* Local data definitions */
-struct MessageIO
- {
- int size; /* length of input or output in bytes */
- char *buf; /* buffer having the input/output information */
- };
-
-/* Prototypes for functions located in other files */
-extern void break_command (char *, int);
-
-/* Prototypes for local functions */
-static int init_hidden_window (void);
-
-static LRESULT CALLBACK v850ice_wndproc (HWND, UINT, WPARAM, LPARAM);
-
-static void v850ice_files_info (struct target_ops *ignore);
-
-static int v850ice_xfer_memory (CORE_ADDR memaddr, char *myaddr,
- int len, int should_write,
- struct target_ops *target);
-
-static void v850ice_prepare_to_store (void);
-
-static void v850ice_fetch_registers (int regno);
-
-static void v850ice_resume (ptid_t ptid, int step,
- enum target_signal siggnal);
-
-static void v850ice_open (char *name, int from_tty);
-
-static void v850ice_close (int quitting);
-
-static void v850ice_stop (void);
-
-static void v850ice_store_registers (int regno);
-
-static void v850ice_mourn (void);
-
-static ptid_t v850ice_wait (ptid_t ptid,
- struct target_waitstatus *status);
-
-static void v850ice_kill (void);
-
-static void v850ice_detach (char *args, int from_tty);
-
-static int v850ice_insert_breakpoint (CORE_ADDR, char *);
-
-static int v850ice_remove_breakpoint (CORE_ADDR, char *);
-
-static void v850ice_command (char *, int);
-
-static int ice_disassemble (unsigned long, int, char *);
-
-static int ice_lookup_addr (unsigned long *, char *, char *);
-
-static int ice_lookup_symbol (unsigned long, char *);
-
-static void ice_SimulateDisassemble (char *, int);
-
-static void ice_SimulateAddrLookup (char *, int);
-
-static void ice_Simulate_SymLookup (char *, int);
-
-static void ice_fputs (const char *, struct ui_file *);
-
-static int ice_file (char *);
-
-static int ice_cont (char *);
-
-static int ice_stepi (char *);
-
-static int ice_nexti (char *);
-
-static void togdb_force_update (void);
-
-static void view_source (CORE_ADDR);
-
-static void do_gdb (char *, char *, void (*func) (char *, int), int);
-
-
-/* Globals */
-static HWND hidden_hwnd; /* HWND for messages */
-
-long (__stdcall * ExeAppReq) (char *, long, char *, struct MessageIO *);
-
-long (__stdcall * RegisterClient) (HWND);
-
-long (__stdcall * UnregisterClient) (void);
-
-extern Tcl_Interp *gdbtk_interp;
-
-/* Globals local to this file only */
-static int ice_open = 0; /* Is ICE open? */
-
-static char *v850_CB_Result; /* special char array for saving 'callback' results */
-
-static int SimulateCallback; /* simulate a callback event */
-
-#define MAX_BLOCK_SIZE 64*1024 /* Cannot transfer memory in blocks bigger
- than this */
-/* MDI/ICE Message IDs */
-#define GSINGLESTEP 0x200 /* single-step target */
-#define GRESUME 0x201 /* resume target */
-#define GREADREG 0x202 /* read a register */
-#define GWRITEREG 0x203 /* write a register */
-#define GWRITEBLOCK 0x204 /* write a block of memory */
-#define GREADBLOCK 0x205 /* read a block of memory */
-#define GSETBREAK 0x206 /* set a breakpoint */
-#define GREMOVEBREAK 0x207 /* remove a breakpoint */
-#define GHALT 0x208 /* ??? */
-#define GCHECKSTATUS 0x209 /* check status of ICE */
-#define GMDIREPLY 0x210 /* Reply for previous query - NOT USED */
-#define GDOWNLOAD 0x211 /* something for MDI */
-#define GCOMMAND 0x212 /* execute command in ice */
-#define GLOADFILENAME 0x213 /* retrieve load filename */
-#define GWRITEMEM 0x214 /* write word, half-word, or byte */
-
-/* GCHECKSTATUS return codes: */
-#define ICE_Idle 0x00
-#define ICE_Breakpoint 0x01 /* hit a breakpoint */
-#define ICE_Stepped 0x02 /* have stepped */
-#define ICE_Exception 0x03 /* have exception */
-#define ICE_Halted 0x04 /* hit a user halt */
-#define ICE_Exited 0x05 /* called exit */
-#define ICE_Terminated 0x06 /* user terminated */
-#define ICE_Running 0x07
-#define ICE_Unknown 0x99
-
-/* Windows messages */
-#define WM_STATE_CHANGE WM_USER+101
-#define WM_SYM_TO_ADDR WM_USER+102
-#define WM_ADDR_TO_SYM WM_USER+103
-#define WM_DISASSEMBLY WM_USER+104
-#define WM_SOURCE WM_USER+105
-
-/* STATE_CHANGE codes */
-#define STATE_CHANGE_REGS 1 /* Register(s) changed */
-#define STATE_CHANGE_LOAD 2 /* HW reset */
-#define STATE_CHANGE_RESET 3 /* Load new file */
-#define STATE_CHANGE_CONT 4 /* Run target */
-#define STATE_CHANGE_STOP 5 /* Stop target */
-#define STATE_CHANGE_STEPI 6 /* Stepi target */
-#define STATE_CHANGE_NEXTI 7 /* Nexti target */
-
-static struct target_ops v850ice_ops; /* Forward decl */
-
-/* This function creates a hidden window */
-static int
-init_hidden_window (void)
-{
- WNDCLASS class;
-
- if (hidden_hwnd != NULL)
- return 1;
-
- class.style = 0;
- class.cbClsExtra = 0;
- class.cbWndExtra = 0;
- class.hInstance = GetModuleHandle (0);
- class.hbrBackground = NULL;
- class.lpszMenuName = NULL;
- class.lpszClassName = "gdb_v850ice";
- class.lpfnWndProc = v850ice_wndproc;
- class.hIcon = NULL;
- class.hCursor = NULL;
-
- if (!RegisterClass (&class))
- return 0;
-
- hidden_hwnd = CreateWindow ("gdb_v850ice", "gdb_v850ice", WS_TILED,
- 0, 0, 0, 0, NULL, NULL, class.hInstance,
- NULL);
- if (hidden_hwnd == NULL)
- {
- char buf[200];
- DWORD err;
-
- err = GetLastError ();
- FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
- 0, buf, 200, NULL);
- printf_unfiltered ("Could not create window: %s", buf);
- return 0;
- }
-
- return 1;
-}
-
-/*
- This function is installed as the message handler for the hidden window
- which QBox will use to communicate with gdb. It recognize and acts
- on the following messages:
-
- WM_SYM_TO_ADDR \
- WM_ADDR_TO_SYM | Not implemented at NEC's request
- WM_DISASSEMBLY /
- WM_STATE_CHANGE - tells us that a state change has occured in the ICE
- */
-static LRESULT CALLBACK
-v850ice_wndproc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
- LRESULT result = FALSE;
-
- switch (message)
- {
- case WM_SYM_TO_ADDR:
- MessageBox (0, "Symbol resolution\nNot implemented", "GDB", MB_OK);
- break;
- case WM_ADDR_TO_SYM:
- MessageBox (0, "Address resolution\nNot implemented", "GDB", MB_OK);
- break;
- case WM_SOURCE:
- view_source ((CORE_ADDR) lParam);
- break;
- case WM_STATE_CHANGE:
- switch (wParam)
- {
- case STATE_CHANGE_LOAD:
- {
- struct MessageIO iob;
- char buf[128];
-
- iob.buf = buf;
- iob.size = 128;
-
- /* Load in a new file... Need filename */
- ExeAppReq ("GDB", GLOADFILENAME, NULL, &iob);
- if (!catch_errors ((catch_errors_ftype *) ice_file, iob.buf, "", RETURN_MASK_ALL))
- printf_unfiltered ("load errored\n");
- }
- break;
- case STATE_CHANGE_RESET:
- registers_changed ();
- flush_cached_frames ();
- togdb_force_update ();
- result = TRUE;
- break;
- case STATE_CHANGE_REGS:
- registers_changed ();
- togdb_force_update ();
- result = TRUE;
- break;
- case STATE_CHANGE_CONT:
- if (!catch_errors ((catch_errors_ftype *) ice_cont, NULL, "", RETURN_MASK_ALL))
- printf_unfiltered ("continue errored\n");
- result = TRUE;
- break;
- case STATE_CHANGE_STEPI:
- if (!catch_errors ((catch_errors_ftype *) ice_stepi, (int) lParam, "",
- RETURN_MASK_ALL))
- printf_unfiltered ("stepi errored\n");
- result = TRUE;
- break;
- case STATE_CHANGE_NEXTI:
- if (!catch_errors ((catch_errors_ftype *) ice_nexti, (int) lParam, "",
- RETURN_MASK_ALL))
- printf_unfiltered ("nexti errored\n");
- result = TRUE;
- break;
- }
- }
-
- if (result == FALSE)
- return DefWindowProc (hwnd, message, wParam, lParam);
-
- return FALSE;
-}
-
-/* Code for opening a connection to the ICE. */
-
-static void
-v850ice_open (char *name, int from_tty)
-{
- HINSTANCE handle;
-
- if (name)
- error ("Too many arguments.");
-
- target_preopen (from_tty);
-
- unpush_target (&v850ice_ops);
-
- if (from_tty)
- puts_filtered ("V850ice debugging\n");
-
- push_target (&v850ice_ops); /* Switch to using v850ice target now */
-
- target_terminal_init ();
-
- /* Initialize everything necessary to facilitate communication
- between QBox, gdb, and the DLLs which control the ICE */
- if (ExeAppReq == NULL)
- {
- handle = LoadLibrary ("necmsg.dll");
- if (handle == NULL)
- error ("Cannot load necmsg.dll");
-
- ExeAppReq = (long (*) (char *, long, char *, struct MessageIO *))
- GetProcAddress (handle, "ExeAppReq");
- RegisterClient = (long (*) (HWND))
- GetProcAddress (handle, "RegisterClient");
- UnregisterClient = (long (*) (void))
- GetProcAddress (handle, "UnregisterClient");
-
- if (ExeAppReq == NULL || RegisterClient == NULL || UnregisterClient == NULL)
- error ("Could not find requisite functions in necmsg.dll.");
-
- if (!init_hidden_window ())
- error ("could not initialize message handling");
- }
-
- /* Tell the DLL we are here */
- RegisterClient (hidden_hwnd);
-
- ice_open = 1;
-
- /* Without this, some commands which require an active target (such as kill)
- won't work. This variable serves (at least) double duty as both the pid
- of the target process (if it has such), and as a flag indicating that a
- target is active. These functions should be split out into seperate
- variables, especially since GDB will someday have a notion of debugging
- several processes. */
- inferior_ptid = pid_to_ptid (42000);
-
- start_remote ();
- return;
-}
-
-/* Clean up connection to a remote debugger. */
-
-static void
-v850ice_close (int quitting)
-{
- if (ice_open)
- {
- UnregisterClient ();
- ice_open = 0;
- inferior_ptid = null_ptid;
- }
-}
-
-/* Stop the process on the ice. */
-static void
-v850ice_stop (void)
-{
- /* This is silly, but it works... */
- v850ice_command ("stop", 0);
-}
-
-static void
-v850ice_detach (char *args, int from_tty)
-{
- if (args)
- error ("Argument given to \"detach\" when remotely debugging.");
-
- pop_target ();
- if (from_tty)
- puts_filtered ("Ending v850ice debugging.\n");
-}
-
-/* Tell the remote machine to resume. */
-
-static void
-v850ice_resume (ptid_t ptid, int step, enum target_signal siggnal)
-{
- long retval;
- char buf[256];
- struct MessageIO iob;
-
- iob.size = 0;
- iob.buf = buf;
-
- if (step)
- retval = ExeAppReq ("GDB", GSINGLESTEP, "step", &iob);
- else
- retval = ExeAppReq ("GDB", GRESUME, "run", &iob);
-
- if (retval)
- error ("ExeAppReq (step = %d) returned %d", step, retval);
-}
-
-/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would.
- Returns "pid" (though it's not clear what, if anything, that
- means in the case of this target). */
-
-static ptid_t
-v850ice_wait (ptid_t ptid, struct target_waitstatus *status)
-{
- long v850_status;
- char buf[256];
- struct MessageIO iob;
- int done = 0;
- int count = 0;
-
- iob.size = 0;
- iob.buf = buf;
-
- do
- {
- if (count++ % 100000)
- {
- deprecated_ui_loop_hook (0);
- count = 0;
- }
-
- v850_status = ExeAppReq ("GDB", GCHECKSTATUS, NULL, &iob);
-
- switch (v850_status)
- {
- case ICE_Idle:
- case ICE_Breakpoint:
- case ICE_Stepped:
- case ICE_Halted:
- status->kind = TARGET_WAITKIND_STOPPED;
- status->value.sig = TARGET_SIGNAL_TRAP;
- done = 1;
- break;
- case ICE_Exception:
- status->kind = TARGET_WAITKIND_SIGNALLED;
- status->value.sig = TARGET_SIGNAL_SEGV;
- done = 1;
- break;
- case ICE_Exited:
- status->kind = TARGET_WAITKIND_EXITED;
- status->value.integer = 0;
- done = 1;
- break;
- case ICE_Terminated:
- status->kind = TARGET_WAITKIND_SIGNALLED;
- status->value.sig = TARGET_SIGNAL_KILL;
- done = 1;
- break;
- default:
- break;
- }
- }
- while (!done);
-
- return inferior_ptid;
-}
-
-static int
-convert_register (int regno, char *buf)
-{
- if (regno <= 31)
- sprintf (buf, "r%d", regno);
- else if (REGISTER_NAME (regno)[0] == 's'
- && REGISTER_NAME (regno)[1] == 'r')
- return 0;
- else
- sprintf (buf, "%s", REGISTER_NAME (regno));
-
- return 1;
-}
-
-/* Read the remote registers into the block REGS. */
-/* Note that the ICE returns register contents as ascii hex strings. We have
- to convert that to an unsigned long, and then call store_unsigned_integer to
- convert it to target byte-order if necessary. */
-
-static void
-v850ice_fetch_registers (int regno)
-{
- long retval;
- char cmd[100];
- char val[100];
- struct MessageIO iob;
- unsigned long regval;
- char *p;
-
- if (regno == -1)
- {
- for (regno = 0; regno < NUM_REGS; regno++)
- v850ice_fetch_registers (regno);
- return;
- }
-
- strcpy (cmd, "reg ");
- if (!convert_register (regno, &cmd[4]))
- return;
-
- iob.size = sizeof val;
- iob.buf = val;
- retval = ExeAppReq ("GDB", GREADREG, cmd, &iob);
- if (retval)
- error ("1: ExeAppReq returned %d: cmd = %s", retval, cmd);
-
- regval = strtoul (val, NULL, 16);
- if (regval == 0 && p == val)
- error ("v850ice_fetch_registers (%d): bad value from ICE: %s.",
- regno, val);
-
- store_unsigned_integer (val, register_size (current_gdbarch, regno), regval);
- regcache_raw_supply (current_regcache, regno, val);
-}
-
-/* Store register REGNO, or all registers if REGNO == -1, from the contents
- of REGISTERS. */
-
-static void
-v850ice_store_registers (int regno)
-{
- long retval;
- char cmd[100];
- unsigned long regval;
- char buf[256];
- struct MessageIO iob;
- iob.size = 0;
- iob.buf = buf;
-
- if (regno == -1)
- {
- for (regno = 0; regno < NUM_REGS; regno++)
- v850ice_store_registers (regno);
- return;
- }
-
- regval = extract_unsigned_integer (&deprecated_registers[DEPRECATED_REGISTER_BYTE (regno)],
- register_size (current_gdbarch, regno));
- strcpy (cmd, "reg ");
- if (!convert_register (regno, &cmd[4]))
- return;
- sprintf (cmd + strlen (cmd), "=0x%x", regval);
-
- retval = ExeAppReq ("GDB", GWRITEREG, cmd, &iob);
- if (retval)
- error ("2: ExeAppReq returned %d: cmd = %s", retval, cmd);
-}
-
-/* Prepare to store registers. Nothing to do here, since the ICE can write one
- register at a time. */
-
-static void
-v850ice_prepare_to_store (void)
-{
-}
-
-/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
- to or from debugger address MYADDR. Write to inferior if SHOULD_WRITE is
- nonzero. TARGET is unused. Returns length of data written or read;
- 0 for error.
-
- We can only read/write MAX_BLOCK_SIZE bytes at a time, though, or the DLL
- dies. */
-static int
-v850ice_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
- int should_write, struct target_ops *target)
-{
- long retval;
- char cmd[100];
- struct MessageIO iob;
- int sent;
-
- if (should_write)
- {
- if (len == 4 || len == 2 || len == 1)
- {
- long value = 0;
- char buf[256];
- char c;
-
- iob.size = 0;
- iob.buf = buf;
-
- sent = 0;
- switch (len)
- {
- case 4:
- c = 'w';
- value |= (long) ((myaddr[3] << 24) & 0xff000000);
- value |= (long) ((myaddr[2] << 16) & 0x00ff0000);
- value |= (long) ((myaddr[1] << 8) & 0x0000ff00);
- value |= (long) (myaddr[0] & 0x000000ff);
- break;
- case 2:
- c = 'h';
- value |= (long) ((myaddr[1] << 8) & 0xff00);
- value |= (long) (myaddr[0] & 0x00ff);
- break;
- case 1:
- c = 'b';
- value |= (long) (myaddr[0] & 0xff);
- break;
- }
-
- sprintf (cmd, "memory %c c 0x%x=0x%x", c, (int) memaddr, value);
- retval = ExeAppReq ("GDB", GWRITEMEM, cmd, &iob);
- if (retval == 0)
- sent = len;
- }
- else
- {
- sent = 0;
- do
- {
- iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
- iob.buf = myaddr;
- sprintf (cmd, "memory b c 0x%x=0x00 l=%d", (int) memaddr, iob.size);
- retval = ExeAppReq ("GDB", GWRITEBLOCK, cmd, &iob);
- if (retval != 0)
- break;
- len -= iob.size;
- memaddr += iob.size;
- myaddr += iob.size;
- sent += iob.size;
- }
- while (len > 0);
- }
- }
- else
- {
- unsigned char *tmp;
- unsigned char *t;
- int i;
-
- tmp = alloca (len + 100);
- t = tmp;
- memset (tmp + len, 0xff, 100);
-
- sent = 0;
- do
- {
- iob.size = len > MAX_BLOCK_SIZE ? MAX_BLOCK_SIZE : len;
- iob.buf = tmp;
- sprintf (cmd, "memory b 0x%x l=%d", (int) memaddr, iob.size);
- retval = ExeAppReq ("GDB", GREADBLOCK, cmd, &iob);
- if (retval != 0)
- break;
- len -= iob.size;
- memaddr += iob.size;
- sent += iob.size;
- tmp += iob.size;
- }
- while (len > 0);
-
- if (retval == 0)
- {
- for (i = 0; i < 100; i++)
- {
- if (t[sent + i] != 0xff)
- {
- warning ("GREADBLOCK trashed bytes after transfer area.");
- break;
- }
- }
- memcpy (myaddr, t, sent);
- }
- }
-
- if (retval != 0)
- error ("3: ExeAppReq returned %d: cmd = %s", retval, cmd);
-
- return sent;
-}
-
-static void
-v850ice_files_info (struct target_ops *ignore)
-{
- puts_filtered ("Debugging a target via the NEC V850 ICE.\n");
-}
-
-static int
-v850ice_insert_breakpoint (CORE_ADDR addr, char *contents_cache)
-{
- long retval;
- char cmd[100];
- char buf[256];
- struct MessageIO iob;
-
- iob.size = 0;
- iob.buf = buf;
- sprintf (cmd, "%d, ", addr);
-
- retval = ExeAppReq ("GDB", GSETBREAK, cmd, &iob);
- if (retval)
- error ("ExeAppReq (GSETBREAK) returned %d: cmd = %s", retval, cmd);
-
- return 0;
-}
-
-static int
-v850ice_remove_breakpoint (CORE_ADDR addr, char *contents_cache)
-{
- long retval;
- char cmd[100];
- char buf[256];
- struct MessageIO iob;
-
- iob.size = 0;
- iob.buf = buf;
-
- sprintf (cmd, "%d, ", addr);
-
- retval = ExeAppReq ("GDB", GREMOVEBREAK, cmd, &iob);
- if (retval)
- error ("ExeAppReq (GREMOVEBREAK) returned %d: cmd = %s", retval, cmd);
-
- return 0;
-}
-
-static void
-v850ice_kill (void)
-{
- target_mourn_inferior ();
- inferior_ptid = null_ptid;
-}
-
-static void
-v850ice_mourn (void)
-{
-}
-
-static void
-v850ice_load (char *filename, int from_tty)
-{
- struct MessageIO iob;
- char buf[256];
-
- iob.size = 0;
- iob.buf = buf;
- generic_load (filename, from_tty);
- ExeAppReq ("GDB", GDOWNLOAD, filename, &iob);
-}
-
-static int
-ice_file (char *arg)
-{
- char *s;
-
- target_detach (NULL, 0);
- pop_target ();
-
- printf_unfiltered ("\n");
-
- s = arg;
- while (*s != '\0')
- {
- if (*s == '\\')
- *s = '/';
- s++;
- }
-
- /* Safegaurd against confusing the breakpoint routines... */
- delete_command (NULL, 0);
-
- /* Must supress from_tty, otherwise we could start asking if the
- user really wants to load a new symbol table, etc... */
- printf_unfiltered ("Reading symbols from %s...", arg);
- exec_open (arg, 0);
- symbol_file_add_main (arg, 0);
- printf_unfiltered ("done\n");
-
- /* exec_open will kill our target, so reinstall the ICE as
- the target. */
- v850ice_open (NULL, 0);
-
- togdb_force_update ();
- return 1;
-}
-
-static int
-ice_cont (char *c)
-{
- printf_filtered ("continue (ice)\n");
- ReplyMessage ((LRESULT) 1);
-
- if (gdbtk_interp == NULL)
- {
- continue_command (NULL, 1);
- }
- else
- Tcl_Eval (gdbtk_interp, "gdb_immediate continue");
-
- return 1;
-}
-
-static void
-do_gdb (char *cmd, char *str, void (*func) (char *, int), int count)
-{
- ReplyMessage ((LRESULT) 1);
-
- while (count--)
- {
- printf_unfiltered (str);
-
- if (gdbtk_interp == NULL)
- {
- func (NULL, 0);
- }
- else
- Tcl_Eval (gdbtk_interp, cmd);
- }
-}
-
-
-static int
-ice_stepi (char *c)
-{
- int count = (int) c;
-
- do_gdb ("gdb_immediate stepi", "stepi (ice)\n", stepi_command, count);
- return 1;
-}
-
-static int
-ice_nexti (char *c)
-{
- int count = (int) c;
-
- do_gdb ("gdb_immediate nexti", "nexti (ice)\n", nexti_command, count);
- return 1;
-}
-
-static void
-v850ice_command (char *arg, int from_tty)
-{
- struct MessageIO iob;
- char buf[256];
-
- iob.buf = buf;
- iob.size = 0;
- ExeAppReq ("GDB", GCOMMAND, arg, &iob);
-}
-
-static void
-togdb_force_update (void)
-{
- if (gdbtk_interp != NULL)
- Tcl_Eval (gdbtk_interp, "gdbtk_update");
-}
-
-static void
-view_source (CORE_ADDR addr)
-{
- char c[256];
-
- if (gdbtk_interp != NULL)
- {
- sprintf (c, "catch {set src [lindex [ManagedWin::find SrcWin] 0]\n$src location BROWSE [gdb_loc *0x%x]}", addr);
- Tcl_Eval (gdbtk_interp, c);
- }
-}
-
-/* Define the target subroutine names */
-
-static void
-init_850ice_ops (void)
-{
- v850ice_ops.to_shortname = "ice";
- v850ice_ops.to_longname = "NEC V850 ICE interface";
- v850ice_ops.to_doc = "Debug a system controlled by a NEC 850 ICE.";
- v850ice_ops.to_open = v850ice_open;
- v850ice_ops.to_close = v850ice_close;
- v850ice_ops.to_detach = v850ice_detach;
- v850ice_ops.to_resume = v850ice_resume;
- v850ice_ops.to_wait = v850ice_wait;
- v850ice_ops.to_fetch_registers = v850ice_fetch_registers;
- v850ice_ops.to_store_registers = v850ice_store_registers;
- v850ice_ops.to_prepare_to_store = v850ice_prepare_to_store;
- v850ice_ops.deprecated_xfer_memory = v850ice_xfer_memory;
- v850ice_ops.to_files_info = v850ice_files_info;
- v850ice_ops.to_insert_breakpoint = v850ice_insert_breakpoint;
- v850ice_ops.to_remove_breakpoint = v850ice_remove_breakpoint;
- v850ice_ops.to_kill = v850ice_kill;
- v850ice_ops.to_load = v850ice_load;
- v850ice_ops.to_mourn_inferior = v850ice_mourn;
- v850ice_ops.to_stop = v850ice_stop;
- v850ice_ops.to_stratum = process_stratum;
- v850ice_ops.to_has_all_memory = 1;
- v850ice_ops.to_has_memory = 1;
- v850ice_ops.to_has_stack = 1;
- v850ice_ops.to_has_registers = 1;
- v850ice_ops.to_has_execution = 1;
- v850ice_ops.to_magic = OPS_MAGIC;
-}
-
-void
-_initialize_v850ice (void)
-{
- init_850ice_ops ();
- add_target (&v850ice_ops);
-
- add_com ("ice", class_obscure, v850ice_command,
- "Send command to ICE");
-}