diff options
-rw-r--r-- | gdb/ChangeLog | 19 | ||||
-rw-r--r-- | gdb/MAINTAINERS | 15 | ||||
-rw-r--r-- | gdb/NEWS | 5 | ||||
-rw-r--r-- | gdb/config/h8300/h8300.mt | 6 | ||||
-rw-r--r-- | gdb/config/h8300/tm-h8300.h | 32 | ||||
-rw-r--r-- | gdb/config/mcore/mcore.mt | 4 | ||||
-rw-r--r-- | gdb/config/mn10300/mn10300.mt | 4 | ||||
-rw-r--r-- | gdb/config/ns32k/nbsdaout.mh | 4 | ||||
-rw-r--r-- | gdb/config/ns32k/nbsdaout.mt | 3 | ||||
-rw-r--r-- | gdb/config/ns32k/nm-nbsd.h | 33 | ||||
-rw-r--r-- | gdb/config/ns32k/nm-nbsdaout.h | 30 | ||||
-rw-r--r-- | gdb/config/ns32k/tm-ns32k.h | 35 | ||||
-rw-r--r-- | gdb/config/v850/v850.mt | 4 | ||||
-rw-r--r-- | gdb/configure.host | 2 | ||||
-rw-r--r-- | gdb/configure.tgt | 18 | ||||
-rw-r--r-- | gdb/h8300-tdep.c | 1383 | ||||
-rw-r--r-- | gdb/mcore-rom.c | 208 | ||||
-rw-r--r-- | gdb/mcore-tdep.c | 1111 | ||||
-rw-r--r-- | gdb/mn10300-tdep.c | 505 | ||||
-rw-r--r-- | gdb/ns32k-tdep.c | 573 | ||||
-rw-r--r-- | gdb/ns32k-tdep.h | 57 | ||||
-rw-r--r-- | gdb/ns32knbsd-nat.c | 367 | ||||
-rw-r--r-- | gdb/ns32knbsd-tdep.c | 62 | ||||
-rw-r--r-- | gdb/v850-tdep.c | 1249 | ||||
-rw-r--r-- | gdb/v850ice.c | 927 |
25 files changed, 29 insertions, 6627 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index ab1b438..a6b28a7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,22 @@ +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 diff --git a/gdb/MAINTAINERS b/gdb/MAINTAINERS index 5f43ad2..3325e0b 100644 --- a/gdb/MAINTAINERS +++ b/gdb/MAINTAINERS @@ -73,8 +73,7 @@ maintainer works with the native maintainer when resolving API issues. 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 @@ -94,17 +93,14 @@ maintainer works with the native maintainer when resolving API issues. 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 @@ -122,8 +118,7 @@ maintainer works with the native maintainer when resolving API issues. sparc --target=sparc-elf ,-Werror Maintenance only - v850 --target=v850-elf broken - Maintenance only + v850 Deleted vax --target=vax-netbsd ,-Werror Maintenance only @@ -6,6 +6,11 @@ * 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: diff --git a/gdb/config/h8300/h8300.mt b/gdb/config/h8300/h8300.mt deleted file mode 100644 index 4d27efc..0000000 --- a/gdb/config/h8300/h8300.mt +++ /dev/null @@ -1,6 +0,0 @@ -# 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 diff --git a/gdb/config/h8300/tm-h8300.h b/gdb/config/h8300/tm-h8300.h deleted file mode 100644 index a1c337e..0000000 --- a/gdb/config/h8300/tm-h8300.h +++ /dev/null @@ -1,32 +0,0 @@ -/* 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) - diff --git a/gdb/config/mcore/mcore.mt b/gdb/config/mcore/mcore.mt deleted file mode 100644 index 01b59d1..0000000 --- a/gdb/config/mcore/mcore.mt +++ /dev/null @@ -1,4 +0,0 @@ -# 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 diff --git a/gdb/config/mn10300/mn10300.mt b/gdb/config/mn10300/mn10300.mt deleted file mode 100644 index 0b54fd5..0000000 --- a/gdb/config/mn10300/mn10300.mt +++ /dev/null @@ -1,4 +0,0 @@ -# Target: Matsushita mn10300 -TDEPFILES= mn10300-tdep.o -SIM_OBS = remote-sim.o -SIM = ../sim/mn10300/libsim.a diff --git a/gdb/config/ns32k/nbsdaout.mh b/gdb/config/ns32k/nbsdaout.mh deleted file mode 100644 index db6fb9a..0000000 --- a/gdb/config/ns32k/nbsdaout.mh +++ /dev/null @@ -1,4 +0,0 @@ -# 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 diff --git a/gdb/config/ns32k/nbsdaout.mt b/gdb/config/ns32k/nbsdaout.mt deleted file mode 100644 index 130c260..0000000 --- a/gdb/config/ns32k/nbsdaout.mt +++ /dev/null @@ -1,3 +0,0 @@ -# Target: PC532 running NetBSD -TDEPFILES= ns32k-tdep.o ns32knbsd-tdep.o -DEPRECATED_TM_FILE= tm-ns32k.h diff --git a/gdb/config/ns32k/nm-nbsd.h b/gdb/config/ns32k/nm-nbsd.h deleted file mode 100644 index eb803f2..0000000 --- a/gdb/config/ns32k/nm-nbsd.h +++ /dev/null @@ -1,33 +0,0 @@ -/* 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 */ diff --git a/gdb/config/ns32k/nm-nbsdaout.h b/gdb/config/ns32k/nm-nbsdaout.h deleted file mode 100644 index aed3c7f..0000000 --- a/gdb/config/ns32k/nm-nbsdaout.h +++ /dev/null @@ -1,30 +0,0 @@ -/* 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 */ diff --git a/gdb/config/ns32k/tm-ns32k.h b/gdb/config/ns32k/tm-ns32k.h deleted file mode 100644 index a603fc8..0000000 --- a/gdb/config/ns32k/tm-ns32k.h +++ /dev/null @@ -1,35 +0,0 @@ -/* 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 */ diff --git a/gdb/config/v850/v850.mt b/gdb/config/v850/v850.mt deleted file mode 100644 index 701a240..0000000 --- a/gdb/config/v850/v850.mt +++ /dev/null @@ -1,4 +0,0 @@ -# Target: NEC V850 processor -TDEPFILES= v850-tdep.o -SIM_OBS = remote-sim.o -SIM = ../sim/v850/libsim.a diff --git a/gdb/configure.host b/gdb/configure.host index ad209c4..2e7741e 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -106,8 +106,6 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) 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) diff --git a/gdb/configure.tgt b/gdb/configure.tgt index 8f6c551..d19784e 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -28,7 +28,6 @@ s390*) gdb_target_cpu=s390 ;; 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 ;; @@ -71,9 +70,6 @@ cris*) gdb_target=cris ;; # OBSOLETE d10v-*-*) gdb_target=d10v ;; -h8300-*-*) gdb_target=h8300 ;; - - frv-*-*) gdb_target=frv ;; hppa*64*-*-hpux11*) gdb_target=hppa64 ;; @@ -127,8 +123,6 @@ m68*-*-uclinux*) gdb_target=monitor ;; 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 ;; @@ -140,10 +134,6 @@ mips*-*-netbsd* | mips*-*-knetbsd*-gnu) 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 ;; @@ -202,14 +192,6 @@ vax-*-netbsd* | vax-*-knetbsd*-gnu) 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 ;; diff --git a/gdb/h8300-tdep.c b/gdb/h8300-tdep.c deleted file mode 100644 index c501b89..0000000 --- a/gdb/h8300-tdep.c +++ /dev/null @@ -1,1383 +0,0 @@ -/* 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; -} - diff --git a/gdb/mcore-rom.c b/gdb/mcore-rom.c deleted file mode 100644 index dcc2cfb..0000000 --- a/gdb/mcore-rom.c +++ /dev/null @@ -1,208 +0,0 @@ -/* 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); -} diff --git a/gdb/mcore-tdep.c b/gdb/mcore-tdep.c deleted file mode 100644 index b1a1ccd..0000000 --- a/gdb/mcore-tdep.c +++ /dev/null @@ -1,1111 +0,0 @@ -/* 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)) - - -#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); -} - -/* 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 -} diff --git a/gdb/mn10300-tdep.c b/gdb/mn10300-tdep.c deleted file mode 100644 index b064a2b..0000000 --- a/gdb/mn10300-tdep.c +++ /dev/null @@ -1,505 +0,0 @@ -/* 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); -} - diff --git a/gdb/ns32k-tdep.c b/gdb/ns32k-tdep.c deleted file mode 100644 index 8813cb2..0000000 --- a/gdb/ns32k-tdep.c +++ /dev/null @@ -1,573 +0,0 @@ -/* 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; -} - -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; -} - - -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); - -} diff --git a/gdb/ns32k-tdep.h b/gdb/ns32k-tdep.h deleted file mode 100644 index 0b6551f..0000000 --- a/gdb/ns32k-tdep.h +++ /dev/null @@ -1,57 +0,0 @@ -/* 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 */ diff --git a/gdb/ns32knbsd-nat.c b/gdb/ns32knbsd-nat.c deleted file mode 100644 index 520dfe4..0000000 --- a/gdb/ns32knbsd-nat.c +++ /dev/null @@ -1,367 +0,0 @@ -/* 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); -} - - -/* 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); -} - - -/* - * 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); -} diff --git a/gdb/ns32knbsd-tdep.c b/gdb/ns32knbsd-tdep.c deleted file mode 100644 index 26d18e5..0000000 --- a/gdb/ns32knbsd-tdep.c +++ /dev/null @@ -1,62 +0,0 @@ -/* 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); -} diff --git a/gdb/v850-tdep.c b/gdb/v850-tdep.c deleted file mode 100644 index 6c7265b..0000000 --- a/gdb/v850-tdep.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* 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; -} - - - -/* 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; -} - - - - -/* 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); -} diff --git a/gdb/v850ice.c b/gdb/v850ice.c deleted file mode 100644 index 93746ff..0000000 --- a/gdb/v850ice.c +++ /dev/null @@ -1,927 +0,0 @@ -/* 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"); -} |