diff options
author | obrien <obrien@FreeBSD.org> | 2000-08-02 11:56:42 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2000-08-02 11:56:42 +0000 |
commit | 9e0c7756d9c079ea44f81d3e743ef817bbd614e4 (patch) | |
tree | 7d862786f9007311b58a4412bb59f30b264e0200 /contrib/gdb | |
parent | cb57b94ee39b660cfc6b617c2551208cf58317b5 (diff) | |
download | FreeBSD-src-9e0c7756d9c079ea44f81d3e743ef817bbd614e4.zip FreeBSD-src-9e0c7756d9c079ea44f81d3e743ef817bbd614e4.tar.gz |
These files are for an arch we don't care about.
Diffstat (limited to 'contrib/gdb')
-rw-r--r-- | contrib/gdb/gdb/m32r-rom.c | 650 | ||||
-rw-r--r-- | contrib/gdb/gdb/m32r-stub.c | 1685 | ||||
-rw-r--r-- | contrib/gdb/gdb/m32r-tdep.c | 745 |
3 files changed, 0 insertions, 3080 deletions
diff --git a/contrib/gdb/gdb/m32r-rom.c b/contrib/gdb/gdb/m32r-rom.c deleted file mode 100644 index 2be833e..0000000 --- a/contrib/gdb/gdb/m32r-rom.c +++ /dev/null @@ -1,650 +0,0 @@ -/* Remote debugging interface to m32r and mon2000 ROM monitors for GDB, - the GNU debugger. - Copyright 1996 Free Software Foundation, Inc. - - Adapted by Michael Snyder of Cygnus Support. - -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. */ - -/* This module defines communication with the Mitsubishi m32r monitor */ - -#include "defs.h" -#include "gdbcore.h" -#include "target.h" -#include "monitor.h" -#include "serial.h" -#include "symtab.h" -#include "command.h" -#include "gdbcmd.h" -#include "symfile.h" /* for generic load */ -#include <time.h> /* for time_t */ -#include "gdb_string.h" -#include "objfiles.h" /* for ALL_OBJFILES etc. */ - - -extern void report_transfer_performance PARAMS ((unsigned long, time_t, time_t)); - -#ifndef _MSC_VER -/* - * All this stuff just to get my host computer's IP address! - */ -#include <sys/types.h> -#include <netdb.h> /* for hostent */ -#include <netinet/in.h> /* for struct in_addr */ -#if 1 -#include <arpa/inet.h> /* for inet_ntoa */ -#endif -#endif - -static char *board_addr; /* user-settable IP address for M32R-EVA */ -static char *server_addr; /* user-settable IP address for gdb host */ -static char *download_path; /* user-settable path for SREC files */ - - -/* - * Function: m32r_load_1 (helper function) - */ - -static void -m32r_load_section (abfd, s, data_count) - bfd *abfd; - asection *s; - unsigned int *data_count; -{ - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_lma (abfd, s); - unsigned int buffer, i; - - *data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx lma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - monitor_printf ("%x mw\r" , section_base); - for (i = 0; i < section_size; i += 4) - { - QUIT; - monitor_expect (" -> ", NULL, 0); - bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); - monitor_printf ("%x\n", buffer); - } - monitor_expect (" -> ", NULL, 0); - monitor_printf ("q\n"); - monitor_expect_prompt (NULL, 0); - } -} - -static int -m32r_load_1 (dummy) - void *dummy; -{ - int data_count = 0; - - bfd_map_over_sections ((bfd *) dummy, m32r_load_section, &data_count); - return data_count; -} - -/* - * Function: m32r_load (an alternate way to load) - */ - -static void -m32r_load (filename, from_tty) - char *filename; - int from_tty; -{ - extern int inferior_pid; - bfd *abfd; - asection *s; - unsigned int i, data_count = 0; - time_t start_time, end_time; /* for timing of download */ - - if (filename == NULL || filename[0] == 0) - filename = get_exec_file (1); - - abfd = bfd_openr (filename, 0); - if (!abfd) - error ("Unable to open file %s\n", filename); - if (bfd_check_format (abfd, bfd_object) == 0) - error ("File is not an object file\n"); - start_time = time (NULL); -#if 0 - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_vma (abfd, s); - unsigned int buffer; - - data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx vma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - monitor_printf ("%x mw\r" , section_base); - for (i = 0; i < section_size; i += 4) - { - monitor_expect (" -> ", NULL, 0); - bfd_get_section_contents (abfd, s, (char *) &buffer, i, 4); - monitor_printf ("%x\n", buffer); - } - monitor_expect (" -> ", NULL, 0); - monitor_printf ("q\n"); - monitor_expect_prompt (NULL, 0); - } -#else - if (!(catch_errors (m32r_load_1, abfd, "Load aborted!\n", RETURN_MASK_ALL))) - { - monitor_printf ("q\n"); - return; - } -#endif - end_time = time (NULL); - printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); - report_transfer_performance (data_count, start_time, end_time); - - /* Finally, make the PC point at the start address */ - if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); - - inferior_pid = 0; /* No process now */ - - /* This is necessary because many things were based on the PC at the - time that we attached to the monitor, which is no longer valid - now that we have loaded new code (and just changed the PC). - Another way to do this might be to call normal_stop, except that - the stack may not be valid, and things would get horribly - confused... */ - - clear_symtab_users (); -} - -static void -m32r_load_gen (filename, from_tty) - char *filename; - int from_tty; -{ - generic_load (filename, from_tty); -} - -static void m32r_open PARAMS ((char *args, int from_tty)); -static void mon2000_open PARAMS ((char *args, int from_tty)); - -/* This array of registers needs to match the indexes used by GDB. The - whole reason this exists is because the various ROM monitors use - different names than GDB does, and don't support all the registers - either. So, typing "info reg sp" becomes an "A7". */ - -static char *m32r_regnames[] = -{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", - "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", - "psw", "cbr", "spi", "spu", "bpc", "pc", "accl", "acch", -}; - -static void -m32r_supply_register (regname, regnamelen, val, vallen) - char *regname; - int regnamelen; - char *val; - int vallen; -{ - int regno; - int num_regs = sizeof(m32r_regnames) / sizeof(m32r_regnames[0]); - - for (regno = 0; regno < num_regs; regno++) - if (strncmp(regname, m32r_regnames[regno], regnamelen) == 0) - break; - - if (regno >= num_regs) - return; /* no match */ - - if (regno == ACCL_REGNUM) - { /* special handling for 64-bit acc reg */ - monitor_supply_register (ACCH_REGNUM, val); - if (val = (char *) strchr(val, ':')) /* skip past ':' to get 2nd word */ - monitor_supply_register (ACCL_REGNUM, val + 1); - } - else - { - monitor_supply_register (regno, val); - if (regno == PSW_REGNUM) - { - unsigned long psw = strtoul (val, NULL, 16); - char *zero = "00000000", *one = "00000001"; - -#ifdef SM_REGNUM - /* Stack mode bit */ - monitor_supply_register (SM_REGNUM, (psw & 0x80) ? one : zero); -#endif -#ifdef BSM_REGNUM - /* Backup stack mode bit */ - monitor_supply_register (BSM_REGNUM, (psw & 0x8000) ? one : zero); -#endif -#ifdef IE_REGNUM - /* Interrupt enable bit */ - monitor_supply_register (IE_REGNUM, (psw & 0x40) ? one : zero); -#endif -#ifdef BIE_REGNUM - /* Backup interrupt enable bit */ - monitor_supply_register (BIE_REGNUM, (psw & 0x4000) ? one : zero); -#endif -#ifdef COND_REGNUM - /* Condition bit (carry etc.) */ - monitor_supply_register (COND_REGNUM, (psw & 0x1) ? one : zero); -#endif -#ifdef CBR_REGNUM - monitor_supply_register (CBR_REGNUM, (psw & 0x1) ? one : zero); -#endif -#ifdef BPC_REGNUM - monitor_supply_register (BPC_REGNUM, zero); /* KLUDGE: (???????) */ -#endif -#ifdef BCARRY_REGNUM - monitor_supply_register (BCARRY_REGNUM, zero); /* KLUDGE: (??????) */ -#endif - } - - if (regno == SPI_REGNUM || regno == SPU_REGNUM) - { /* special handling for stack pointer (spu or spi) */ - unsigned long stackmode = read_register (PSW_REGNUM) & 0x80; - - if (regno == SPI_REGNUM && !stackmode) /* SP == SPI */ - monitor_supply_register (SP_REGNUM, val); - else if (regno == SPU_REGNUM && stackmode) /* SP == SPU */ - monitor_supply_register (SP_REGNUM, val); - } - } -} - -/* m32r RevC board monitor */ - -static struct target_ops m32r_ops; - -static char *m32r_inits[] = {"\r", NULL}; - -static struct monitor_ops m32r_cmds ; - -static void -init_m32r_cmds(void) -{ - m32r_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; - m32r_cmds.init = m32r_inits; /* Init strings */ - m32r_cmds.cont = "go\r"; /* continue command */ - m32r_cmds.step = "step\r"; /* single step */ - m32r_cmds.stop = NULL; /* interrupt command */ - m32r_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ - m32r_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ - m32r_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ - m32r_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ - m32r_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ - m32r_cmds.setmem.cmdw = "%x 1 %x fillh\r";/* setmem.cmdw (addr, value) */ - m32r_cmds.setmem.cmdl = "%x 1 %x fillw\r";/* setmem.cmdl (addr, value) */ - m32r_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - m32r_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - m32r_cmds.setmem.term = NULL; /* setmem.term */ - m32r_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - m32r_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ - m32r_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - m32r_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - m32r_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - m32r_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - m32r_cmds.getmem.term = NULL; /* getmem.term */ - m32r_cmds.getmem.term_cmd = NULL ; /* getmem.term_cmd */ - m32r_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ - m32r_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - m32r_cmds.setreg.term = NULL; /* setreg.term */ - m32r_cmds.setreg.term_cmd = NULL ; /* setreg.term_cmd */ - m32r_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ - m32r_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ - m32r_cmds.getreg.term = NULL; /* getreg.term */ - m32r_cmds.getreg.term_cmd = NULL ; /* getreg.term_cmd */ - m32r_cmds.dump_registers = ".reg\r"; /* dump_registers */ - m32r_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - m32r_cmds.supply_register = m32r_supply_register; /* supply_register */ - m32r_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - m32r_cmds.load = NULL; /* download command */ - m32r_cmds.loadresp = NULL; /* load response */ - m32r_cmds.prompt = "ok "; /* monitor command prompt */ - m32r_cmds.line_term = "\r"; /* end-of-line terminator */ - m32r_cmds.cmd_end = NULL; /* optional command terminator */ - m32r_cmds.target = &m32r_ops; /* target operations */ - m32r_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - m32r_cmds.regnames = m32r_regnames; /* registers names */ - m32r_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */ -} /* init_m32r_cmds */ - -static void -m32r_open(args, from_tty) - char *args; - int from_tty; -{ - monitor_open (args, &m32r_cmds, from_tty); -} - -/* Mon2000 monitor (MSA2000 board) */ - -static struct target_ops mon2000_ops; -static struct monitor_ops mon2000_cmds; - -static void -init_mon2000_cmds(void) -{ - mon2000_cmds.flags = MO_CLR_BREAK_USES_ADDR | MO_REGISTER_VALUE_FIRST; - mon2000_cmds.init = m32r_inits; /* Init strings */ - mon2000_cmds.cont = "go\r"; /* continue command */ - mon2000_cmds.step = "step\r"; /* single step */ - mon2000_cmds.stop = NULL; /* interrupt command */ - mon2000_cmds.set_break = "%x +bp\r"; /* set a breakpoint */ - mon2000_cmds.clr_break = "%x -bp\r"; /* clear a breakpoint */ - mon2000_cmds.clr_all_break = "bpoff\r"; /* clear all breakpoints */ - mon2000_cmds.fill = "%x %x %x fill\r"; /* fill (start length val) */ - mon2000_cmds.setmem.cmdb = "%x 1 %x fill\r"; /* setmem.cmdb (addr, value) */ - mon2000_cmds.setmem.cmdw = "%x 1 %x fillh\r";/* setmem.cmdw (addr, value) */ - mon2000_cmds.setmem.cmdl = "%x 1 %x fillw\r";/* setmem.cmdl (addr, value) */ - mon2000_cmds.setmem.cmdll = NULL; /* setmem.cmdll (addr, value) */ - mon2000_cmds.setmem.resp_delim = NULL; /* setmem.resp_delim */ - mon2000_cmds.setmem.term = NULL; /* setmem.term */ - mon2000_cmds.setmem.term_cmd = NULL; /* setmem.term_cmd */ - mon2000_cmds.getmem.cmdb = "%x %x dump\r"; /* getmem.cmdb (addr, len) */ - mon2000_cmds.getmem.cmdw = NULL; /* getmem.cmdw (addr, len) */ - mon2000_cmds.getmem.cmdl = NULL; /* getmem.cmdl (addr, len) */ - mon2000_cmds.getmem.cmdll = NULL; /* getmem.cmdll (addr, len) */ - mon2000_cmds.getmem.resp_delim = ": "; /* getmem.resp_delim */ - mon2000_cmds.getmem.term = NULL; /* getmem.term */ - mon2000_cmds.getmem.term_cmd = NULL ; /* getmem.term_cmd */ - mon2000_cmds.setreg.cmd = "%x to %%%s\r"; /* setreg.cmd (name, value) */ - mon2000_cmds.setreg.resp_delim = NULL; /* setreg.resp_delim */ - mon2000_cmds.setreg.term = NULL; /* setreg.term */ - mon2000_cmds.setreg.term_cmd = NULL ; /* setreg.term_cmd */ - mon2000_cmds.getreg.cmd = NULL; /* getreg.cmd (name) */ - mon2000_cmds.getreg.resp_delim = NULL; /* getreg.resp_delim */ - mon2000_cmds.getreg.term = NULL; /* getreg.term */ - mon2000_cmds.getreg.term_cmd = NULL ; /* getreg.term_cmd */ - mon2000_cmds.dump_registers = ".reg\r"; /* dump_registers */ - mon2000_cmds.register_pattern = "\\(\\w+\\) += \\([0-9a-fA-F]+\\b\\)"; /* register_pattern */ - mon2000_cmds.supply_register = m32r_supply_register; /* supply_register */ - mon2000_cmds.load_routine = NULL; /* load_routine (defaults to SRECs) */ - mon2000_cmds.load = NULL; /* download command */ - mon2000_cmds.loadresp = NULL; /* load response */ - mon2000_cmds.prompt = "Mon2000>"; /* monitor command prompt */ - mon2000_cmds.line_term = "\r"; /* end-of-line terminator */ - mon2000_cmds.cmd_end = NULL; /* optional command terminator */ - mon2000_cmds.target = &mon2000_ops; /* target operations */ - mon2000_cmds.stopbits = SERIAL_1_STOPBITS; /* number of stop bits */ - mon2000_cmds.regnames = m32r_regnames; /* registers names */ - mon2000_cmds.magic = MONITOR_OPS_MAGIC ; /* magic */ -} /* init_mon2000_cmds */ - -static void -mon2000_open(args, from_tty) - char *args; - int from_tty; -{ - monitor_open (args, &mon2000_cmds, from_tty); -} - -#ifndef _MSC_VER - -/* Function: set_board_address - Tell the BootOne monitor what it's ethernet IP address is. */ - -static void -m32r_set_board_address (args, from_tty) - char *args; - int from_tty; -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("ulip %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (IP address for M32R-EVA board)"); -} - -/* Function: set_server_address - Tell the BootOne monitor what gdb's ethernet IP address is. */ - -static void -m32r_set_server_address (args, from_tty) - char *args; - int from_tty; -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("uhip %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (IP address of GDB's host computer)"); -} - -/* Function: set_download_path - Tell the BootOne monitor the default path for downloadable SREC files. */ - -static void -m32r_set_download_path (args, from_tty) - char *args; - int from_tty; -{ - int resp_len; - char buf[1024]; - - if (args && *args) - { - monitor_printf ("up %s\n", args); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); - /* now parse the result for success */ - } - else - error ("Requires argument (default path for downloadable SREC files)"); -} - -static void -m32r_upload_command (args, from_tty) - char *args; - int from_tty; -{ - bfd *abfd; - asection *s; - time_t start_time, end_time; /* for timing of download */ - extern int inferior_pid; - int resp_len, data_count = 0; - char buf[1024]; - struct hostent *hostent; - struct in_addr inet_addr; - - /* first check to see if there's an ethernet port! */ - monitor_printf ("ust\r"); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); - if (!strchr (buf, ':')) - error ("No ethernet connection!"); - - if (board_addr == 0) - { - /* scan second colon in the output from the "ust" command */ - char * myIPaddress = strchr (strchr (buf, ':') + 1, ':') + 1; - - while (isspace(*myIPaddress)) - myIPaddress++; - - if (!strncmp (myIPaddress, "0.0.", 4)) /* empty */ - error ("Please use 'set board-address' to set the M32R-EVA board's IP address."); - if (strchr (myIPaddress, '(')) - *(strchr (myIPaddress, '(')) = '\0'; /* delete trailing junk */ - board_addr = strsave (myIPaddress); - } - if (server_addr == 0) - { - buf[0] = 0; - gethostname (buf, sizeof(buf)); - if (buf[0] != 0) - hostent = gethostbyname (buf); - if (hostent != 0) - { -#if 1 - memcpy (&inet_addr.s_addr, hostent->h_addr, - sizeof(inet_addr.s_addr)); - server_addr = (char *) inet_ntoa (inet_addr); -#else - server_addr = (char *) inet_ntoa (hostent->h_addr); -#endif - } - if (server_addr == 0) /* failed? */ - error ("Need to know gdb host computer's IP address (use 'set server-address')"); - } - - if (args == 0 || args[0] == 0) /* no args: upload the current file */ - args = get_exec_file (1); - - if (args[0] != '/' && download_path == 0) - if (current_directory) - download_path = strsave (current_directory); - else - error ("Need to know default download path (use 'set download-path')"); - - start_time = time (NULL); - monitor_printf ("uhip %s\r", server_addr); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */ - monitor_printf ("ulip %s\r", board_addr); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */ - if (args[0] != '/') - monitor_printf ("up %s\r", download_path); /* use default path */ - else - monitor_printf ("up\r"); /* rooted filename/path */ - resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */ - - if (strrchr (args, '.') && !strcmp (strrchr (args, '.'), ".srec")) - monitor_printf ("ul %s\r", args); - else /* add ".srec" suffix */ - monitor_printf ("ul %s.srec\r", args); - resp_len = monitor_expect_prompt (buf, sizeof(buf)); /* parse result? */ - - if (buf[0] == 0 || strstr(buf, "complete") == 0) - error("Upload file not found: %s.srec\nCheck IP addresses and download path.", args); - else - printf_filtered (" -- Ethernet load complete.\n"); - - end_time = time (NULL); - if (abfd = bfd_openr (args, 0)) - { /* Download is done -- print section statistics */ - if (bfd_check_format (abfd, bfd_object) == 0) - { - printf_filtered ("File is not an object file\n"); - } - for (s = abfd->sections; s; s = s->next) - if (s->flags & SEC_LOAD) - { - bfd_size_type section_size = bfd_section_size (abfd, s); - bfd_vma section_base = bfd_section_lma (abfd, s); - unsigned int buffer; - - data_count += section_size; - - printf_filtered ("Loading section %s, size 0x%lx lma ", - bfd_section_name (abfd, s), section_size); - print_address_numeric (section_base, 1, gdb_stdout); - printf_filtered ("\n"); - gdb_flush (gdb_stdout); - } - /* Finally, make the PC point at the start address */ - write_pc (bfd_get_start_address (abfd)); - report_transfer_performance (data_count, start_time, end_time); - printf_filtered ("Start address 0x%lx\n", bfd_get_start_address (abfd)); - } - inferior_pid = 0; /* No process now */ - - /* This is necessary because many things were based on the PC at the - time that we attached to the monitor, which is no longer valid - now that we have loaded new code (and just changed the PC). - Another way to do this might be to call normal_stop, except that - the stack may not be valid, and things would get horribly - confused... */ - - clear_symtab_users (); -} - -#endif /* ! _MSC_VER */ - -void -_initialize_m32r_rom () -{ - /* Initialize m32r RevC monitor target */ - init_m32r_cmds () ; - init_monitor_ops (&m32r_ops); - - m32r_ops.to_shortname = "m32r"; - m32r_ops.to_longname = "m32r monitor"; - m32r_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ - m32r_ops.to_doc = "Debug via the m32r monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - m32r_ops.to_open = m32r_open; - add_target (&m32r_ops); - - /* Initialize mon2000 monitor target */ - init_mon2000_cmds (); - init_monitor_ops (&mon2000_ops); - - mon2000_ops.to_shortname = "mon2000"; - mon2000_ops.to_longname = "Mon2000 monitor"; - mon2000_ops.to_load = m32r_load_gen; /* monitor lacks a download command */ - mon2000_ops.to_doc = "Debug via the Mon2000 monitor.\n\ -Specify the serial device it is connected to (e.g. /dev/ttya)."; - mon2000_ops.to_open = mon2000_open; - add_target (&mon2000_ops); - -#ifndef _MSC_VER - add_show_from_set - (add_set_cmd ("download-path", class_obscure, var_string, - (char *) &download_path, - "Set the default path for downloadable SREC files.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("board-address", class_obscure, var_string, - (char *) &board_addr, - "Set IP address for M32R-EVA target board.", - &setlist), - &showlist); - - add_show_from_set - (add_set_cmd ("server-address", class_obscure, var_string, - (char *) &server_addr, - "Set IP address for download server (GDB's host computer).", - &setlist), - &showlist); - - add_com ("upload", class_obscure, m32r_upload_command, - "Upload the srec file via the monitor's Ethernet upload capability."); - - add_com ("tload", class_obscure, m32r_load, "test upload command."); -#endif -} diff --git a/contrib/gdb/gdb/m32r-stub.c b/contrib/gdb/gdb/m32r-stub.c deleted file mode 100644 index 60c828f..0000000 --- a/contrib/gdb/gdb/m32r-stub.c +++ /dev/null @@ -1,1685 +0,0 @@ -/**************************************************************************** - - THIS SOFTWARE IS NOT COPYRIGHTED - - HP offers the following for use in the public domain. HP makes no - warranty with regard to the software or it's performance and the - user accepts the software "AS IS" with all faults. - - HP DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD - TO THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - -****************************************************************************/ - -/**************************************************************************** - * Header: remcom.c,v 1.34 91/03/09 12:29:49 glenne Exp $ - * - * Module name: remcom.c $ - * Revision: 1.34 $ - * Date: 91/03/09 12:29:49 $ - * Contributor: Lake Stevens Instrument Division$ - * - * Description: low level support for gdb debugger. $ - * - * Considerations: only works on target hardware $ - * - * Written by: Glenn Engel $ - * ModuleState: Experimental $ - * - * NOTES: See Below $ - * - * Modified for M32R by Michael Snyder, Cygnus Support. - * - * To enable debugger support, two things need to happen. One, a - * call to set_debug_traps() is necessary in order to allow any breakpoints - * or error conditions to be properly intercepted and reported to gdb. - * Two, a breakpoint needs to be generated to begin communication. This - * is most easily accomplished by a call to breakpoint(). Breakpoint() - * simulates a breakpoint by executing a trap #1. - * - * The external function exceptionHandler() is - * used to attach a specific handler to a specific M32R vector number. - * It should use the same privilege level it runs at. It should - * install it as an interrupt gate so that interrupts are masked - * while the handler runs. - * - * Because gdb will sometimes write to the stack area to execute function - * calls, this program cannot rely on using the supervisor stack so it - * uses it's own stack area reserved in the int array remcomStack. - * - ************* - * - * The following gdb commands are supported: - * - * command function Return value - * - * g return the value of the CPU registers hex data or ENN - * G set the value of the CPU registers OK or ENN - * - * mAA..AA,LLLL Read LLLL bytes at address AA..AA hex data or ENN - * MAA..AA,LLLL: Write LLLL bytes at address AA.AA OK or ENN - * XAA..AA,LLLL: Write LLLL binary bytes at address OK or ENN - * AA..AA - * - * c Resume at current address SNN ( signal NN) - * cAA..AA Continue at address AA..AA SNN - * - * s Step one instruction SNN - * sAA..AA Step one instruction from AA..AA SNN - * - * k kill - * - * ? What was the last sigval ? SNN (signal NN) - * - * All commands and responses are sent with a packet which includes a - * checksum. A packet consists of - * - * $<packet info>#<checksum>. - * - * where - * <packet info> :: <characters representing the command or response> - * <checksum> :: <two hex digits computed as modulo 256 sum of <packetinfo>> - * - * When a packet is received, it is first acknowledged with either '+' or '-'. - * '+' indicates a successful transfer. '-' indicates a failed transfer. - * - * Example: - * - * Host: Reply: - * $m0,10#2a +$00010203040506070809101112131415#42 - * - ****************************************************************************/ - - -/************************************************************************ - * - * external low-level support routines - */ -extern void putDebugChar(); /* write a single character */ -extern int getDebugChar(); /* read and return a single char */ -extern void exceptionHandler(); /* assign an exception handler */ - -/***************************************************************************** - * BUFMAX defines the maximum number of characters in inbound/outbound buffers - * at least NUMREGBYTES*2 are needed for register packets - */ -#define BUFMAX 400 - -static char initialized; /* boolean flag. != 0 means we've been initialized */ - -int remote_debug; -/* debug > 0 prints ill-formed commands in valid packets & checksum errors */ - -static const unsigned char hexchars[]="0123456789abcdef"; - -#define NUMREGS 24 - -/* Number of bytes of registers. */ -#define NUMREGBYTES (NUMREGS * 4) -enum regnames { R0, R1, R2, R3, R4, R5, R6, R7, - R8, R9, R10, R11, R12, R13, R14, R15, - PSW, CBR, SPI, SPU, BPC, PC, ACCL, ACCH }; - -enum SYS_calls { - SYS_null, - SYS_exit, - SYS_open, - SYS_close, - SYS_read, - SYS_write, - SYS_lseek, - SYS_unlink, - SYS_getpid, - SYS_kill, - SYS_fstat, - SYS_sbrk, - SYS_fork, - SYS_execve, - SYS_wait4, - SYS_link, - SYS_chdir, - SYS_stat, - SYS_utime, - SYS_chown, - SYS_chmod, - SYS_time, - SYS_pipe }; - -static int registers[NUMREGS]; - -#define STACKSIZE 8096 -static unsigned char remcomInBuffer[BUFMAX]; -static unsigned char remcomOutBuffer[BUFMAX]; -static int remcomStack[STACKSIZE/sizeof(int)]; -static int* stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - -static unsigned int save_vectors[18]; /* previous exception vectors */ - -/* Indicate to caller of mem2hex or hex2mem that there has been an error. */ -static volatile int mem_err = 0; - -/* Store the vector number here (since GDB only gets the signal - number through the usual means, and that's not very specific). */ -int gdb_m32r_vector = -1; - -#if 0 -#include "syscall.h" /* for SYS_exit, SYS_write etc. */ -#endif - -/* Global entry points: - */ - -extern void handle_exception(int); -extern void set_debug_traps(void); -extern void breakpoint(void); - -/* Local functions: - */ - -static int computeSignal(int); -static void putpacket(unsigned char *); -static void getpacket(unsigned char *); - -static unsigned char *mem2hex(unsigned char *, unsigned char *, int, int); -static unsigned char *hex2mem(unsigned char *, unsigned char *, int, int); -static int hexToInt(unsigned char **, int *); -static unsigned char *bin2mem(unsigned char *, unsigned char *, int, int); -static void stash_registers(void); -static void restore_registers(void); -static int prepare_to_step(int); -static int finish_from_step(void); - -static void gdb_error(char *, char *); -static int gdb_putchar(int), gdb_puts(char *), gdb_write(char *, int); - -static unsigned char *strcpy (unsigned char *, const unsigned char *); -static int strlen (const unsigned char *); - -/* - * This function does all command procesing for interfacing to gdb. - */ - -void -handle_exception(int exceptionVector) -{ - int sigval; - int addr, length, i; - unsigned char * ptr; - unsigned char buf[16]; - int binary; - - if (!finish_from_step()) - return; /* "false step": let the target continue */ - - gdb_m32r_vector = exceptionVector; - - if (remote_debug) - { - mem2hex((unsigned char *) &exceptionVector, buf, 4, 0); - gdb_error("Handle exception %s, ", buf); - mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); - gdb_error("PC == 0x%s\n", buf); - } - - /* reply to host that an exception has occurred */ - sigval = computeSignal( exceptionVector ); - - ptr = remcomOutBuffer; - - *ptr++ = 'T'; /* notify gdb with signo, PC, FP and SP */ - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - - *ptr++ = hexchars[PC >> 4]; - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); /* PC */ - *ptr++ = ';'; - - *ptr++ = hexchars[R13 >> 4]; - *ptr++ = hexchars[R13 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); /* FP */ - *ptr++ = ';'; - - *ptr++ = hexchars[R15 >> 4]; - *ptr++ = hexchars[R15 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); /* SP */ - *ptr++ = ';'; - *ptr++ = 0; - - if (exceptionVector == 0) /* simulated SYS call stuff */ - { - mem2hex((unsigned char *) ®isters[PC], buf, 4, 0); - switch (registers[R0]) { - case SYS_exit: - gdb_error("Target program has exited at %s\n", buf); - ptr = remcomOutBuffer; - *ptr++ = 'W'; - sigval = registers[R1] & 0xff; - *ptr++ = hexchars[sigval >> 4]; - *ptr++ = hexchars[sigval & 0xf]; - *ptr++ = 0; - break; - case SYS_open: - gdb_error("Target attempts SYS_open call at %s\n", buf); - break; - case SYS_close: - gdb_error("Target attempts SYS_close call at %s\n", buf); - break; - case SYS_read: - gdb_error("Target attempts SYS_read call at %s\n", buf); - break; - case SYS_write: - if (registers[R1] == 1 || /* write to stdout */ - registers[R1] == 2) /* write to stderr */ - { /* (we can do that) */ - registers[R0] = gdb_write((void *) registers[R2], registers[R3]); - return; - } - else - gdb_error("Target attempts SYS_write call at %s\n", buf); - break; - case SYS_lseek: - gdb_error("Target attempts SYS_lseek call at %s\n", buf); - break; - case SYS_unlink: - gdb_error("Target attempts SYS_unlink call at %s\n", buf); - break; - case SYS_getpid: - gdb_error("Target attempts SYS_getpid call at %s\n", buf); - break; - case SYS_kill: - gdb_error("Target attempts SYS_kill call at %s\n", buf); - break; - case SYS_fstat: - gdb_error("Target attempts SYS_fstat call at %s\n", buf); - break; - default: - gdb_error("Target attempts unknown SYS call at %s\n", buf); - break; - } - } - - putpacket(remcomOutBuffer); - - while (1==1) { - remcomOutBuffer[0] = 0; - getpacket(remcomInBuffer); - binary = 0; - switch (remcomInBuffer[0]) { - default: /* Unknown code. Return an empty reply message. */ - break; - case 'R': - ptr = &remcomInBuffer[1]; - if (hexToInt (&ptr, &addr)) - registers[PC] = addr; - strcpy(remcomOutBuffer, "OK"); - break; - case '!': - strcpy(remcomOutBuffer, "OK"); - break; - case 'X': /* XAA..AA,LLLL:<binary data>#cs */ - binary = 1; - case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ - /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ - { - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - if (*(ptr++) == ':') - { - mem_err = 0; - if (binary) - bin2mem (ptr, (unsigned char *) addr, length, 1); - else - hex2mem(ptr, (unsigned char*) addr, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - gdb_error ("memory fault", ""); - } else { - strcpy(remcomOutBuffer,"OK"); - } - ptr = 0; - } - if (ptr) - { - strcpy(remcomOutBuffer,"E02"); - gdb_error("malformed write memory command: %s", - remcomInBuffer); - } - } - break; - case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ - /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - if (*(ptr++) == ',') - if (hexToInt(&ptr,&length)) - { - ptr = 0; - mem_err = 0; - mem2hex((unsigned char*) addr, remcomOutBuffer, length, 1); - if (mem_err) { - strcpy (remcomOutBuffer, "E03"); - gdb_error ("memory fault", ""); - } - } - if (ptr) - { - strcpy(remcomOutBuffer,"E01"); - gdb_error("malformed read memory command: %s", - remcomInBuffer); - } - break; - case '?': - remcomOutBuffer[0] = 'S'; - remcomOutBuffer[1] = hexchars[sigval >> 4]; - remcomOutBuffer[2] = hexchars[sigval % 16]; - remcomOutBuffer[3] = 0; - break; - case 'd': - remote_debug = !(remote_debug); /* toggle debug flag */ - break; - case 'g': /* return the value of the CPU registers */ - mem2hex((unsigned char*) registers, remcomOutBuffer, NUMREGBYTES, 0); - break; - case 'P': /* set the value of a single CPU register - return OK */ - { - int regno; - - ptr = &remcomInBuffer[1]; - if (hexToInt (&ptr, ®no) && *ptr++ == '=') - if (regno >= 0 && regno < NUMREGS) - { - int stackmode; - - hex2mem (ptr, (unsigned char *) ®isters[regno], 4, 0); - /* - * Since we just changed a single CPU register, let's - * make sure to keep the several stack pointers consistant. - */ - stackmode = registers[PSW] & 0x80; - if (regno == R15) /* stack pointer changed */ - { /* need to change SPI or SPU */ - if (stackmode == 0) - registers[SPI] = registers[R15]; - else - registers[SPU] = registers[R15]; - } - else if (regno == SPU) /* "user" stack pointer changed */ - { - if (stackmode != 0) /* stack in user mode: copy SP */ - registers[R15] = registers[SPU]; - } - else if (regno == SPI) /* "interrupt" stack pointer changed */ - { - if (stackmode == 0) /* stack in interrupt mode: copy SP */ - registers[R15] = registers[SPI]; - } - else if (regno == PSW) /* stack mode may have changed! */ - { /* force SP to either SPU or SPI */ - if (stackmode == 0) /* stack in user mode */ - registers[R15] = registers[SPI]; - else /* stack in interrupt mode */ - registers[R15] = registers[SPU]; - } - strcpy (remcomOutBuffer, "OK"); - break; - } - strcpy (remcomOutBuffer, "P01"); - break; - } - case 'G': /* set the value of the CPU registers - return OK */ - hex2mem(&remcomInBuffer[1], (unsigned char*) registers, NUMREGBYTES, 0); - strcpy(remcomOutBuffer,"OK"); - break; - case 's': /* sAA..AA Step one instruction from AA..AA(optional) */ - case 'c': /* cAA..AA Continue from address AA..AA(optional) */ - /* try to read optional parameter, pc unchanged if no parm */ - ptr = &remcomInBuffer[1]; - if (hexToInt(&ptr,&addr)) - registers[ PC ] = addr; - - if (remcomInBuffer[0] == 's') /* single-stepping */ - { - if (!prepare_to_step(0)) /* set up for single-step */ - { - /* prepare_to_step has already emulated the target insn: - Send SIGTRAP to gdb, don't resume the target at all. */ - ptr = remcomOutBuffer; - *ptr++ = 'T'; /* Simulate stopping with SIGTRAP */ - *ptr++ = '0'; - *ptr++ = '5'; - - *ptr++ = hexchars[PC >> 4]; /* send PC */ - *ptr++ = hexchars[PC & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[PC], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[R13 >> 4]; /* send FP */ - *ptr++ = hexchars[R13 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R13], ptr, 4, 0); - *ptr++ = ';'; - - *ptr++ = hexchars[R15 >> 4]; /* send SP */ - *ptr++ = hexchars[R15 & 0xf]; - *ptr++ = ':'; - ptr = mem2hex((unsigned char *)®isters[R15], ptr, 4, 0); - *ptr++ = ';'; - *ptr++ = 0; - - break; - } - } - else /* continuing, not single-stepping */ - { - /* OK, about to do a "continue". First check to see if the - target pc is on an odd boundary (second instruction in the - word). If so, we must do a single-step first, because - ya can't jump or return back to an odd boundary! */ - if ((registers[PC] & 2) != 0) - prepare_to_step(1); - } - return; - - case 'D': /* Detach */ - /* I am interpreting this to mean, release the board from control - by the remote stub. To do this, I am restoring the original - (or at least previous) exception vectors. - */ - for (i = 0; i < 18; i++) - exceptionHandler (i, save_vectors[i]); - putpacket ("OK"); - return; /* continue the inferior */ - - case 'k': /* kill the program */ - continue; - } /* switch */ - - /* reply to the request */ - putpacket(remcomOutBuffer); - } -} - -static int -hex(ch) - unsigned char ch; -{ - if ((ch >= 'a') && (ch <= 'f')) return (ch-'a'+10); - if ((ch >= '0') && (ch <= '9')) return (ch-'0'); - if ((ch >= 'A') && (ch <= 'F')) return (ch-'A'+10); - return (-1); -} - -/* scan for the sequence $<data>#<checksum> */ - -static void -getpacket(buffer) - unsigned char * buffer; -{ - unsigned char checksum; - unsigned char xmitcsum; - int i; - int count; - unsigned char ch; - - do { - /* wait around for the start character, ignore all other characters */ - while ((ch = getDebugChar()) != '$'); - checksum = 0; - xmitcsum = -1; - - count = 0; - - /* now, read until a # or end of buffer is found */ - while (count < BUFMAX) { - ch = getDebugChar(); - - if (ch == '#' && (count == 0 || buffer[count-1] != 0x7d)) - break; - - checksum = checksum + ch; - buffer[count] = ch; - count = count + 1; - } - buffer[count] = 0; - - if (ch == '#') { - xmitcsum = hex(getDebugChar()) << 4; - xmitcsum += hex(getDebugChar()); - if (checksum != xmitcsum) { - if (remote_debug) { - unsigned char buf[16]; - - mem2hex((unsigned char *) &checksum, buf, 4, 0); - gdb_error("Bad checksum: my count = %s, ", buf); - mem2hex((unsigned char *) &xmitcsum, buf, 4, 0); - gdb_error("sent count = %s\n", buf); - gdb_error(" -- Bad buffer: \"%s\"\n", buffer); - } - - putDebugChar('-'); /* failed checksum */ - } else { - putDebugChar('+'); /* successful transfer */ - /* if a sequence char is present, reply the sequence ID */ - if (buffer[2] == ':') { - putDebugChar( buffer[0] ); - putDebugChar( buffer[1] ); - /* remove sequence chars from buffer */ - count = strlen(buffer); - for (i=3; i <= count; i++) buffer[i-3] = buffer[i]; - } - } - } - } while (checksum != xmitcsum); -} - -/* send the packet in buffer. */ - -static void -putpacket(buffer) - unsigned char *buffer; -{ - unsigned char checksum; - int count; - char ch; - - /* $<packet info>#<checksum>. */ - do { - putDebugChar('$'); - checksum = 0; - count = 0; - - while (ch=buffer[count]) { - putDebugChar(ch); - checksum += ch; - count += 1; - } - putDebugChar('#'); - putDebugChar(hexchars[checksum >> 4]); - putDebugChar(hexchars[checksum % 16]); - } while (getDebugChar() != '+'); -} - -/* Address of a routine to RTE to if we get a memory fault. */ - -static void (*volatile mem_fault_routine)() = 0; - -static void -set_mem_err () -{ - mem_err = 1; -} - -/* Check the address for safe access ranges. As currently defined, - this routine will reject the "expansion bus" address range(s). - To make those ranges useable, someone must implement code to detect - whether there's anything connected to the expansion bus. */ - -static int -mem_safe (addr) - unsigned char *addr; -{ -#define BAD_RANGE_ONE_START ((unsigned char *) 0x600000) -#define BAD_RANGE_ONE_END ((unsigned char *) 0xa00000) -#define BAD_RANGE_TWO_START ((unsigned char *) 0xff680000) -#define BAD_RANGE_TWO_END ((unsigned char *) 0xff800000) - - if (addr < BAD_RANGE_ONE_START) return 1; /* safe */ - if (addr < BAD_RANGE_ONE_END) return 0; /* unsafe */ - if (addr < BAD_RANGE_TWO_START) return 1; /* safe */ - if (addr < BAD_RANGE_TWO_END) return 0; /* unsafe */ -} - -/* These are separate functions so that they are so short and sweet - that the compiler won't save any registers (if there is a fault - to mem_fault, they won't get restored, so there better not be any - saved). */ -static int -get_char (addr) - unsigned char *addr; -{ -#if 1 - if (mem_fault_routine && !mem_safe(addr)) - { - mem_fault_routine (); - return 0; - } -#endif - return *addr; -} - -static void -set_char (addr, val) - unsigned char *addr; - unsigned char val; -{ -#if 1 - if (mem_fault_routine && !mem_safe (addr)) - { - mem_fault_routine (); - return; - } -#endif - *addr = val; -} - -/* Convert the memory pointed to by mem into hex, placing result in buf. - Return a pointer to the last char put in buf (null). - If MAY_FAULT is non-zero, then we should set mem_err in response to - a fault; if zero treat a fault like any other fault in the stub. */ - -static unsigned char * -mem2hex(mem, buf, count, may_fault) - unsigned char* mem; - unsigned char* buf; - int count; - int may_fault; -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i<count;i++) { - ch = get_char (mem++); - if (may_fault && mem_err) - return (buf); - *buf++ = hexchars[ch >> 4]; - *buf++ = hexchars[ch % 16]; - } - *buf = 0; - if (may_fault) - mem_fault_routine = 0; - return(buf); -} - -/* Convert the hex array pointed to by buf into binary to be placed in mem. - Return a pointer to the character AFTER the last byte written. */ - -static unsigned char* -hex2mem(buf, mem, count, may_fault) - unsigned char* buf; - unsigned char* mem; - int count; - int may_fault; -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i=0;i<count;i++) { - ch = hex(*buf++) << 4; - ch = ch + hex(*buf++); - set_char (mem++, ch); - if (may_fault && mem_err) - return (mem); - } - if (may_fault) - mem_fault_routine = 0; - return(mem); -} - -/* Convert the binary stream in BUF to memory. - - Gdb will escape $, #, and the escape char (0x7d). - COUNT is the total number of bytes to write into - memory. */ -static unsigned char * -bin2mem (buf, mem, count, may_fault) - unsigned char *buf; - unsigned char *mem; - int count; - int may_fault; -{ - int i; - unsigned char ch; - - if (may_fault) - mem_fault_routine = set_mem_err; - for (i = 0; i < count; i++) - { - /* Check for any escaped characters. Be paranoid and - only unescape chars that should be escaped. */ - if (*buf == 0x7d) - { - switch (*(buf+1)) - { - case 0x3: /* # */ - case 0x4: /* $ */ - case 0x5d: /* escape char */ - buf++; - *buf += 0x20; - break; - default: - /* nothing */ - break; - } - } - - set_char (mem++, *buf++); - - if (may_fault && mem_err) - return mem; - } - - if (may_fault) - mem_fault_routine = 0; - return mem; -} - -/* this function takes the m32r exception vector and attempts to - translate this number into a unix compatible signal value */ - -static int -computeSignal(exceptionVector) - int exceptionVector; -{ - int sigval; - switch (exceptionVector) { - case 0 : sigval = 23; break; /* I/O trap */ - case 1 : sigval = 5; break; /* breakpoint */ - case 2 : sigval = 5; break; /* breakpoint */ - case 3 : sigval = 5; break; /* breakpoint */ - case 4 : sigval = 5; break; /* breakpoint */ - case 5 : sigval = 5; break; /* breakpoint */ - case 6 : sigval = 5; break; /* breakpoint */ - case 7 : sigval = 5; break; /* breakpoint */ - case 8 : sigval = 5; break; /* breakpoint */ - case 9 : sigval = 5; break; /* breakpoint */ - case 10 : sigval = 5; break; /* breakpoint */ - case 11 : sigval = 5; break; /* breakpoint */ - case 12 : sigval = 5; break; /* breakpoint */ - case 13 : sigval = 5; break; /* breakpoint */ - case 14 : sigval = 5; break; /* breakpoint */ - case 15 : sigval = 5; break; /* breakpoint */ - case 16 : sigval = 10; break; /* BUS ERROR (alignment) */ - case 17 : sigval = 2; break; /* INTerrupt */ - default : sigval = 7; break; /* "software generated" */ - } - return (sigval); -} - -/**********************************************/ -/* WHILE WE FIND NICE HEX CHARS, BUILD AN INT */ -/* RETURN NUMBER OF CHARS PROCESSED */ -/**********************************************/ -static int -hexToInt(ptr, intValue) - unsigned char **ptr; - int *intValue; -{ - int numChars = 0; - int hexValue; - - *intValue = 0; - while (**ptr) - { - hexValue = hex(**ptr); - if (hexValue >=0) - { - *intValue = (*intValue <<4) | hexValue; - numChars ++; - } - else - break; - (*ptr)++; - } - return (numChars); -} - -/* - Table of branch instructions: - - 10B6 RTE return from trap or exception - 1FCr JMP jump - 1ECr JL jump and link - 7Fxx BRA branch - FFxxxxxx BRA branch (long) - B09rxxxx BNEZ branch not-equal-zero - Br1rxxxx BNE branch not-equal - 7Dxx BNC branch not-condition - FDxxxxxx BNC branch not-condition (long) - B0Arxxxx BLTZ branch less-than-zero - B0Crxxxx BLEZ branch less-equal-zero - 7Exx BL branch and link - FExxxxxx BL branch and link (long) - B0Drxxxx BGTZ branch greater-than-zero - B0Brxxxx BGEZ branch greater-equal-zero - B08rxxxx BEQZ branch equal-zero - Br0rxxxx BEQ branch equal - 7Cxx BC branch condition - FCxxxxxx BC branch condition (long) - */ - -static int -isShortBranch(instr) - unsigned char *instr; -{ - unsigned char instr0 = instr[0] & 0x7F; /* mask off high bit */ - - if (instr0 == 0x10 && instr[1] == 0xB6) /* RTE */ - return 1; /* return from trap or exception */ - - if (instr0 == 0x1E || instr0 == 0x1F) /* JL or JMP */ - if ((instr[1] & 0xF0) == 0xC0) - return 2; /* jump thru a register */ - - if (instr0 == 0x7C || instr0 == 0x7D || /* BC, BNC, BL, BRA */ - instr0 == 0x7E || instr0 == 0x7F) - return 3; /* eight bit PC offset */ - - return 0; -} - -static int -isLongBranch(instr) - unsigned char *instr; -{ - if (instr[0] == 0xFC || instr[0] == 0xFD || /* BRA, BNC, BL, BC */ - instr[0] == 0xFE || instr[0] == 0xFF) /* 24 bit relative */ - return 4; - if ((instr[0] & 0xF0) == 0xB0) /* 16 bit relative */ - { - if ((instr[1] & 0xF0) == 0x00 || /* BNE, BEQ */ - (instr[1] & 0xF0) == 0x10) - return 5; - if (instr[0] == 0xB0) /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ, BEQZ */ - if ((instr[1] & 0xF0) == 0x80 || (instr[1] & 0xF0) == 0x90 || - (instr[1] & 0xF0) == 0xA0 || (instr[1] & 0xF0) == 0xB0 || - (instr[1] & 0xF0) == 0xC0 || (instr[1] & 0xF0) == 0xD0) - return 6; - } - return 0; -} - -/* if address is NOT on a 4-byte boundary, or high-bit of instr is zero, - then it's a 2-byte instruction, else it's a 4-byte instruction. */ - -#define INSTRUCTION_SIZE(addr) \ - ((((int) addr & 2) || (((unsigned char *) addr)[0] & 0x80) == 0) ? 2 : 4) - -static int -isBranch(instr) - unsigned char *instr; -{ - if (INSTRUCTION_SIZE(instr) == 2) - return isShortBranch(instr); - else - return isLongBranch(instr); -} - -static int -willBranch(instr, branchCode) - unsigned char *instr; -{ - switch (branchCode) - { - case 0: return 0; /* not a branch */ - case 1: return 1; /* RTE */ - case 2: return 1; /* JL or JMP */ - case 3: /* BC, BNC, BL, BRA (short) */ - case 4: /* BC, BNC, BL, BRA (long) */ - switch (instr[0] & 0x0F) - { - case 0xC: /* Branch if Condition Register */ - return (registers[CBR] != 0); - case 0xD: /* Branch if NOT Condition Register */ - return (registers[CBR] == 0); - case 0xE: /* Branch and Link */ - case 0xF: /* Branch (unconditional) */ - return 1; - default: /* oops? */ - return 0; - } - case 5: /* BNE, BEQ */ - switch (instr[1] & 0xF0) - { - case 0x00: /* Branch if r1 equal to r2 */ - return (registers[instr[0] & 0x0F] == registers[instr[1] & 0x0F]); - case 0x10: /* Branch if r1 NOT equal to r2 */ - return (registers[instr[0] & 0x0F] != registers[instr[1] & 0x0F]); - default: /* oops? */ - return 0; - } - case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ */ - switch (instr[1] & 0xF0) - { - case 0x80: /* Branch if reg equal to zero */ - return (registers[instr[1] & 0x0F] == 0); - case 0x90: /* Branch if reg NOT equal to zero */ - return (registers[instr[1] & 0x0F] != 0); - case 0xA0: /* Branch if reg less than zero */ - return (registers[instr[1] & 0x0F] < 0); - case 0xB0: /* Branch if reg greater or equal to zero */ - return (registers[instr[1] & 0x0F] >= 0); - case 0xC0: /* Branch if reg less than or equal to zero */ - return (registers[instr[1] & 0x0F] <= 0); - case 0xD0: /* Branch if reg greater than zero */ - return (registers[instr[1] & 0x0F] > 0); - default: /* oops? */ - return 0; - } - default: /* oops? */ - return 0; - } -} - -static int -branchDestination(instr, branchCode) - unsigned char *instr; -{ - switch (branchCode) { - default: - case 0: /* not a branch */ - return 0; - case 1: /* RTE */ - return registers[BPC] & ~3; /* pop BPC into PC */ - case 2: /* JL or JMP */ - return registers[instr[1] & 0x0F] & ~3; /* jump thru a register */ - case 3: /* BC, BNC, BL, BRA (short, 8-bit relative offset) */ - return (((int) instr) & ~3) + ((unsigned char) instr[1] << 2); - case 4: /* BC, BNC, BL, BRA (long, 24-bit relative offset) */ - return ((int) instr + - ((((unsigned char) instr[1] << 16) | (instr[2] << 8) | (instr[3])) << 2)); - case 5: /* BNE, BEQ (16-bit relative offset) */ - case 6: /* BNEZ, BLTZ, BLEZ, BGTZ, BGEZ ,BEQZ (ditto) */ - return ((int) instr + ((((unsigned char) instr[2] << 8) | (instr[3])) << 2)); - } - - /* An explanatory note: in the last three return expressions, I have - cast the most-significant byte of the return offset to char. - What this accomplishes is sign extension. If the other - less-significant bytes were signed as well, they would get sign - extended too and, if negative, their leading bits would clobber - the bits of the more-significant bytes ahead of them. There are - other ways I could have done this, but sign extension from - odd-sized integers is always a pain. */ -} - -static void -branchSideEffects(instr, branchCode) - unsigned char *instr; - int branchCode; -{ - switch (branchCode) - { - case 1: /* RTE */ - return; /* I <THINK> this is already handled... */ - case 2: /* JL (or JMP) */ - case 3: /* BL (or BC, BNC, BRA) */ - case 4: - if ((instr[0] & 0x0F) == 0x0E) /* branch/jump and link */ - registers[R14] = (registers[PC] & ~3) + 4; - return; - default: /* any other branch has no side effects */ - return; - } -} - -static struct STEPPING_CONTEXT { - int stepping; /* true when we've started a single-step */ - unsigned long target_addr; /* the instr we're trying to execute */ - unsigned long target_size; /* the size of the target instr */ - unsigned long noop_addr; /* where we've inserted a no-op, if any */ - unsigned long trap1_addr; /* the trap following the target instr */ - unsigned long trap2_addr; /* the trap at a branch destination, if any */ - unsigned short noop_save; /* instruction overwritten by our no-op */ - unsigned short trap1_save; /* instruction overwritten by trap1 */ - unsigned short trap2_save; /* instruction overwritten by trap2 */ - unsigned short continue_p; /* true if NOT returning to gdb after step */ -} stepping; - -/* Function: prepare_to_step - Called from handle_exception to prepare the user program to single-step. - Places a trap instruction after the target instruction, with special - extra handling for branch instructions and for instructions in the - second half-word of a word. - - Returns: True if we should actually execute the instruction; - False if we are going to emulate executing the instruction, - in which case we simply report to GDB that the instruction - has already been executed. */ - -#define TRAP1 0x10f1; /* trap #1 instruction */ -#define NOOP 0x7000; /* noop instruction */ - -static unsigned short trap1 = TRAP1; -static unsigned short noop = NOOP; - -static int -prepare_to_step(continue_p) - int continue_p; /* if this isn't REALLY a single-step (see below) */ -{ - unsigned long pc = registers[PC]; - int branchCode = isBranch((unsigned char *) pc); - unsigned char *p; - - /* zero out the stepping context - (paranoia -- it should already be zeroed) */ - for (p = (unsigned char *) &stepping; - p < ((unsigned char *) &stepping) + sizeof(stepping); - p++) - *p = 0; - - if (branchCode != 0) /* next instruction is a branch */ - { - branchSideEffects((unsigned char *) pc, branchCode); - if (willBranch((unsigned char *)pc, branchCode)) - registers[PC] = branchDestination((unsigned char *) pc, branchCode); - else - registers[PC] = pc + INSTRUCTION_SIZE(pc); - return 0; /* branch "executed" -- just notify GDB */ - } - else if (((int) pc & 2) != 0) /* "second-slot" instruction */ - { - /* insert no-op before pc */ - stepping.noop_addr = pc - 2; - stepping.noop_save = *(unsigned short *) stepping.noop_addr; - *(unsigned short *) stepping.noop_addr = noop; - /* insert trap after pc */ - stepping.trap1_addr = pc + 2; - stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; - *(unsigned short *) stepping.trap1_addr = trap1; - } - else /* "first-slot" instruction */ - { - /* insert trap after pc */ - stepping.trap1_addr = pc + INSTRUCTION_SIZE(pc); - stepping.trap1_save = *(unsigned short *) stepping.trap1_addr; - *(unsigned short *) stepping.trap1_addr = trap1; - } - /* "continue_p" means that we are actually doing a continue, and not - being requested to single-step by GDB. Sometimes we have to do - one single-step before continuing, because the PC is on a half-word - boundary. There's no way to simply resume at such an address. */ - stepping.continue_p = continue_p; - stepping.stepping = 1; /* starting a single-step */ - return 1; -} - -/* Function: finish_from_step - Called from handle_exception to finish up when the user program - returns from a single-step. Replaces the instructions that had - been overwritten by traps or no-ops, - - Returns: True if we should notify GDB that the target stopped. - False if we only single-stepped because we had to before we - could continue (ie. we were trying to continue at a - half-word boundary). In that case don't notify GDB: - just "continue continuing". */ - -static int -finish_from_step() -{ - if (stepping.stepping) /* anything to do? */ - { - int continue_p = stepping.continue_p; - unsigned char *p; - - if (stepping.noop_addr) /* replace instr "under" our no-op */ - *(unsigned short *) stepping.noop_addr = stepping.noop_save; - if (stepping.trap1_addr) /* replace instr "under" our trap */ - *(unsigned short *) stepping.trap1_addr = stepping.trap1_save; - if (stepping.trap2_addr) /* ditto our other trap, if any */ - *(unsigned short *) stepping.trap2_addr = stepping.trap2_save; - - for (p = (unsigned char *) &stepping; /* zero out the stepping context */ - p < ((unsigned char *) &stepping) + sizeof(stepping); - p++) - *p = 0; - - return !(continue_p); - } - else /* we didn't single-step, therefore this must be a legitimate stop */ - return 1; -} - -struct PSWreg { /* separate out the bit flags in the PSW register */ - int pad1 : 16; - int bsm : 1; - int bie : 1; - int pad2 : 5; - int bc : 1; - int sm : 1; - int ie : 1; - int pad3 : 5; - int c : 1; -} *psw; - -/* Upon entry the value for LR to save has been pushed. - We unpush that so that the value for the stack pointer saved is correct. - Upon entry, all other registers are assumed to have not been modified - since the interrupt/trap occured. */ - -asm (" -stash_registers: - push r0 - push r1 - seth r1, #shigh(registers) - add3 r1, r1, #low(registers) - pop r0 ; r1 - st r0, @(4,r1) - pop r0 ; r0 - st r0, @r1 - addi r1, #4 ; only add 4 as subsequent saves are `pre inc' - st r2, @+r1 - st r3, @+r1 - st r4, @+r1 - st r5, @+r1 - st r6, @+r1 - st r7, @+r1 - st r8, @+r1 - st r9, @+r1 - st r10, @+r1 - st r11, @+r1 - st r12, @+r1 - st r13, @+r1 ; fp - pop r0 ; lr (r14) - st r0, @+r1 - st sp, @+r1 ; sp contains right value at this point - mvfc r0, cr0 - st r0, @+r1 ; cr0 == PSW - mvfc r0, cr1 - st r0, @+r1 ; cr1 == CBR - mvfc r0, cr2 - st r0, @+r1 ; cr2 == SPI - mvfc r0, cr3 - st r0, @+r1 ; cr3 == SPU - mvfc r0, cr6 - st r0, @+r1 ; cr6 == BPC - st r0, @+r1 ; PC == BPC - mvfaclo r0 - st r0, @+r1 ; ACCL - mvfachi r0 - st r0, @+r1 ; ACCH - jmp lr"); - -/* C routine to clean up what stash_registers did. - It is called after calling stash_registers. - This is separate from stash_registers as we want to do this in C - but doing stash_registers in C isn't straightforward. */ - -static void -cleanup_stash () -{ - psw = (struct PSWreg *) ®isters[PSW]; /* fields of PSW register */ - psw->sm = psw->bsm; /* fix up pre-trap values of psw fields */ - psw->ie = psw->bie; - psw->c = psw->bc; - registers[CBR] = psw->bc; /* fix up pre-trap "C" register */ - -#if 0 /* FIXME: Was in previous version. Necessary? - (Remember that we use the "rte" insn to return from the - trap/interrupt so the values of bsm, bie, bc are important. */ - psw->bsm = psw->bie = psw->bc = 0; /* zero post-trap values */ -#endif - - /* FIXME: Copied from previous version. This can probably be deleted - since methinks stash_registers has already done this. */ - registers[PC] = registers[BPC]; /* pre-trap PC */ - - /* FIXME: Copied from previous version. Necessary? */ - if (psw->sm) /* copy R15 into (psw->sm ? SPU : SPI) */ - registers[SPU] = registers[R15]; - else - registers[SPI] = registers[R15]; -} - -asm (" -restore_and_return: - seth r0, #shigh(registers+8) - add3 r0, r0, #low(registers+8) - ld r2, @r0+ ; restore r2 - ld r3, @r0+ ; restore r3 - ld r4, @r0+ ; restore r4 - ld r5, @r0+ ; restore r5 - ld r6, @r0+ ; restore r6 - ld r7, @r0+ ; restore r7 - ld r8, @r0+ ; restore r8 - ld r9, @r0+ ; restore r9 - ld r10, @r0+ ; restore r10 - ld r11, @r0+ ; restore r11 - ld r12, @r0+ ; restore r12 - ld r13, @r0+ ; restore r13 - ld r14, @r0+ ; restore r14 - ld r15, @r0+ ; restore r15 - ld r1, @r0+ ; restore cr0 == PSW - mvtc r1, cr0 - ld r1, @r0+ ; restore cr1 == CBR (no-op, because it's read only) - mvtc r1, cr1 - ld r1, @r0+ ; restore cr2 == SPI - mvtc r1, cr2 - ld r1, @r0+ ; restore cr3 == SPU - mvtc r1, cr3 - addi r0, #4 ; skip BPC - ld r1, @r0+ ; restore cr6 (BPC) == PC - mvtc r1, cr6 - ld r1, @r0+ ; restore ACCL - mvtaclo r1 - ld r1, @r0+ ; restore ACCH - mvtachi r1 - seth r0, #shigh(registers) - add3 r0, r0, #low(registers) - ld r1, @(4,r0) ; restore r1 - ld r0, @r0 ; restore r0 - rte"); - -/* General trap handler, called after the registers have been stashed. - NUM is the trap/exception number. */ - -static void -process_exception (num) - int num; -{ - cleanup_stash (); - asm volatile (" - seth r1, #shigh(stackPtr) - add3 r1, r1, #low(stackPtr) - ld r15, @r1 ; setup local stack (protect user stack) - mv r0, %0 - bl handle_exception - bl restore_and_return" - : : "r" (num) : "r0", "r1"); -} - -void _catchException0 (); - -asm (" -_catchException0: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #0 - bl process_exception"); - -void _catchException1 (); - -asm (" -_catchException1: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - bl cleanup_stash - seth r1, #shigh(stackPtr) - add3 r1, r1, #low(stackPtr) - ld r15, @r1 ; setup local stack (protect user stack) - seth r1, #shigh(registers + 21*4) ; PC - add3 r1, r1, #low(registers + 21*4) - ld r0, @r1 - addi r0, #-4 ; back up PC for breakpoint trap. - st r0, @r1 ; FIXME: what about bp in right slot? - ldi r0, #1 - bl handle_exception - bl restore_and_return"); - -void _catchException2 (); - -asm (" -_catchException2: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #2 - bl process_exception"); - -void _catchException3 (); - -asm (" -_catchException3: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #3 - bl process_exception"); - -void _catchException4 (); - -asm (" -_catchException4: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #4 - bl process_exception"); - -void _catchException5 (); - -asm (" -_catchException5: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #5 - bl process_exception"); - -void _catchException6 (); - -asm (" -_catchException6: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #6 - bl process_exception"); - -void _catchException7 (); - -asm (" -_catchException7: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #7 - bl process_exception"); - -void _catchException8 (); - -asm (" -_catchException8: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #8 - bl process_exception"); - -void _catchException9 (); - -asm (" -_catchException9: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #9 - bl process_exception"); - -void _catchException10 (); - -asm (" -_catchException10: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #10 - bl process_exception"); - -void _catchException11 (); - -asm (" -_catchException11: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #11 - bl process_exception"); - -void _catchException12 (); - -asm (" -_catchException12: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #12 - bl process_exception"); - -void _catchException13 (); - -asm (" -_catchException13: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #13 - bl process_exception"); - -void _catchException14 (); - -asm (" -_catchException14: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #14 - bl process_exception"); - -void _catchException15 (); - -asm (" -_catchException15: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #15 - bl process_exception"); - -void _catchException16 (); - -asm (" -_catchException16: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #16 - bl process_exception"); - -void _catchException17 (); - -asm (" -_catchException17: - push lr - bl stash_registers - ; Note that at this point the pushed value of `lr' has been popped - ldi r0, #17 - bl process_exception"); - - -/* this function is used to set up exception handlers for tracing and - breakpoints */ -void -set_debug_traps() -{ - /* extern void remcomHandler(); */ - int i; - - for (i = 0; i < 18; i++) /* keep a copy of old vectors */ - if (save_vectors[i] == 0) /* only copy them the first time */ - save_vectors[i] = getExceptionHandler (i); - - stackPtr = &remcomStack[STACKSIZE/sizeof(int) - 1]; - - exceptionHandler (0, _catchException0); - exceptionHandler (1, _catchException1); - exceptionHandler (2, _catchException2); - exceptionHandler (3, _catchException3); - exceptionHandler (4, _catchException4); - exceptionHandler (5, _catchException5); - exceptionHandler (6, _catchException6); - exceptionHandler (7, _catchException7); - exceptionHandler (8, _catchException8); - exceptionHandler (9, _catchException9); - exceptionHandler (10, _catchException10); - exceptionHandler (11, _catchException11); - exceptionHandler (12, _catchException12); - exceptionHandler (13, _catchException13); - exceptionHandler (14, _catchException14); - exceptionHandler (15, _catchException15); - exceptionHandler (16, _catchException16); - /* exceptionHandler (17, _catchException17); */ - - /* In case GDB is started before us, ack any packets (presumably - "$?#xx") sitting there. */ - putDebugChar ('+'); - - initialized = 1; -} - -/* This function will generate a breakpoint exception. It is used at the - beginning of a program to sync up with a debugger and can be used - otherwise as a quick means to stop program execution and "break" into - the debugger. */ - -#define BREAKPOINT() asm volatile (" trap #2"); - -void -breakpoint() -{ - if (initialized) - BREAKPOINT(); -} - -/* STDOUT section: - Stuff pertaining to simulating stdout by sending chars to gdb to be echoed. - Functions: gdb_putchar(char ch) - gdb_puts(char *str) - gdb_write(char *str, int len) - gdb_error(char *format, char *parm) - */ - -/* Function: gdb_putchar(int) - Make gdb write a char to stdout. - Returns: the char */ - -static int -gdb_putchar(ch) - int ch; -{ - char buf[4]; - - buf[0] = 'O'; - buf[1] = hexchars[ch >> 4]; - buf[2] = hexchars[ch & 0x0F]; - buf[3] = 0; - putpacket(buf); - return ch; -} - -/* Function: gdb_write(char *, int) - Make gdb write n bytes to stdout (not assumed to be null-terminated). - Returns: number of bytes written */ - -static int -gdb_write(data, len) - char *data; - int len; -{ - char *buf, *cpy; - int i; - - buf = remcomOutBuffer; - buf[0] = 'O'; - i = 0; - while (i < len) - { - for (cpy = buf+1; - i < len && cpy < buf + sizeof(remcomOutBuffer) - 3; - i++) - { - *cpy++ = hexchars[data[i] >> 4]; - *cpy++ = hexchars[data[i] & 0x0F]; - } - *cpy = 0; - putpacket(buf); - } - return len; -} - -/* Function: gdb_puts(char *) - Make gdb write a null-terminated string to stdout. - Returns: the length of the string */ - -static int -gdb_puts(str) - char *str; -{ - return gdb_write(str, strlen(str)); -} - -/* Function: gdb_error(char *, char *) - Send an error message to gdb's stdout. - First string may have 1 (one) optional "%s" in it, which - will cause the optional second string to be inserted. */ - -static void -gdb_error(format, parm) - char * format; - char * parm; -{ - char buf[400], *cpy; - int len; - - if (remote_debug) - { - if (format && *format) - len = strlen(format); - else - return; /* empty input */ - - if (parm && *parm) - len += strlen(parm); - - for (cpy = buf; *format; ) - { - if (format[0] == '%' && format[1] == 's') /* include second string */ - { - format += 2; /* advance two chars instead of just one */ - while (parm && *parm) - *cpy++ = *parm++; - } - else - *cpy++ = *format++; - } - *cpy = '\0'; - gdb_puts(buf); - } -} - -static unsigned char * -strcpy (unsigned char *dest, const unsigned char *src) -{ - unsigned char *ret = dest; - - if (dest && src) - { - while (*src) - *dest++ = *src++; - *dest = 0; - } - return ret; -} - -static int -strlen (const unsigned char *src) -{ - int ret; - - for (ret = 0; *src; src++) - ret++; - - return ret; -} - -#if 0 -void exit (code) - int code; -{ - _exit (code); -} - -int atexit (void *p) -{ - return 0; -} - -void abort (void) -{ - _exit (1); -} -#endif diff --git a/contrib/gdb/gdb/m32r-tdep.c b/contrib/gdb/gdb/m32r-tdep.c deleted file mode 100644 index acd34fa..0000000 --- a/contrib/gdb/gdb/m32r-tdep.c +++ /dev/null @@ -1,745 +0,0 @@ -/* Target-dependent code for the Mitsubishi m32r for GDB, the GNU debugger. - Copyright 1996, 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 "obstack.h" -#include "target.h" -#include "value.h" -#include "bfd.h" -#include "gdb_string.h" -#include "gdbcore.h" -#include "symfile.h" - -/* Function: m32r_use_struct_convention - Return nonzero if call_function should allocate stack space for a - struct return? */ -int -m32r_use_struct_convention (gcc_p, type) - int gcc_p; - struct type *type; -{ - return (TYPE_LENGTH (type) > 8); -} - -/* Function: frame_find_saved_regs - Return the frame_saved_regs structure for the frame. - Doesn't really work for dummy frames, but it does pass back - an empty frame_saved_regs, so I guess that's better than total failure */ - -void -m32r_frame_find_saved_regs (fi, regaddr) - struct frame_info *fi; - struct frame_saved_regs *regaddr; -{ - memcpy(regaddr, &fi->fsr, sizeof(struct frame_saved_regs)); -} - -/* Turn this on if you want to see just how much instruction decoding - if being done, its quite a lot - */ -#if 0 -static void dump_insn(char * commnt,CORE_ADDR pc, int insn) -{ - printf_filtered(" %s %08x %08x ", - commnt,(unsigned int)pc,(unsigned int) insn); - (*tm_print_insn)(pc,&tm_print_insn_info); - printf_filtered("\n"); -} -#define insn_debug(args) { printf_filtered args; } -#else -#define dump_insn(a,b,c) {} -#define insn_debug(args) {} -#endif - -#define DEFAULT_SEARCH_LIMIT 44 - -/* Function: scan_prologue - This function decodes the target function prologue to determine - 1) the size of the stack frame, and 2) which registers are saved on it. - It saves the offsets of saved regs in the frame_saved_regs argument, - and returns the frame size. */ - -/* - The sequence it currently generates is: - - if (varargs function) { ddi sp,#n } - push registers - if (additional stack <= 256) { addi sp,#-stack } - else if (additional stack < 65k) { add3 sp,sp,#-stack - - } else if (additional stack) { - seth sp,#(stack & 0xffff0000) - or3 sp,sp,#(stack & 0x0000ffff) - sub sp,r4 - } - if (frame pointer) { - mv sp,fp - } - -These instructions are scheduled like everything else, so you should stop at -the first branch instruction. - -*/ - -/* This is required by skip prologue and by m32r_init_extra_frame_info. - The results of decoding a prologue should be cached because this - thrashing is getting nuts. - I am thinking of making a container class with two indexes, name and - address. It may be better to extend the symbol table. - */ - -static void decode_prologue (start_pc, scan_limit, - pl_endptr, framelength, - fi, fsr) - CORE_ADDR start_pc; - CORE_ADDR scan_limit; - CORE_ADDR * pl_endptr; /* var parameter */ - unsigned long * framelength; - struct frame_info * fi; - struct frame_saved_regs * fsr; -{ - unsigned long framesize; - int insn; - int op1; - int maybe_one_more = 0; - CORE_ADDR after_prologue = 0; - CORE_ADDR after_stack_adjust = 0; - CORE_ADDR current_pc; - - - framesize = 0; - after_prologue = 0; - insn_debug(("rd prolog l(%d)\n",scan_limit - current_pc)); - - for (current_pc = start_pc; current_pc < scan_limit; current_pc += 2) - { - - insn = read_memory_unsigned_integer (current_pc, 2); - dump_insn("insn-1",current_pc,insn); /* MTZ */ - - /* If this is a 32 bit instruction, we dont want to examine its - immediate data as though it were an instruction */ - if (current_pc & 0x02) - { /* Clear the parallel execution bit from 16 bit instruction */ - if (maybe_one_more) - { /* The last instruction was a branch, usually terminates - the series, but if this is a parallel instruction, - it may be a stack framing instruction */ - if (! (insn & 0x8000)) - { insn_debug(("Really done")); - break; /* nope, we are really done */ - } - } - insn &= 0x7fff; /* decode this instruction further */ - } - else - { - if (maybe_one_more) - break; /* This isnt the one more */ - if (insn & 0x8000) - { - insn_debug(("32 bit insn\n")); - if (current_pc == scan_limit) - scan_limit += 2; /* extend the search */ - current_pc += 2; /* skip the immediate data */ - if (insn == 0x8faf) /* add3 sp, sp, xxxx */ - /* add 16 bit sign-extended offset */ - { insn_debug(("stack increment\n")); - framesize += -((short) read_memory_unsigned_integer (current_pc, 2)); - } - else - { - if (((insn >> 8) == 0xe4) && /* ld24 r4, xxxxxx; sub sp, r4 */ - read_memory_unsigned_integer (current_pc + 2, 2) == 0x0f24) - { /* subtract 24 bit sign-extended negative-offset */ - dump_insn("insn-2",current_pc+2,insn); - insn = read_memory_unsigned_integer (current_pc - 2, 4); - dump_insn("insn-3(l4)",current_pc -2,insn); - if (insn & 0x00800000) /* sign extend */ - insn |= 0xff000000; /* negative */ - else - insn &= 0x00ffffff; /* positive */ - framesize += insn; - } - } - after_prologue = current_pc; - continue; - } - } - op1 = insn & 0xf000; /* isolate just the first nibble */ - - if ((insn & 0xf0ff) == 0x207f) - { /* st reg, @-sp */ - int regno; - insn_debug(("push\n")); -#if 0 /* No, PUSH FP is not an indication that we will use a frame pointer. */ - if (((insn & 0xffff) == 0x2d7f) && fi) - fi->using_frame_pointer = 1; -#endif - framesize += 4; -#if 0 -/* Why should we increase the scan limit, just because we did a push? - And if there is a reason, surely we would only want to do it if we - had already reached the scan limit... */ - if (current_pc == scan_limit) - scan_limit += 2; -#endif - regno = ((insn >> 8) & 0xf); - if (fsr) /* save_regs offset */ - fsr->regs[regno] = framesize; - after_prologue = 0; - continue; - } - if ((insn >> 8) == 0x4f) /* addi sp, xx */ - /* add 8 bit sign-extended offset */ - { - int stack_adjust = (char) (insn & 0xff); - - /* there are probably two of these stack adjustments: - 1) A negative one in the prologue, and - 2) A positive one in the epilogue. - We are only interested in the first one. */ - - if (stack_adjust < 0) - { - framesize -= stack_adjust; - after_prologue = 0; - /* A frameless function may have no "mv fp, sp". - In that case, this is the end of the prologue. */ - after_stack_adjust = current_pc + 2; - } - continue; - } - if (insn == 0x1d8f) { /* mv fp, sp */ - if (fi) - fi->using_frame_pointer = 1; /* fp is now valid */ - insn_debug(("done fp found\n")); - after_prologue = current_pc + 2; - break; /* end of stack adjustments */ - } - if (insn == 0x7000) /* Nop looks like a branch, continue explicitly */ - { insn_debug(("nop\n")); - after_prologue = current_pc + 2; - continue; /* nop occurs between pushes */ - } - /* End of prolog if any of these are branch instructions */ - if ((op1 == 0x7000) - || ( op1 == 0xb000) - || (op1 == 0x7000)) - { - after_prologue = current_pc; - insn_debug(("Done: branch\n")); - maybe_one_more = 1; - continue; - } - /* Some of the branch instructions are mixed with other types */ - if (op1 == 0x1000) - {int subop = insn & 0x0ff0; - if ((subop == 0x0ec0) || (subop == 0x0fc0)) - { insn_debug(("done: jmp\n")); - after_prologue = current_pc; - maybe_one_more = 1; - continue; /* jmp , jl */ - } - } - } - - if (current_pc >= scan_limit) - { - if (pl_endptr) -#if 1 - if (after_stack_adjust != 0) - /* We did not find a "mv fp,sp", but we DID find - a stack_adjust. Is it safe to use that as the - end of the prologue? I just don't know. */ - { - *pl_endptr = after_stack_adjust; - if (framelength) - *framelength = framesize; - } - else -#endif - /* We reached the end of the loop without finding the end - of the prologue. No way to win -- we should report failure. - The way we do that is to return the original start_pc. - GDB will set a breakpoint at the start of the function (etc.) */ - - *pl_endptr = start_pc; - - return; - } - if (after_prologue == 0) - after_prologue = current_pc; - - insn_debug((" framesize %d, firstline %08x\n",framesize,after_prologue)); - if (framelength) - *framelength = framesize; - if (pl_endptr) - *pl_endptr = after_prologue; -} /* decode_prologue */ - -/* Function: skip_prologue - Find end of function prologue */ - -CORE_ADDR -m32r_skip_prologue (pc) - CORE_ADDR pc; -{ - CORE_ADDR func_addr, func_end; - struct symtab_and_line sal; - - /* See what the symbol table says */ - - if (find_pc_partial_function (pc, NULL, &func_addr, &func_end)) - { - sal = find_pc_line (func_addr, 0); - - if (sal.line != 0 && sal.end <= func_end) - { - - insn_debug(("BP after prologue %08x\n",sal.end)); - func_end = 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. */ - { - insn_debug(("No line info, line(%x) sal_end(%x) funcend(%x)\n", - sal.line,sal.end,func_end)); - func_end = min(func_end,func_addr + DEFAULT_SEARCH_LIMIT); - } - } - else - func_end = pc + DEFAULT_SEARCH_LIMIT; - decode_prologue (pc, func_end, &sal.end, 0, 0, 0); - return sal.end; -} - -static unsigned long -m32r_scan_prologue (fi, fsr) - struct frame_info *fi; - struct frame_saved_regs *fsr; -{ - struct symtab_and_line sal; - CORE_ADDR prologue_start, prologue_end, current_pc; - unsigned long framesize; - - /* this code essentially duplicates skip_prologue, - but we need the start address below. */ - - if (find_pc_partial_function (fi->pc, NULL, &prologue_start, &prologue_end)) - { - sal = find_pc_line (prologue_start, 0); - - if (sal.line == 0) /* no line info, use current PC */ - if (prologue_start == entry_point_address ()) - return 0; - } - else - { - prologue_start = fi->pc; - prologue_end = prologue_start + 48; /* We're in the boondocks: - allow for 16 pushes, an add, - and "mv fp,sp" */ - } -#if 0 - prologue_end = min (prologue_end, fi->pc); -#endif - insn_debug(("fipc(%08x) start(%08x) end(%08x)\n", - fi->pc,prologue_start,prologue_end)); - prologue_end = min(prologue_end, prologue_start + DEFAULT_SEARCH_LIMIT); - decode_prologue (prologue_start,prologue_end,&prologue_end,&framesize, - fi,fsr); - return framesize; -} - -/* Function: init_extra_frame_info - This function actually figures out the frame address for a given pc and - sp. This is tricky on the m32r because we sometimes don't use an explicit - frame pointer, and the previous stack pointer isn't necessarily recorded - on the stack. The only reliable way to get this info is to - examine the prologue. */ - -void -m32r_init_extra_frame_info (fi) - struct frame_info *fi; -{ - int reg; - - if (fi->next) - fi->pc = FRAME_SAVED_PC (fi->next); - - memset (fi->fsr.regs, '\000', sizeof fi->fsr.regs); - - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - { - /* We need to setup fi->frame here because run_stack_dummy gets it wrong - by assuming it's always FP. */ - fi->frame = generic_read_register_dummy (fi->pc, fi->frame, SP_REGNUM); - fi->framesize = 0; - return; - } - else - { - fi->using_frame_pointer = 0; - fi->framesize = m32r_scan_prologue (fi, &fi->fsr); - - if (!fi->next) - if (fi->using_frame_pointer) - { - fi->frame = read_register (FP_REGNUM); - } - else - fi->frame = read_register (SP_REGNUM); - else /* fi->next means this is not the innermost frame */ - if (fi->using_frame_pointer) /* we have an FP */ - if (fi->next->fsr.regs[FP_REGNUM] != 0) /* caller saved our FP */ - fi->frame = read_memory_integer (fi->next->fsr.regs[FP_REGNUM], 4); - for (reg = 0; reg < NUM_REGS; reg++) - if (fi->fsr.regs[reg] != 0) - fi->fsr.regs[reg] = fi->frame + fi->framesize - fi->fsr.regs[reg]; - } -} - -/* Function: mn10300_virtual_frame_pointer - Return the register that the function uses for a frame pointer, - plus any necessary offset to be applied to the register before - any frame pointer offsets. */ - -void -m32r_virtual_frame_pointer (pc, reg, offset) - CORE_ADDR pc; - long *reg; - long *offset; -{ - struct frame_info fi; - - /* Set up a dummy frame_info. */ - fi.next = NULL; - fi.prev = NULL; - fi.frame = 0; - fi.pc = pc; - - /* Analyze the prolog and fill in the extra info. */ - m32r_init_extra_frame_info (&fi); - - - /* Results will tell us which type of frame it uses. */ - if (fi.using_frame_pointer) - { - *reg = FP_REGNUM; - *offset = 0; - } - else - { - *reg = SP_REGNUM; - *offset = 0; - } -} - -/* 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. */ - -CORE_ADDR -m32r_find_callers_reg (fi, regnum) - struct frame_info *fi; - int regnum; -{ - for (; fi; fi = fi->next) - if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy (fi->pc, fi->frame, regnum); - else if (fi->fsr.regs[regnum] != 0) - return read_memory_integer (fi->fsr.regs[regnum], - REGISTER_RAW_SIZE(regnum)); - return read_register (regnum); -} - -/* Function: frame_chain - 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 - INIT_EXTRA_FRAME_INFO and INIT_FRAME_PC will be called for the new frame. - For m32r, we save the frame size when we initialize the frame_info. */ - -CORE_ADDR -m32r_frame_chain (fi) - struct frame_info *fi; -{ - CORE_ADDR fn_start, callers_pc, fp; - - /* is this a dummy frame? */ - if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame)) - return fi->frame; /* dummy frame same as caller's frame */ - - /* is caller-of-this a dummy frame? */ - callers_pc = FRAME_SAVED_PC(fi); /* find out who called us: */ - fp = m32r_find_callers_reg (fi, FP_REGNUM); - if (PC_IN_CALL_DUMMY(callers_pc, fp, fp)) - return fp; /* dummy frame's frame may bear no relation to ours */ - - if (find_pc_partial_function (fi->pc, 0, &fn_start, 0)) - if (fn_start == entry_point_address ()) - return 0; /* in _start fn, don't chain further */ - if (fi->framesize == 0) - { - printf_filtered("cannot determine frame size @ %08x , pc(%08x)\n", - (unsigned long) fi->frame, - (unsigned long) fi->pc ); - return 0; - } - insn_debug(("m32rx frame %08x\n",fi->frame+fi->framesize)); - return fi->frame + fi->framesize; -} - -/* Function: push_return_address (pc) - Set up the return address for the inferior function call. - Necessary for targets that don't actually execute a JSR/BSR instruction - (ie. when using an empty CALL_DUMMY) */ - -CORE_ADDR -m32r_push_return_address (pc, sp) - CORE_ADDR pc; - CORE_ADDR sp; -{ - write_register (RP_REGNUM, CALL_DUMMY_ADDRESS ()); - return sp; -} - - -/* Function: pop_frame - Discard from the stack the innermost frame, - restoring all saved registers. */ - -struct frame_info * -m32r_pop_frame (frame) - struct frame_info *frame; -{ - int regnum; - - if (PC_IN_CALL_DUMMY (frame->pc, frame->frame, frame->frame)) - generic_pop_dummy_frame (); - else - { - for (regnum = 0; regnum < NUM_REGS; regnum++) - if (frame->fsr.regs[regnum] != 0) - write_register (regnum, - read_memory_integer (frame->fsr.regs[regnum], 4)); - - write_register (PC_REGNUM, FRAME_SAVED_PC (frame)); - write_register (SP_REGNUM, read_register (FP_REGNUM)); - if (read_register (PSW_REGNUM) & 0x80) - write_register (SPU_REGNUM, read_register (SP_REGNUM)); - else - write_register (SPI_REGNUM, read_register (SP_REGNUM)); - } - flush_cached_frames (); - return NULL; -} - -/* Function: frame_saved_pc - Find the caller of this frame. We do this by seeing if RP_REGNUM is saved - in the stack anywhere, otherwise we get it from the registers. */ - -CORE_ADDR -m32r_frame_saved_pc (fi) - struct frame_info *fi; -{ - if (PC_IN_CALL_DUMMY(fi->pc, fi->frame, fi->frame)) - return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM); - else - return m32r_find_callers_reg (fi, RP_REGNUM); -} - -/* Function: push_arguments - Setup the function arguments for calling a function in the inferior. - - On the Mitsubishi M32R architecture, there are four registers (R0 to R3) - which are dedicated for passing function arguments. Up to the first - four arguments (depending on size) may go into these registers. - The rest go on the stack. - - Arguments that are smaller than 4 bytes will still take up a whole - register or a whole 32-bit word on the stack, and will be - right-justified in the register or the stack word. This includes - chars, shorts, and small aggregate types. - - Arguments of 8 bytes size are split between two registers, if - available. If only one register is available, the argument will - be split between the register and the stack. Otherwise it is - passed entirely on the stack. Aggregate types with sizes between - 4 and 8 bytes are passed entirely on the stack, and are left-justified - within the double-word (as opposed to aggregates smaller than 4 bytes - which are right-justified). - - Aggregates of greater than 8 bytes are first copied onto the stack, - and then a pointer to the copy is passed in the place of the normal - argument (either in a register if available, or on the stack). - - Functions that must return an aggregate type can return it in the - normal return value registers (R0 and R1) if its size is 8 bytes or - less. For larger return values, the caller must allocate space for - the callee to copy the return value to. A pointer to this space is - passed as an implicit first argument, always in R0. */ - -CORE_ADDR -m32r_push_arguments (nargs, args, sp, struct_return, struct_addr) - int nargs; - value_ptr *args; - CORE_ADDR sp; - unsigned char struct_return; - CORE_ADDR struct_addr; -{ - int stack_offset, stack_alloc; - int argreg; - int argnum; - struct type *type; - CORE_ADDR regval; - char *val; - char valbuf[4]; - int len; - int odd_sized_struct; - - /* first force sp to a 4-byte alignment */ - sp = sp & ~3; - - argreg = ARG0_REGNUM; - /* The "struct return pointer" pseudo-argument goes in R0 */ - if (struct_return) - write_register (argreg++, struct_addr); - - /* Now make sure there's space on the stack */ - for (argnum = 0, stack_alloc = 0; - argnum < nargs; argnum++) - stack_alloc += ((TYPE_LENGTH(VALUE_TYPE(args[argnum])) + 3) & ~3); - sp -= stack_alloc; /* make room on stack for args */ - - - /* 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. */ - - argreg = ARG0_REGNUM; - for (argnum = 0, stack_offset = 0; argnum < nargs; argnum++) - { - type = VALUE_TYPE (args[argnum]); - len = TYPE_LENGTH (type); - memset(valbuf, 0, sizeof(valbuf)); - if (len < 4) - { /* value gets right-justified in the register or stack word */ - memcpy(valbuf + (4 - len), - (char *) VALUE_CONTENTS (args[argnum]), len); - val = valbuf; - } - else - val = (char *) VALUE_CONTENTS (args[argnum]); - - if (len > 4 && (len & 3) != 0) - odd_sized_struct = 1; /* such structs go entirely on stack */ - else - odd_sized_struct = 0; - while (len > 0) - { - if (argreg > ARGLAST_REGNUM || odd_sized_struct) - { /* must go on the stack */ - write_memory (sp + stack_offset, val, 4); - stack_offset += 4; - } - /* NOTE WELL!!!!! This is not an "else if" clause!!! - That's because some *&^%$ things get passed on the stack - AND in the registers! */ - if (argreg <= ARGLAST_REGNUM) - { /* there's room in a register */ - regval = extract_address (val, REGISTER_RAW_SIZE(argreg)); - write_register (argreg++, regval); - } - /* Store the value 4 bytes at a time. This means that things - larger than 4 bytes may go partly in registers and partly - on the stack. */ - len -= REGISTER_RAW_SIZE(argreg); - val += REGISTER_RAW_SIZE(argreg); - } - } - return sp; -} - -/* Function: fix_call_dummy - If there is real CALL_DUMMY code (eg. on the stack), this function - has the responsability to insert the address of the actual code that - is the target of the target function call. */ - -void -m32r_fix_call_dummy (dummy, pc, fun, nargs, args, type, gcc_p) - char *dummy; - CORE_ADDR pc; - CORE_ADDR fun; - int nargs; - value_ptr *args; - struct type *type; - int gcc_p; -{ - /* ld24 r8, <(imm24) fun> */ - *(unsigned long *) (dummy) = (fun & 0x00ffffff) | 0xe8000000; -} - -/* Function: get_saved_register - Just call the generic_get_saved_register function. */ - -void -get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval) - char *raw_buffer; - int *optimized; - CORE_ADDR *addrp; - struct frame_info *frame; - int regnum; - enum lval_type *lval; -{ - generic_get_saved_register (raw_buffer, optimized, addrp, - frame, regnum, lval); -} - - -/* Function: m32r_write_sp - Because SP is really a read-only register that mirrors either SPU or SPI, - we must actually write one of those two as well, depending on PSW. */ - -void -m32r_write_sp (val) - CORE_ADDR val; -{ - unsigned long psw = read_register (PSW_REGNUM); - - if (psw & 0x80) /* stack mode: user or interrupt */ - write_register (SPU_REGNUM, val); - else - write_register (SPI_REGNUM, val); - write_register (SP_REGNUM, val); -} - -void -_initialize_m32r_tdep () -{ - tm_print_insn = print_insn_m32r; -} - |