xref: /netbsd-src/external/gpl3/gdb/dist/sim/rx/gdb-if.c (revision 1f4e7eb9e5e045e008f1894823a8e4e6c9f46890)
14e98e3e1Schristos /* gdb-if.c -- sim interface to GDB.
24e98e3e1Schristos 
3*1f4e7eb9Schristos Copyright (C) 2008-2024 Free Software Foundation, Inc.
44e98e3e1Schristos Contributed by Red Hat, Inc.
54e98e3e1Schristos 
64e98e3e1Schristos This file is part of the GNU simulators.
74e98e3e1Schristos 
84e98e3e1Schristos This program is free software; you can redistribute it and/or modify
94e98e3e1Schristos it under the terms of the GNU General Public License as published by
104e98e3e1Schristos the Free Software Foundation; either version 3 of the License, or
114e98e3e1Schristos (at your option) any later version.
124e98e3e1Schristos 
134e98e3e1Schristos This program is distributed in the hope that it will be useful,
144e98e3e1Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
154e98e3e1Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
164e98e3e1Schristos GNU General Public License for more details.
174e98e3e1Schristos 
184e98e3e1Schristos You should have received a copy of the GNU General Public License
194e98e3e1Schristos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
204e98e3e1Schristos 
214b169a6bSchristos /* This must come before any other includes.  */
224b169a6bSchristos #include "defs.h"
234b169a6bSchristos 
244e98e3e1Schristos #include <stdio.h>
254e98e3e1Schristos #include <assert.h>
264e98e3e1Schristos #include <signal.h>
274e98e3e1Schristos #include <string.h>
284e98e3e1Schristos #include <ctype.h>
294e98e3e1Schristos #include <stdlib.h>
304e98e3e1Schristos 
314e98e3e1Schristos #include "ansidecl.h"
32*1f4e7eb9Schristos #include "bfd.h"
334b169a6bSchristos #include "libiberty.h"
344b169a6bSchristos #include "sim/callback.h"
354b169a6bSchristos #include "sim/sim.h"
364e98e3e1Schristos #include "gdb/signals.h"
37*1f4e7eb9Schristos #include "sim/sim-rx.h"
384e98e3e1Schristos 
394e98e3e1Schristos #include "cpu.h"
404e98e3e1Schristos #include "mem.h"
414e98e3e1Schristos #include "load.h"
424e98e3e1Schristos #include "syscalls.h"
434e98e3e1Schristos #include "err.h"
444e98e3e1Schristos #include "trace.h"
454e98e3e1Schristos 
464e98e3e1Schristos /* Ideally, we'd wrap up all the minisim's data structures in an
474e98e3e1Schristos    object and pass that around.  However, neither GDB nor run needs
484e98e3e1Schristos    that ability.
494e98e3e1Schristos 
504e98e3e1Schristos    So we just have one instance, that lives in global variables, and
514e98e3e1Schristos    each time we open it, we re-initialize it.  */
524e98e3e1Schristos struct sim_state
534e98e3e1Schristos {
544e98e3e1Schristos   const char *message;
554e98e3e1Schristos };
564e98e3e1Schristos 
574e98e3e1Schristos static struct sim_state the_minisim = {
584e98e3e1Schristos   "This is the sole rx minisim instance.  See libsim.a's global variables."
594e98e3e1Schristos };
604e98e3e1Schristos 
61837edd6bSchristos static int rx_sim_is_open;
624e98e3e1Schristos 
634e98e3e1Schristos SIM_DESC
644e98e3e1Schristos sim_open (SIM_OPEN_KIND kind,
654e98e3e1Schristos 	  struct host_callback_struct *callback,
66ba340e45Schristos 	  struct bfd *abfd, char * const *argv)
674e98e3e1Schristos {
68837edd6bSchristos   if (rx_sim_is_open)
694e98e3e1Schristos     fprintf (stderr, "rx minisim: re-opened sim\n");
704e98e3e1Schristos 
714e98e3e1Schristos   /* The 'run' interface doesn't use this function, so we don't care
724e98e3e1Schristos      about KIND; it's always SIM_OPEN_DEBUG.  */
734e98e3e1Schristos   if (kind != SIM_OPEN_DEBUG)
744e98e3e1Schristos     fprintf (stderr, "rx minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
754e98e3e1Schristos 	     kind);
764e98e3e1Schristos 
774e98e3e1Schristos   set_callbacks (callback);
784e98e3e1Schristos 
794e98e3e1Schristos   /* We don't expect any command-line arguments.  */
804e98e3e1Schristos 
814e98e3e1Schristos   init_mem ();
824e98e3e1Schristos   init_regs ();
834e98e3e1Schristos   execution_error_init_debugger ();
844e98e3e1Schristos 
854e98e3e1Schristos   sim_disasm_init (abfd);
86837edd6bSchristos   rx_sim_is_open = 1;
874e98e3e1Schristos   return &the_minisim;
884e98e3e1Schristos }
894e98e3e1Schristos 
904e98e3e1Schristos static void
914e98e3e1Schristos check_desc (SIM_DESC sd)
924e98e3e1Schristos {
934e98e3e1Schristos   if (sd != &the_minisim)
944e98e3e1Schristos     fprintf (stderr, "rx minisim: desc != &the_minisim\n");
954e98e3e1Schristos }
964e98e3e1Schristos 
974e98e3e1Schristos void
984e98e3e1Schristos sim_close (SIM_DESC sd, int quitting)
994e98e3e1Schristos {
1004e98e3e1Schristos   check_desc (sd);
1014e98e3e1Schristos 
1024e98e3e1Schristos   /* Not much to do.  At least free up our memory.  */
1034e98e3e1Schristos   init_mem ();
1044e98e3e1Schristos 
105837edd6bSchristos   rx_sim_is_open = 0;
1064e98e3e1Schristos }
1074e98e3e1Schristos 
1084e98e3e1Schristos static bfd *
1094e98e3e1Schristos open_objfile (const char *filename)
1104e98e3e1Schristos {
1114e98e3e1Schristos   bfd *prog = bfd_openr (filename, 0);
1124e98e3e1Schristos 
1134e98e3e1Schristos   if (!prog)
1144e98e3e1Schristos     {
1154e98e3e1Schristos       fprintf (stderr, "Can't read %s\n", filename);
1164e98e3e1Schristos       return 0;
1174e98e3e1Schristos     }
1184e98e3e1Schristos 
1194e98e3e1Schristos   if (!bfd_check_format (prog, bfd_object))
1204e98e3e1Schristos     {
1214e98e3e1Schristos       fprintf (stderr, "%s not a rx program\n", filename);
1224e98e3e1Schristos       return 0;
1234e98e3e1Schristos     }
1244e98e3e1Schristos 
1254e98e3e1Schristos   return prog;
1264e98e3e1Schristos }
1274e98e3e1Schristos 
1284e98e3e1Schristos static struct swap_list
1294e98e3e1Schristos {
1304e98e3e1Schristos   bfd_vma start, end;
1314e98e3e1Schristos   struct swap_list *next;
1324e98e3e1Schristos } *swap_list = NULL;
1334e98e3e1Schristos 
1344e98e3e1Schristos static void
1354e98e3e1Schristos free_swap_list (void)
1364e98e3e1Schristos {
1374e98e3e1Schristos   while (swap_list)
1384e98e3e1Schristos     {
1394e98e3e1Schristos       struct swap_list *next = swap_list->next;
1404e98e3e1Schristos       free (swap_list);
1414e98e3e1Schristos       swap_list = next;
1424e98e3e1Schristos     }
1434e98e3e1Schristos }
1444e98e3e1Schristos 
1454e98e3e1Schristos /* When running in big endian mode, we must do an additional
1464e98e3e1Schristos    byte swap of memory areas used to hold instructions.  See
1474e98e3e1Schristos    the comment preceding rx_load in load.c to see why this is
1484e98e3e1Schristos    so.
1494e98e3e1Schristos 
1504e98e3e1Schristos    Construct a list of memory areas that must be byte swapped.
1514e98e3e1Schristos    This list will be consulted when either reading or writing
1524e98e3e1Schristos    memory.  */
1534e98e3e1Schristos 
1544e98e3e1Schristos static void
1554e98e3e1Schristos build_swap_list (struct bfd *abfd)
1564e98e3e1Schristos {
1574e98e3e1Schristos   asection *s;
1584e98e3e1Schristos   free_swap_list ();
1594e98e3e1Schristos 
1604e98e3e1Schristos   /* Nothing to do when in little endian mode.  */
1614e98e3e1Schristos   if (!rx_big_endian)
1624e98e3e1Schristos     return;
1634e98e3e1Schristos 
1644e98e3e1Schristos   for (s = abfd->sections; s; s = s->next)
1654e98e3e1Schristos     {
1664e98e3e1Schristos       if ((s->flags & SEC_LOAD) && (s->flags & SEC_CODE))
1674e98e3e1Schristos 	{
1684e98e3e1Schristos 	  struct swap_list *sl;
1694e98e3e1Schristos 	  bfd_size_type size;
1704e98e3e1Schristos 
1718dffb485Schristos 	  size = bfd_section_size (s);
1724e98e3e1Schristos 	  if (size <= 0)
1734e98e3e1Schristos 	    continue;
1744e98e3e1Schristos 
1754e98e3e1Schristos 	  sl = malloc (sizeof (struct swap_list));
1764e98e3e1Schristos 	  assert (sl != NULL);
1774e98e3e1Schristos 	  sl->next = swap_list;
1788dffb485Schristos 	  sl->start = bfd_section_lma (s);
1794e98e3e1Schristos 	  sl->end = sl->start + size;
1804e98e3e1Schristos 	  swap_list = sl;
1814e98e3e1Schristos 	}
1824e98e3e1Schristos     }
1834e98e3e1Schristos }
1844e98e3e1Schristos 
1854e98e3e1Schristos static int
1864e98e3e1Schristos addr_in_swap_list (bfd_vma addr)
1874e98e3e1Schristos {
1884e98e3e1Schristos   struct swap_list *s;
1894e98e3e1Schristos 
1904e98e3e1Schristos   for (s = swap_list; s; s = s->next)
1914e98e3e1Schristos     {
1924e98e3e1Schristos       if (s->start <= addr && addr < s->end)
1934e98e3e1Schristos 	return 1;
1944e98e3e1Schristos     }
1954e98e3e1Schristos   return 0;
1964e98e3e1Schristos }
1974e98e3e1Schristos 
1984e98e3e1Schristos SIM_RC
199837edd6bSchristos sim_load (SIM_DESC sd, const char *prog, struct bfd *abfd, int from_tty)
2004e98e3e1Schristos {
2014e98e3e1Schristos   check_desc (sd);
2024e98e3e1Schristos 
2034e98e3e1Schristos   if (!abfd)
2044e98e3e1Schristos     abfd = open_objfile (prog);
2054e98e3e1Schristos   if (!abfd)
2064e98e3e1Schristos     return SIM_RC_FAIL;
2074e98e3e1Schristos 
208a2e2270fSchristos   rx_load (abfd, get_callbacks ());
2094e98e3e1Schristos   build_swap_list (abfd);
2104e98e3e1Schristos 
2114e98e3e1Schristos   return SIM_RC_OK;
2124e98e3e1Schristos }
2134e98e3e1Schristos 
2144e98e3e1Schristos SIM_RC
215ba340e45Schristos sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
216ba340e45Schristos 		     char * const *argv, char * const *env)
2174e98e3e1Schristos {
2184e98e3e1Schristos   check_desc (sd);
2194e98e3e1Schristos 
2204e98e3e1Schristos   if (abfd)
2214e98e3e1Schristos     {
222a2e2270fSchristos       rx_load (abfd, NULL);
2234e98e3e1Schristos       build_swap_list (abfd);
2244e98e3e1Schristos     }
2254e98e3e1Schristos 
2264e98e3e1Schristos   return SIM_RC_OK;
2274e98e3e1Schristos }
2284e98e3e1Schristos 
229*1f4e7eb9Schristos uint64_t
230*1f4e7eb9Schristos sim_read (SIM_DESC sd, uint64_t addr, void *buffer, uint64_t length)
2314e98e3e1Schristos {
2324e98e3e1Schristos   int i;
2334b169a6bSchristos   unsigned char *data = buffer;
2344e98e3e1Schristos 
2354e98e3e1Schristos   check_desc (sd);
2364e98e3e1Schristos 
237*1f4e7eb9Schristos   if (addr == 0)
2384e98e3e1Schristos     return 0;
2394e98e3e1Schristos 
2404e98e3e1Schristos   execution_error_clear_last_error ();
2414e98e3e1Schristos 
2424e98e3e1Schristos   for (i = 0; i < length; i++)
2434e98e3e1Schristos     {
244*1f4e7eb9Schristos       bfd_vma vma = addr + i;
245*1f4e7eb9Schristos       int do_swap = addr_in_swap_list (vma);
246*1f4e7eb9Schristos       data[i] = mem_get_qi (vma ^ (do_swap ? 3 : 0));
2474e98e3e1Schristos 
2484e98e3e1Schristos       if (execution_error_get_last_error () != SIM_ERR_NONE)
2494e98e3e1Schristos 	return i;
2504e98e3e1Schristos     }
2514e98e3e1Schristos 
2524e98e3e1Schristos   return length;
2534e98e3e1Schristos }
2544e98e3e1Schristos 
255*1f4e7eb9Schristos uint64_t
256*1f4e7eb9Schristos sim_write (SIM_DESC sd, uint64_t addr, const void *buffer, uint64_t length)
2574e98e3e1Schristos {
2584e98e3e1Schristos   int i;
2594b169a6bSchristos   const unsigned char *data = buffer;
2604e98e3e1Schristos 
2614e98e3e1Schristos   check_desc (sd);
2624e98e3e1Schristos 
2634e98e3e1Schristos   execution_error_clear_last_error ();
2644e98e3e1Schristos 
2654e98e3e1Schristos   for (i = 0; i < length; i++)
2664e98e3e1Schristos     {
267*1f4e7eb9Schristos       bfd_vma vma = addr + i;
268*1f4e7eb9Schristos       int do_swap = addr_in_swap_list (vma);
269*1f4e7eb9Schristos       mem_put_qi (vma ^ (do_swap ? 3 : 0), data[i]);
2704e98e3e1Schristos 
2714e98e3e1Schristos       if (execution_error_get_last_error () != SIM_ERR_NONE)
2724e98e3e1Schristos 	return i;
2734e98e3e1Schristos     }
2744e98e3e1Schristos 
2754e98e3e1Schristos   return length;
2764e98e3e1Schristos }
2774e98e3e1Schristos 
2784e98e3e1Schristos /* Read the LENGTH bytes at BUF as an little-endian value.  */
2794e98e3e1Schristos static DI
2804b169a6bSchristos get_le (const unsigned char *buf, int length)
2814e98e3e1Schristos {
2824e98e3e1Schristos   DI acc = 0;
2834e98e3e1Schristos   while (--length >= 0)
2844e98e3e1Schristos     acc = (acc << 8) + buf[length];
2854e98e3e1Schristos 
2864e98e3e1Schristos   return acc;
2874e98e3e1Schristos }
2884e98e3e1Schristos 
2894e98e3e1Schristos /* Read the LENGTH bytes at BUF as a big-endian value.  */
2904e98e3e1Schristos static DI
2914b169a6bSchristos get_be (const unsigned char *buf, int length)
2924e98e3e1Schristos {
2934e98e3e1Schristos   DI acc = 0;
2944e98e3e1Schristos   while (length-- > 0)
2954e98e3e1Schristos     acc = (acc << 8) + *buf++;
2964e98e3e1Schristos 
2974e98e3e1Schristos   return acc;
2984e98e3e1Schristos }
2994e98e3e1Schristos 
3004e98e3e1Schristos /* Store VAL as a little-endian value in the LENGTH bytes at BUF.  */
3014e98e3e1Schristos static void
3024e98e3e1Schristos put_le (unsigned char *buf, int length, DI val)
3034e98e3e1Schristos {
3044e98e3e1Schristos   int i;
3054e98e3e1Schristos 
3064e98e3e1Schristos   for (i = 0; i < length; i++)
3074e98e3e1Schristos     {
3084e98e3e1Schristos       buf[i] = val & 0xff;
3094e98e3e1Schristos       val >>= 8;
3104e98e3e1Schristos     }
3114e98e3e1Schristos }
3124e98e3e1Schristos 
3134e98e3e1Schristos /* Store VAL as a big-endian value in the LENGTH bytes at BUF.  */
3144e98e3e1Schristos static void
3154e98e3e1Schristos put_be (unsigned char *buf, int length, DI val)
3164e98e3e1Schristos {
3174e98e3e1Schristos   int i;
3184e98e3e1Schristos 
3194e98e3e1Schristos   for (i = length-1; i >= 0; i--)
3204e98e3e1Schristos     {
3214e98e3e1Schristos       buf[i] = val & 0xff;
3224e98e3e1Schristos       val >>= 8;
3234e98e3e1Schristos     }
3244e98e3e1Schristos }
3254e98e3e1Schristos 
3264e98e3e1Schristos 
3274e98e3e1Schristos static int
3284e98e3e1Schristos check_regno (enum sim_rx_regnum regno)
3294e98e3e1Schristos {
3304e98e3e1Schristos   return 0 <= regno && regno < sim_rx_num_regs;
3314e98e3e1Schristos }
3324e98e3e1Schristos 
3334e98e3e1Schristos static size_t
3344e98e3e1Schristos reg_size (enum sim_rx_regnum regno)
3354e98e3e1Schristos {
3364e98e3e1Schristos   size_t size;
3374e98e3e1Schristos 
3384e98e3e1Schristos   switch (regno)
3394e98e3e1Schristos     {
3404e98e3e1Schristos     case sim_rx_r0_regnum:
3414e98e3e1Schristos       size = sizeof (regs.r[0]);
3424e98e3e1Schristos       break;
3434e98e3e1Schristos     case sim_rx_r1_regnum:
3444e98e3e1Schristos       size = sizeof (regs.r[1]);
3454e98e3e1Schristos       break;
3464e98e3e1Schristos     case sim_rx_r2_regnum:
3474e98e3e1Schristos       size = sizeof (regs.r[2]);
3484e98e3e1Schristos       break;
3494e98e3e1Schristos     case sim_rx_r3_regnum:
3504e98e3e1Schristos       size = sizeof (regs.r[3]);
3514e98e3e1Schristos       break;
3524e98e3e1Schristos     case sim_rx_r4_regnum:
3534e98e3e1Schristos       size = sizeof (regs.r[4]);
3544e98e3e1Schristos       break;
3554e98e3e1Schristos     case sim_rx_r5_regnum:
3564e98e3e1Schristos       size = sizeof (regs.r[5]);
3574e98e3e1Schristos       break;
3584e98e3e1Schristos     case sim_rx_r6_regnum:
3594e98e3e1Schristos       size = sizeof (regs.r[6]);
3604e98e3e1Schristos       break;
3614e98e3e1Schristos     case sim_rx_r7_regnum:
3624e98e3e1Schristos       size = sizeof (regs.r[7]);
3634e98e3e1Schristos       break;
3644e98e3e1Schristos     case sim_rx_r8_regnum:
3654e98e3e1Schristos       size = sizeof (regs.r[8]);
3664e98e3e1Schristos       break;
3674e98e3e1Schristos     case sim_rx_r9_regnum:
3684e98e3e1Schristos       size = sizeof (regs.r[9]);
3694e98e3e1Schristos       break;
3704e98e3e1Schristos     case sim_rx_r10_regnum:
3714e98e3e1Schristos       size = sizeof (regs.r[10]);
3724e98e3e1Schristos       break;
3734e98e3e1Schristos     case sim_rx_r11_regnum:
3744e98e3e1Schristos       size = sizeof (regs.r[11]);
3754e98e3e1Schristos       break;
3764e98e3e1Schristos     case sim_rx_r12_regnum:
3774e98e3e1Schristos       size = sizeof (regs.r[12]);
3784e98e3e1Schristos       break;
3794e98e3e1Schristos     case sim_rx_r13_regnum:
3804e98e3e1Schristos       size = sizeof (regs.r[13]);
3814e98e3e1Schristos       break;
3824e98e3e1Schristos     case sim_rx_r14_regnum:
3834e98e3e1Schristos       size = sizeof (regs.r[14]);
3844e98e3e1Schristos       break;
3854e98e3e1Schristos     case sim_rx_r15_regnum:
3864e98e3e1Schristos       size = sizeof (regs.r[15]);
3874e98e3e1Schristos       break;
3884e98e3e1Schristos     case sim_rx_isp_regnum:
3894e98e3e1Schristos       size = sizeof (regs.r_isp);
3904e98e3e1Schristos       break;
3914e98e3e1Schristos     case sim_rx_usp_regnum:
3924e98e3e1Schristos       size = sizeof (regs.r_usp);
3934e98e3e1Schristos       break;
3944e98e3e1Schristos     case sim_rx_intb_regnum:
3954e98e3e1Schristos       size = sizeof (regs.r_intb);
3964e98e3e1Schristos       break;
3974e98e3e1Schristos     case sim_rx_pc_regnum:
3984e98e3e1Schristos       size = sizeof (regs.r_pc);
3994e98e3e1Schristos       break;
4004e98e3e1Schristos     case sim_rx_ps_regnum:
4014e98e3e1Schristos       size = sizeof (regs.r_psw);
4024e98e3e1Schristos       break;
4034e98e3e1Schristos     case sim_rx_bpc_regnum:
4044e98e3e1Schristos       size = sizeof (regs.r_bpc);
4054e98e3e1Schristos       break;
4064e98e3e1Schristos     case sim_rx_bpsw_regnum:
4074e98e3e1Schristos       size = sizeof (regs.r_bpsw);
4084e98e3e1Schristos       break;
4094e98e3e1Schristos     case sim_rx_fintv_regnum:
4104e98e3e1Schristos       size = sizeof (regs.r_fintv);
4114e98e3e1Schristos       break;
4124e98e3e1Schristos     case sim_rx_fpsw_regnum:
4134e98e3e1Schristos       size = sizeof (regs.r_fpsw);
4144e98e3e1Schristos       break;
4154e98e3e1Schristos     case sim_rx_acc_regnum:
4164e98e3e1Schristos       size = sizeof (regs.r_acc);
4174e98e3e1Schristos       break;
4184e98e3e1Schristos     default:
4194e98e3e1Schristos       size = 0;
4204e98e3e1Schristos       break;
4214e98e3e1Schristos     }
4224e98e3e1Schristos   return size;
4234e98e3e1Schristos }
4244e98e3e1Schristos 
4254e98e3e1Schristos int
4264b169a6bSchristos sim_fetch_register (SIM_DESC sd, int regno, void *buf, int length)
4274e98e3e1Schristos {
4284e98e3e1Schristos   size_t size;
4294e98e3e1Schristos   DI val;
4304e98e3e1Schristos 
4314e98e3e1Schristos   check_desc (sd);
4324e98e3e1Schristos 
4334e98e3e1Schristos   if (!check_regno (regno))
4344e98e3e1Schristos     return 0;
4354e98e3e1Schristos 
4364e98e3e1Schristos   size = reg_size (regno);
4374e98e3e1Schristos 
4384e98e3e1Schristos   if (length != size)
4394e98e3e1Schristos     return 0;
4404e98e3e1Schristos 
4414e98e3e1Schristos   switch (regno)
4424e98e3e1Schristos     {
4434e98e3e1Schristos     case sim_rx_r0_regnum:
4444e98e3e1Schristos       val = get_reg (0);
4454e98e3e1Schristos       break;
4464e98e3e1Schristos     case sim_rx_r1_regnum:
4474e98e3e1Schristos       val = get_reg (1);
4484e98e3e1Schristos       break;
4494e98e3e1Schristos     case sim_rx_r2_regnum:
4504e98e3e1Schristos       val = get_reg (2);
4514e98e3e1Schristos       break;
4524e98e3e1Schristos     case sim_rx_r3_regnum:
4534e98e3e1Schristos       val = get_reg (3);
4544e98e3e1Schristos       break;
4554e98e3e1Schristos     case sim_rx_r4_regnum:
4564e98e3e1Schristos       val = get_reg (4);
4574e98e3e1Schristos       break;
4584e98e3e1Schristos     case sim_rx_r5_regnum:
4594e98e3e1Schristos       val = get_reg (5);
4604e98e3e1Schristos       break;
4614e98e3e1Schristos     case sim_rx_r6_regnum:
4624e98e3e1Schristos       val = get_reg (6);
4634e98e3e1Schristos       break;
4644e98e3e1Schristos     case sim_rx_r7_regnum:
4654e98e3e1Schristos       val = get_reg (7);
4664e98e3e1Schristos       break;
4674e98e3e1Schristos     case sim_rx_r8_regnum:
4684e98e3e1Schristos       val = get_reg (8);
4694e98e3e1Schristos       break;
4704e98e3e1Schristos     case sim_rx_r9_regnum:
4714e98e3e1Schristos       val = get_reg (9);
4724e98e3e1Schristos       break;
4734e98e3e1Schristos     case sim_rx_r10_regnum:
4744e98e3e1Schristos       val = get_reg (10);
4754e98e3e1Schristos       break;
4764e98e3e1Schristos     case sim_rx_r11_regnum:
4774e98e3e1Schristos       val = get_reg (11);
4784e98e3e1Schristos       break;
4794e98e3e1Schristos     case sim_rx_r12_regnum:
4804e98e3e1Schristos       val = get_reg (12);
4814e98e3e1Schristos       break;
4824e98e3e1Schristos     case sim_rx_r13_regnum:
4834e98e3e1Schristos       val = get_reg (13);
4844e98e3e1Schristos       break;
4854e98e3e1Schristos     case sim_rx_r14_regnum:
4864e98e3e1Schristos       val = get_reg (14);
4874e98e3e1Schristos       break;
4884e98e3e1Schristos     case sim_rx_r15_regnum:
4894e98e3e1Schristos       val = get_reg (15);
4904e98e3e1Schristos       break;
4914e98e3e1Schristos     case sim_rx_isp_regnum:
4924e98e3e1Schristos       val = get_reg (isp);
4934e98e3e1Schristos       break;
4944e98e3e1Schristos     case sim_rx_usp_regnum:
4954e98e3e1Schristos       val = get_reg (usp);
4964e98e3e1Schristos       break;
4974e98e3e1Schristos     case sim_rx_intb_regnum:
4984e98e3e1Schristos       val = get_reg (intb);
4994e98e3e1Schristos       break;
5004e98e3e1Schristos     case sim_rx_pc_regnum:
5014e98e3e1Schristos       val = get_reg (pc);
5024e98e3e1Schristos       break;
5034e98e3e1Schristos     case sim_rx_ps_regnum:
5044e98e3e1Schristos       val = get_reg (psw);
5054e98e3e1Schristos       break;
5064e98e3e1Schristos     case sim_rx_bpc_regnum:
5074e98e3e1Schristos       val = get_reg (bpc);
5084e98e3e1Schristos       break;
5094e98e3e1Schristos     case sim_rx_bpsw_regnum:
5104e98e3e1Schristos       val = get_reg (bpsw);
5114e98e3e1Schristos       break;
5124e98e3e1Schristos     case sim_rx_fintv_regnum:
5134e98e3e1Schristos       val = get_reg (fintv);
5144e98e3e1Schristos       break;
5154e98e3e1Schristos     case sim_rx_fpsw_regnum:
5164e98e3e1Schristos       val = get_reg (fpsw);
5174e98e3e1Schristos       break;
5184e98e3e1Schristos     case sim_rx_acc_regnum:
5194e98e3e1Schristos       val = ((DI) get_reg (acchi) << 32) | get_reg (acclo);
5204e98e3e1Schristos       break;
5214e98e3e1Schristos     default:
5224e98e3e1Schristos       fprintf (stderr, "rx minisim: unrecognized register number: %d\n",
5234e98e3e1Schristos 	       regno);
5244e98e3e1Schristos       return -1;
5254e98e3e1Schristos     }
5264e98e3e1Schristos 
5274e98e3e1Schristos   if (rx_big_endian)
5284e98e3e1Schristos     put_be (buf, length, val);
5294e98e3e1Schristos   else
5304e98e3e1Schristos     put_le (buf, length, val);
5314e98e3e1Schristos 
5324e98e3e1Schristos   return size;
5334e98e3e1Schristos }
5344e98e3e1Schristos 
5354e98e3e1Schristos int
5364b169a6bSchristos sim_store_register (SIM_DESC sd, int regno, const void *buf, int length)
5374e98e3e1Schristos {
5384e98e3e1Schristos   size_t size;
5394e98e3e1Schristos   DI val;
5404e98e3e1Schristos 
5414e98e3e1Schristos   check_desc (sd);
5424e98e3e1Schristos 
5434e98e3e1Schristos   if (!check_regno (regno))
5444e98e3e1Schristos     return -1;
5454e98e3e1Schristos 
5464e98e3e1Schristos   size = reg_size (regno);
5474e98e3e1Schristos 
5484e98e3e1Schristos   if (length != size)
5494e98e3e1Schristos     return -1;
5504e98e3e1Schristos 
5514e98e3e1Schristos   if (rx_big_endian)
5524e98e3e1Schristos     val = get_be (buf, length);
5534e98e3e1Schristos   else
5544e98e3e1Schristos     val = get_le (buf, length);
5554e98e3e1Schristos 
5564e98e3e1Schristos   switch (regno)
5574e98e3e1Schristos     {
5584e98e3e1Schristos     case sim_rx_r0_regnum:
5594e98e3e1Schristos       put_reg (0, val);
5604e98e3e1Schristos       break;
5614e98e3e1Schristos     case sim_rx_r1_regnum:
5624e98e3e1Schristos       put_reg (1, val);
5634e98e3e1Schristos       break;
5644e98e3e1Schristos     case sim_rx_r2_regnum:
5654e98e3e1Schristos       put_reg (2, val);
5664e98e3e1Schristos       break;
5674e98e3e1Schristos     case sim_rx_r3_regnum:
5684e98e3e1Schristos       put_reg (3, val);
5694e98e3e1Schristos       break;
5704e98e3e1Schristos     case sim_rx_r4_regnum:
5714e98e3e1Schristos       put_reg (4, val);
5724e98e3e1Schristos       break;
5734e98e3e1Schristos     case sim_rx_r5_regnum:
5744e98e3e1Schristos       put_reg (5, val);
5754e98e3e1Schristos       break;
5764e98e3e1Schristos     case sim_rx_r6_regnum:
5774e98e3e1Schristos       put_reg (6, val);
5784e98e3e1Schristos       break;
5794e98e3e1Schristos     case sim_rx_r7_regnum:
5804e98e3e1Schristos       put_reg (7, val);
5814e98e3e1Schristos       break;
5824e98e3e1Schristos     case sim_rx_r8_regnum:
5834e98e3e1Schristos       put_reg (8, val);
5844e98e3e1Schristos       break;
5854e98e3e1Schristos     case sim_rx_r9_regnum:
5864e98e3e1Schristos       put_reg (9, val);
5874e98e3e1Schristos       break;
5884e98e3e1Schristos     case sim_rx_r10_regnum:
5894e98e3e1Schristos       put_reg (10, val);
5904e98e3e1Schristos       break;
5914e98e3e1Schristos     case sim_rx_r11_regnum:
5924e98e3e1Schristos       put_reg (11, val);
5934e98e3e1Schristos       break;
5944e98e3e1Schristos     case sim_rx_r12_regnum:
5954e98e3e1Schristos       put_reg (12, val);
5964e98e3e1Schristos       break;
5974e98e3e1Schristos     case sim_rx_r13_regnum:
5984e98e3e1Schristos       put_reg (13, val);
5994e98e3e1Schristos       break;
6004e98e3e1Schristos     case sim_rx_r14_regnum:
6014e98e3e1Schristos       put_reg (14, val);
6024e98e3e1Schristos       break;
6034e98e3e1Schristos     case sim_rx_r15_regnum:
6044e98e3e1Schristos       put_reg (15, val);
6054e98e3e1Schristos       break;
6064e98e3e1Schristos     case sim_rx_isp_regnum:
6074e98e3e1Schristos       put_reg (isp, val);
6084e98e3e1Schristos       break;
6094e98e3e1Schristos     case sim_rx_usp_regnum:
6104e98e3e1Schristos       put_reg (usp, val);
6114e98e3e1Schristos       break;
6124e98e3e1Schristos     case sim_rx_intb_regnum:
6134e98e3e1Schristos       put_reg (intb, val);
6144e98e3e1Schristos       break;
6154e98e3e1Schristos     case sim_rx_pc_regnum:
6164e98e3e1Schristos       put_reg (pc, val);
6174e98e3e1Schristos       break;
6184e98e3e1Schristos     case sim_rx_ps_regnum:
6194e98e3e1Schristos       put_reg (psw, val);
6204e98e3e1Schristos       break;
6214e98e3e1Schristos     case sim_rx_bpc_regnum:
6224e98e3e1Schristos       put_reg (bpc, val);
6234e98e3e1Schristos       break;
6244e98e3e1Schristos     case sim_rx_bpsw_regnum:
6254e98e3e1Schristos       put_reg (bpsw, val);
6264e98e3e1Schristos       break;
6274e98e3e1Schristos     case sim_rx_fintv_regnum:
6284e98e3e1Schristos       put_reg (fintv, val);
6294e98e3e1Schristos       break;
6304e98e3e1Schristos     case sim_rx_fpsw_regnum:
6314e98e3e1Schristos       put_reg (fpsw, val);
6324e98e3e1Schristos       break;
6334e98e3e1Schristos     case sim_rx_acc_regnum:
6344e98e3e1Schristos       put_reg (acclo, val & 0xffffffff);
6354e98e3e1Schristos       put_reg (acchi, (val >> 32) & 0xffffffff);
6364e98e3e1Schristos       break;
6374e98e3e1Schristos     default:
6384e98e3e1Schristos       fprintf (stderr, "rx minisim: unrecognized register number: %d\n",
6394e98e3e1Schristos 	       regno);
6404e98e3e1Schristos       return 0;
6414e98e3e1Schristos     }
6424e98e3e1Schristos 
6434e98e3e1Schristos   return size;
6444e98e3e1Schristos }
6454e98e3e1Schristos 
6464e98e3e1Schristos void
647*1f4e7eb9Schristos sim_info (SIM_DESC sd, bool verbose)
6484e98e3e1Schristos {
6494e98e3e1Schristos   check_desc (sd);
6504e98e3e1Schristos 
6514e98e3e1Schristos   printf ("The rx minisim doesn't collect any statistics.\n");
6524e98e3e1Schristos }
6534e98e3e1Schristos 
6544e98e3e1Schristos static volatile int stop;
6554e98e3e1Schristos static enum sim_stop reason;
6564e98e3e1Schristos int siggnal;
6574e98e3e1Schristos 
6584e98e3e1Schristos 
6594e98e3e1Schristos /* Given a signal number used by the RX bsp (that is, newlib),
660837edd6bSchristos    return a target signal number used by GDB.  */
661837edd6bSchristos static int
662837edd6bSchristos rx_signal_to_gdb_signal (int rx)
6634e98e3e1Schristos {
6644e98e3e1Schristos   switch (rx)
6654e98e3e1Schristos     {
6664e98e3e1Schristos     case 4:
667837edd6bSchristos       return GDB_SIGNAL_ILL;
6684e98e3e1Schristos 
6694e98e3e1Schristos     case 5:
670837edd6bSchristos       return GDB_SIGNAL_TRAP;
6714e98e3e1Schristos 
6724e98e3e1Schristos     case 10:
673837edd6bSchristos       return GDB_SIGNAL_BUS;
6744e98e3e1Schristos 
6754e98e3e1Schristos     case 11:
676837edd6bSchristos       return GDB_SIGNAL_SEGV;
6774e98e3e1Schristos 
6784e98e3e1Schristos     case 24:
679837edd6bSchristos       return GDB_SIGNAL_XCPU;
6804e98e3e1Schristos 
6814e98e3e1Schristos     case 2:
682837edd6bSchristos       return GDB_SIGNAL_INT;
6834e98e3e1Schristos 
6844e98e3e1Schristos     case 8:
685837edd6bSchristos       return GDB_SIGNAL_FPE;
6864e98e3e1Schristos 
6874e98e3e1Schristos     case 6:
688837edd6bSchristos       return GDB_SIGNAL_ABRT;
6894e98e3e1Schristos     }
6904e98e3e1Schristos 
6914e98e3e1Schristos   return 0;
6924e98e3e1Schristos }
6934e98e3e1Schristos 
6944e98e3e1Schristos 
6954e98e3e1Schristos /* Take a step return code RC and set up the variables consulted by
6964e98e3e1Schristos    sim_stop_reason appropriately.  */
6974b169a6bSchristos static void
6984e98e3e1Schristos handle_step (int rc)
6994e98e3e1Schristos {
7004e98e3e1Schristos   if (execution_error_get_last_error () != SIM_ERR_NONE)
7014e98e3e1Schristos     {
7024e98e3e1Schristos       reason = sim_stopped;
703a2e2270fSchristos       siggnal = GDB_SIGNAL_SEGV;
7044e98e3e1Schristos     }
7054e98e3e1Schristos   if (RX_STEPPED (rc) || RX_HIT_BREAK (rc))
7064e98e3e1Schristos     {
7074e98e3e1Schristos       reason = sim_stopped;
708a2e2270fSchristos       siggnal = GDB_SIGNAL_TRAP;
7094e98e3e1Schristos     }
7104e98e3e1Schristos   else if (RX_STOPPED (rc))
7114e98e3e1Schristos     {
7124e98e3e1Schristos       reason = sim_stopped;
713837edd6bSchristos       siggnal = rx_signal_to_gdb_signal (RX_STOP_SIG (rc));
7144e98e3e1Schristos     }
7154e98e3e1Schristos   else
7164e98e3e1Schristos     {
7174e98e3e1Schristos       assert (RX_EXITED (rc));
7184e98e3e1Schristos       reason = sim_exited;
7194e98e3e1Schristos       siggnal = RX_EXIT_STATUS (rc);
7204e98e3e1Schristos     }
7214e98e3e1Schristos }
7224e98e3e1Schristos 
7234e98e3e1Schristos 
7244e98e3e1Schristos void
7254e98e3e1Schristos sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
7264e98e3e1Schristos {
7274e98e3e1Schristos   int rc;
7284e98e3e1Schristos 
7294e98e3e1Schristos   check_desc (sd);
7304e98e3e1Schristos 
7314e98e3e1Schristos   if (sig_to_deliver != 0)
7324e98e3e1Schristos     {
7334e98e3e1Schristos       fprintf (stderr,
7344e98e3e1Schristos 	       "Warning: the rx minisim does not implement "
7354e98e3e1Schristos 	       "signal delivery yet.\n" "Resuming with no signal.\n");
7364e98e3e1Schristos     }
7374e98e3e1Schristos 
7384e98e3e1Schristos   execution_error_clear_last_error ();
7394e98e3e1Schristos 
7404e98e3e1Schristos   if (step)
7414e98e3e1Schristos     {
7424e98e3e1Schristos       rc = setjmp (decode_jmp_buf);
7434e98e3e1Schristos       if (rc == 0)
7444e98e3e1Schristos 	rc = decode_opcode ();
7454e98e3e1Schristos       handle_step (rc);
7464e98e3e1Schristos     }
7474e98e3e1Schristos   else
7484e98e3e1Schristos     {
7494e98e3e1Schristos       /* We don't clear 'stop' here, because then we would miss
7504e98e3e1Schristos          interrupts that arrived on the way here.  Instead, we clear
7514e98e3e1Schristos          the flag in sim_stop_reason, after GDB has disabled the
7524e98e3e1Schristos          interrupt signal handler.  */
7534e98e3e1Schristos       for (;;)
7544e98e3e1Schristos 	{
7554e98e3e1Schristos 	  if (stop)
7564e98e3e1Schristos 	    {
7574e98e3e1Schristos 	      stop = 0;
7584e98e3e1Schristos 	      reason = sim_stopped;
759a2e2270fSchristos 	      siggnal = GDB_SIGNAL_INT;
7604e98e3e1Schristos 	      break;
7614e98e3e1Schristos 	    }
7624e98e3e1Schristos 
7634e98e3e1Schristos 	  rc = setjmp (decode_jmp_buf);
7644e98e3e1Schristos 	  if (rc == 0)
7654e98e3e1Schristos 	    rc = decode_opcode ();
7664e98e3e1Schristos 
7674e98e3e1Schristos 	  if (execution_error_get_last_error () != SIM_ERR_NONE)
7684e98e3e1Schristos 	    {
7694e98e3e1Schristos 	      reason = sim_stopped;
770a2e2270fSchristos 	      siggnal = GDB_SIGNAL_SEGV;
7714e98e3e1Schristos 	      break;
7724e98e3e1Schristos 	    }
7734e98e3e1Schristos 
7744e98e3e1Schristos 	  if (!RX_STEPPED (rc))
7754e98e3e1Schristos 	    {
7764e98e3e1Schristos 	      handle_step (rc);
7774e98e3e1Schristos 	      break;
7784e98e3e1Schristos 	    }
7794e98e3e1Schristos 	}
7804e98e3e1Schristos     }
7814e98e3e1Schristos }
7824e98e3e1Schristos 
7834e98e3e1Schristos int
7844e98e3e1Schristos sim_stop (SIM_DESC sd)
7854e98e3e1Schristos {
7864e98e3e1Schristos   stop = 1;
7874e98e3e1Schristos 
7884e98e3e1Schristos   return 1;
7894e98e3e1Schristos }
7904e98e3e1Schristos 
7914e98e3e1Schristos void
7924e98e3e1Schristos sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p)
7934e98e3e1Schristos {
7944e98e3e1Schristos   check_desc (sd);
7954e98e3e1Schristos 
7964e98e3e1Schristos   *reason_p = reason;
7974e98e3e1Schristos   *sigrc_p = siggnal;
7984e98e3e1Schristos }
7994e98e3e1Schristos 
8004e98e3e1Schristos void
801837edd6bSchristos sim_do_command (SIM_DESC sd, const char *cmd)
8024e98e3e1Schristos {
8034b169a6bSchristos   const char *arg;
8044b169a6bSchristos   char **argv = buildargv (cmd);
8054e98e3e1Schristos 
806837edd6bSchristos   check_desc (sd);
8074e98e3e1Schristos 
8084b169a6bSchristos   cmd = arg = "";
8094b169a6bSchristos   if (argv != NULL)
8104e98e3e1Schristos     {
8114b169a6bSchristos       if (argv[0] != NULL)
8124b169a6bSchristos 	cmd = argv[0];
8134b169a6bSchristos       if (argv[1] != NULL)
8144b169a6bSchristos 	arg = argv[1];
8154e98e3e1Schristos     }
8164e98e3e1Schristos 
8174e98e3e1Schristos   if (strcmp (cmd, "trace") == 0)
8184e98e3e1Schristos     {
8194b169a6bSchristos       if (strcmp (arg, "on") == 0)
8204e98e3e1Schristos 	trace = 1;
8214b169a6bSchristos       else if (strcmp (arg, "off") == 0)
8224e98e3e1Schristos 	trace = 0;
8234e98e3e1Schristos       else
8244e98e3e1Schristos 	printf ("The 'sim trace' command expects 'on' or 'off' "
8254e98e3e1Schristos 		"as an argument.\n");
8264e98e3e1Schristos     }
8274e98e3e1Schristos   else if (strcmp (cmd, "verbose") == 0)
8284e98e3e1Schristos     {
8294b169a6bSchristos       if (strcmp (arg, "on") == 0)
8304e98e3e1Schristos 	verbose = 1;
8314b169a6bSchristos       else if (strcmp (arg, "noisy") == 0)
8324e98e3e1Schristos 	verbose = 2;
8334b169a6bSchristos       else if (strcmp (arg, "off") == 0)
8344e98e3e1Schristos 	verbose = 0;
8354e98e3e1Schristos       else
8364e98e3e1Schristos 	printf ("The 'sim verbose' command expects 'on', 'noisy', or 'off'"
8374e98e3e1Schristos 		" as an argument.\n");
8384e98e3e1Schristos     }
8394e98e3e1Schristos   else
8404e98e3e1Schristos     printf ("The 'sim' command expects either 'trace' or 'verbose'"
8414e98e3e1Schristos 	    " as a subcommand.\n");
842837edd6bSchristos 
8434b169a6bSchristos   freeargv (argv);
8444e98e3e1Schristos }
845a2e2270fSchristos 
846a2e2270fSchristos char **
84703467a24Schristos sim_complete_command (SIM_DESC sd, const char *text, const char *word)
848a2e2270fSchristos {
849a2e2270fSchristos   return NULL;
850a2e2270fSchristos }
8514b169a6bSchristos 
8524b169a6bSchristos /* Stub this out for now.  */
8534b169a6bSchristos 
8544b169a6bSchristos char *
8554b169a6bSchristos sim_memory_map (SIM_DESC sd)
8564b169a6bSchristos {
8574b169a6bSchristos   return NULL;
8584b169a6bSchristos }
859