xref: /netbsd-src/external/gpl3/gdb/dist/sim/m32c/gdb-if.c (revision 71f621822dbfd5073a314948bec169b7bb05f7be)
14e98e3e1Schristos /* gdb.c --- sim interface to GDB.
24e98e3e1Schristos 
3*71f62182Schristos Copyright (C) 2005-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>
27212397c6Schristos #include <stdlib.h>
284e98e3e1Schristos #include <string.h>
294e98e3e1Schristos #include <ctype.h>
304e98e3e1Schristos 
314e98e3e1Schristos #include "ansidecl.h"
324b169a6bSchristos #include "libiberty.h"
334b169a6bSchristos #include "sim/callback.h"
344b169a6bSchristos #include "sim/sim.h"
354e98e3e1Schristos #include "gdb/signals.h"
36*71f62182Schristos #include "sim/sim-m32c.h"
374e98e3e1Schristos 
384e98e3e1Schristos #include "cpu.h"
394e98e3e1Schristos #include "mem.h"
404e98e3e1Schristos #include "load.h"
414e98e3e1Schristos #include "syscalls.h"
424e98e3e1Schristos #ifdef TIMER_A
434e98e3e1Schristos #include "timer_a.h"
444e98e3e1Schristos #endif
454e98e3e1Schristos 
464e98e3e1Schristos /* I don't want to wrap up all the minisim's data structures in an
474e98e3e1Schristos    object and pass that around.  That'd be a big change, and neither
484e98e3e1Schristos    GDB nor run needs 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 m32c minisim instance.  See libsim.a's global variables."
594e98e3e1Schristos };
604e98e3e1Schristos 
614b169a6bSchristos static int 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 {
684e98e3e1Schristos   setbuf (stdout, 0);
694b169a6bSchristos   if (is_open)
704e98e3e1Schristos     fprintf (stderr, "m32c minisim: re-opened sim\n");
714e98e3e1Schristos 
724e98e3e1Schristos   /* The 'run' interface doesn't use this function, so we don't care
734e98e3e1Schristos      about KIND; it's always SIM_OPEN_DEBUG.  */
744e98e3e1Schristos   if (kind != SIM_OPEN_DEBUG)
754e98e3e1Schristos     fprintf (stderr, "m32c minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
764e98e3e1Schristos 	     kind);
774e98e3e1Schristos 
784e98e3e1Schristos   if (abfd)
794e98e3e1Schristos     m32c_set_mach (bfd_get_mach (abfd));
804e98e3e1Schristos 
814e98e3e1Schristos   /* We can use ABFD, if non-NULL to select the appropriate
824e98e3e1Schristos      architecture.  But we only support the r8c right now.  */
834e98e3e1Schristos 
844e98e3e1Schristos   set_callbacks (callback);
854e98e3e1Schristos 
864e98e3e1Schristos   /* We don't expect any command-line arguments.  */
874e98e3e1Schristos 
884e98e3e1Schristos   init_mem ();
894e98e3e1Schristos   init_regs ();
904e98e3e1Schristos 
914b169a6bSchristos   is_open = 1;
924e98e3e1Schristos   return &the_minisim;
934e98e3e1Schristos }
944e98e3e1Schristos 
954e98e3e1Schristos static void
964e98e3e1Schristos check_desc (SIM_DESC sd)
974e98e3e1Schristos {
984e98e3e1Schristos   if (sd != &the_minisim)
994e98e3e1Schristos     fprintf (stderr, "m32c minisim: desc != &the_minisim\n");
1004e98e3e1Schristos }
1014e98e3e1Schristos 
1024e98e3e1Schristos void
1034e98e3e1Schristos sim_close (SIM_DESC sd, int quitting)
1044e98e3e1Schristos {
1054e98e3e1Schristos   check_desc (sd);
1064e98e3e1Schristos 
1074e98e3e1Schristos   /* Not much to do.  At least free up our memory.  */
1084e98e3e1Schristos   init_mem ();
1094e98e3e1Schristos 
1104b169a6bSchristos   is_open = 0;
1114e98e3e1Schristos }
1124e98e3e1Schristos 
1134e98e3e1Schristos static bfd *
1144e98e3e1Schristos open_objfile (const char *filename)
1154e98e3e1Schristos {
1164e98e3e1Schristos   bfd *prog = bfd_openr (filename, 0);
1174e98e3e1Schristos 
1184e98e3e1Schristos   if (!prog)
1194e98e3e1Schristos     {
1204e98e3e1Schristos       fprintf (stderr, "Can't read %s\n", filename);
1214e98e3e1Schristos       return 0;
1224e98e3e1Schristos     }
1234e98e3e1Schristos 
1244e98e3e1Schristos   if (!bfd_check_format (prog, bfd_object))
1254e98e3e1Schristos     {
1264e98e3e1Schristos       fprintf (stderr, "%s not a m32c program\n", filename);
1274e98e3e1Schristos       return 0;
1284e98e3e1Schristos     }
1294e98e3e1Schristos 
1304e98e3e1Schristos   return prog;
1314e98e3e1Schristos }
1324e98e3e1Schristos 
1334e98e3e1Schristos 
1344e98e3e1Schristos SIM_RC
135b23b2582Schristos sim_load (SIM_DESC sd, const char *prog, struct bfd * abfd, int from_tty)
1364e98e3e1Schristos {
1374e98e3e1Schristos   check_desc (sd);
1384e98e3e1Schristos 
1394e98e3e1Schristos   if (!abfd)
1404e98e3e1Schristos     abfd = open_objfile (prog);
1414e98e3e1Schristos   if (!abfd)
1424e98e3e1Schristos     return SIM_RC_FAIL;
1434e98e3e1Schristos 
1444e98e3e1Schristos   m32c_load (abfd);
1454e98e3e1Schristos 
1464e98e3e1Schristos   return SIM_RC_OK;
1474e98e3e1Schristos }
1484e98e3e1Schristos 
1494e98e3e1Schristos SIM_RC
150ba340e45Schristos sim_create_inferior (SIM_DESC sd, struct bfd * abfd,
151ba340e45Schristos 		     char * const *argv, char * const *env)
1524e98e3e1Schristos {
1534e98e3e1Schristos   check_desc (sd);
1544e98e3e1Schristos 
1554e98e3e1Schristos   if (abfd)
1564e98e3e1Schristos     m32c_load (abfd);
1574e98e3e1Schristos 
1584e98e3e1Schristos   return SIM_RC_OK;
1594e98e3e1Schristos }
1604e98e3e1Schristos 
161*71f62182Schristos uint64_t
162*71f62182Schristos sim_read (SIM_DESC sd, uint64_t addr, void *buf, uint64_t length)
1634e98e3e1Schristos {
1644e98e3e1Schristos   check_desc (sd);
1654e98e3e1Schristos 
166*71f62182Schristos   if (addr == 0)
1674e98e3e1Schristos     return 0;
1684e98e3e1Schristos 
169*71f62182Schristos   mem_get_blk ((int) addr, buf, length);
1704e98e3e1Schristos 
1714e98e3e1Schristos   return length;
1724e98e3e1Schristos }
1734e98e3e1Schristos 
174*71f62182Schristos uint64_t
175*71f62182Schristos sim_write (SIM_DESC sd, uint64_t addr, const void *buf, uint64_t length)
1764e98e3e1Schristos {
1774e98e3e1Schristos   check_desc (sd);
1784e98e3e1Schristos 
179*71f62182Schristos   mem_put_blk ((int) addr, buf, length);
1804e98e3e1Schristos 
1814e98e3e1Schristos   return length;
1824e98e3e1Schristos }
1834e98e3e1Schristos 
1844e98e3e1Schristos 
1854e98e3e1Schristos /* Read the LENGTH bytes at BUF as an little-endian value.  */
1864e98e3e1Schristos static DI
1874b169a6bSchristos get_le (const unsigned char *buf, int length)
1884e98e3e1Schristos {
1894e98e3e1Schristos   DI acc = 0;
1904e98e3e1Schristos   while (--length >= 0)
1914e98e3e1Schristos     acc = (acc << 8) + buf[length];
1924e98e3e1Schristos 
1934e98e3e1Schristos   return acc;
1944e98e3e1Schristos }
1954e98e3e1Schristos 
1964e98e3e1Schristos /* Store VAL as a little-endian value in the LENGTH bytes at BUF.  */
1974e98e3e1Schristos static void
1984e98e3e1Schristos put_le (unsigned char *buf, int length, DI val)
1994e98e3e1Schristos {
2004e98e3e1Schristos   int i;
2014e98e3e1Schristos 
2024e98e3e1Schristos   for (i = 0; i < length; i++)
2034e98e3e1Schristos     {
2044e98e3e1Schristos       buf[i] = val & 0xff;
2054e98e3e1Schristos       val >>= 8;
2064e98e3e1Schristos     }
2074e98e3e1Schristos }
2084e98e3e1Schristos 
2094e98e3e1Schristos static int
2104e98e3e1Schristos check_regno (enum m32c_sim_reg regno)
2114e98e3e1Schristos {
2124e98e3e1Schristos   return 0 <= regno && regno < m32c_sim_reg_num_regs;
2134e98e3e1Schristos }
2144e98e3e1Schristos 
2154e98e3e1Schristos static size_t
2164e98e3e1Schristos mask_size (int addr_mask)
2174e98e3e1Schristos {
2184e98e3e1Schristos   switch (addr_mask)
2194e98e3e1Schristos     {
2204e98e3e1Schristos     case 0xffff:
2214e98e3e1Schristos       return 2;
2224e98e3e1Schristos     case 0xfffff:
2234e98e3e1Schristos     case 0xffffff:
2244e98e3e1Schristos       return 3;
2254e98e3e1Schristos     default:
2264e98e3e1Schristos       fprintf (stderr,
2274e98e3e1Schristos 	       "m32c minisim: addr_mask_size: unexpected mask 0x%x\n",
2284e98e3e1Schristos 	       addr_mask);
2294e98e3e1Schristos       return sizeof (addr_mask);
2304e98e3e1Schristos     }
2314e98e3e1Schristos }
2324e98e3e1Schristos 
2334e98e3e1Schristos static size_t
2344e98e3e1Schristos reg_size (enum m32c_sim_reg regno)
2354e98e3e1Schristos {
2364e98e3e1Schristos   switch (regno)
2374e98e3e1Schristos     {
2384e98e3e1Schristos     case m32c_sim_reg_r0_bank0:
2394e98e3e1Schristos     case m32c_sim_reg_r1_bank0:
2404e98e3e1Schristos     case m32c_sim_reg_r2_bank0:
2414e98e3e1Schristos     case m32c_sim_reg_r3_bank0:
2424e98e3e1Schristos     case m32c_sim_reg_r0_bank1:
2434e98e3e1Schristos     case m32c_sim_reg_r1_bank1:
2444e98e3e1Schristos     case m32c_sim_reg_r2_bank1:
2454e98e3e1Schristos     case m32c_sim_reg_r3_bank1:
2464e98e3e1Schristos     case m32c_sim_reg_flg:
2474e98e3e1Schristos     case m32c_sim_reg_svf:
2484e98e3e1Schristos       return 2;
2494e98e3e1Schristos 
2504e98e3e1Schristos     case m32c_sim_reg_a0_bank0:
2514e98e3e1Schristos     case m32c_sim_reg_a1_bank0:
2524e98e3e1Schristos     case m32c_sim_reg_fb_bank0:
2534e98e3e1Schristos     case m32c_sim_reg_sb_bank0:
2544e98e3e1Schristos     case m32c_sim_reg_a0_bank1:
2554e98e3e1Schristos     case m32c_sim_reg_a1_bank1:
2564e98e3e1Schristos     case m32c_sim_reg_fb_bank1:
2574e98e3e1Schristos     case m32c_sim_reg_sb_bank1:
2584e98e3e1Schristos     case m32c_sim_reg_usp:
2594e98e3e1Schristos     case m32c_sim_reg_isp:
2604e98e3e1Schristos       return mask_size (addr_mask);
2614e98e3e1Schristos 
2624e98e3e1Schristos     case m32c_sim_reg_pc:
2634e98e3e1Schristos     case m32c_sim_reg_intb:
2644e98e3e1Schristos     case m32c_sim_reg_svp:
2654e98e3e1Schristos     case m32c_sim_reg_vct:
2664e98e3e1Schristos       return mask_size (membus_mask);
2674e98e3e1Schristos 
2684e98e3e1Schristos     case m32c_sim_reg_dmd0:
2694e98e3e1Schristos     case m32c_sim_reg_dmd1:
2704e98e3e1Schristos       return 1;
2714e98e3e1Schristos 
2724e98e3e1Schristos     case m32c_sim_reg_dct0:
2734e98e3e1Schristos     case m32c_sim_reg_dct1:
2744e98e3e1Schristos     case m32c_sim_reg_drc0:
2754e98e3e1Schristos     case m32c_sim_reg_drc1:
2764e98e3e1Schristos       return 2;
2774e98e3e1Schristos 
2784e98e3e1Schristos     case m32c_sim_reg_dma0:
2794e98e3e1Schristos     case m32c_sim_reg_dma1:
2804e98e3e1Schristos     case m32c_sim_reg_dsa0:
2814e98e3e1Schristos     case m32c_sim_reg_dsa1:
2824e98e3e1Schristos     case m32c_sim_reg_dra0:
2834e98e3e1Schristos     case m32c_sim_reg_dra1:
2844e98e3e1Schristos       return 3;
2854e98e3e1Schristos 
2864e98e3e1Schristos     default:
2874e98e3e1Schristos       fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
2884e98e3e1Schristos 	       regno);
2894e98e3e1Schristos       return -1;
2904e98e3e1Schristos     }
2914e98e3e1Schristos }
2924e98e3e1Schristos 
2934e98e3e1Schristos int
2944b169a6bSchristos sim_fetch_register (SIM_DESC sd, int regno, void *buf, int length)
2954e98e3e1Schristos {
2964e98e3e1Schristos   size_t size;
2974e98e3e1Schristos 
2984e98e3e1Schristos   check_desc (sd);
2994e98e3e1Schristos 
3004e98e3e1Schristos   if (!check_regno (regno))
3014e98e3e1Schristos     return 0;
3024e98e3e1Schristos 
3034e98e3e1Schristos   size = reg_size (regno);
3044e98e3e1Schristos   if (length == size)
3054e98e3e1Schristos     {
3064e98e3e1Schristos       DI val;
3074e98e3e1Schristos 
3084e98e3e1Schristos       switch (regno)
3094e98e3e1Schristos 	{
3104e98e3e1Schristos 	case m32c_sim_reg_r0_bank0:
3114e98e3e1Schristos 	  val = regs.r[0].r_r0;
3124e98e3e1Schristos 	  break;
3134e98e3e1Schristos 	case m32c_sim_reg_r1_bank0:
3144e98e3e1Schristos 	  val = regs.r[0].r_r1;
3154e98e3e1Schristos 	  break;
3164e98e3e1Schristos 	case m32c_sim_reg_r2_bank0:
3174e98e3e1Schristos 	  val = regs.r[0].r_r2;
3184e98e3e1Schristos 	  break;
3194e98e3e1Schristos 	case m32c_sim_reg_r3_bank0:
3204e98e3e1Schristos 	  val = regs.r[0].r_r3;
3214e98e3e1Schristos 	  break;
3224e98e3e1Schristos 	case m32c_sim_reg_a0_bank0:
3234e98e3e1Schristos 	  val = regs.r[0].r_a0;
3244e98e3e1Schristos 	  break;
3254e98e3e1Schristos 	case m32c_sim_reg_a1_bank0:
3264e98e3e1Schristos 	  val = regs.r[0].r_a1;
3274e98e3e1Schristos 	  break;
3284e98e3e1Schristos 	case m32c_sim_reg_fb_bank0:
3294e98e3e1Schristos 	  val = regs.r[0].r_fb;
3304e98e3e1Schristos 	  break;
3314e98e3e1Schristos 	case m32c_sim_reg_sb_bank0:
3324e98e3e1Schristos 	  val = regs.r[0].r_sb;
3334e98e3e1Schristos 	  break;
3344e98e3e1Schristos 	case m32c_sim_reg_r0_bank1:
3354e98e3e1Schristos 	  val = regs.r[1].r_r0;
3364e98e3e1Schristos 	  break;
3374e98e3e1Schristos 	case m32c_sim_reg_r1_bank1:
3384e98e3e1Schristos 	  val = regs.r[1].r_r1;
3394e98e3e1Schristos 	  break;
3404e98e3e1Schristos 	case m32c_sim_reg_r2_bank1:
3414e98e3e1Schristos 	  val = regs.r[1].r_r2;
3424e98e3e1Schristos 	  break;
3434e98e3e1Schristos 	case m32c_sim_reg_r3_bank1:
3444e98e3e1Schristos 	  val = regs.r[1].r_r3;
3454e98e3e1Schristos 	  break;
3464e98e3e1Schristos 	case m32c_sim_reg_a0_bank1:
3474e98e3e1Schristos 	  val = regs.r[1].r_a0;
3484e98e3e1Schristos 	  break;
3494e98e3e1Schristos 	case m32c_sim_reg_a1_bank1:
3504e98e3e1Schristos 	  val = regs.r[1].r_a1;
3514e98e3e1Schristos 	  break;
3524e98e3e1Schristos 	case m32c_sim_reg_fb_bank1:
3534e98e3e1Schristos 	  val = regs.r[1].r_fb;
3544e98e3e1Schristos 	  break;
3554e98e3e1Schristos 	case m32c_sim_reg_sb_bank1:
3564e98e3e1Schristos 	  val = regs.r[1].r_sb;
3574e98e3e1Schristos 	  break;
3584e98e3e1Schristos 
3594e98e3e1Schristos 	case m32c_sim_reg_usp:
3604e98e3e1Schristos 	  val = regs.r_usp;
3614e98e3e1Schristos 	  break;
3624e98e3e1Schristos 	case m32c_sim_reg_isp:
3634e98e3e1Schristos 	  val = regs.r_isp;
3644e98e3e1Schristos 	  break;
3654e98e3e1Schristos 	case m32c_sim_reg_pc:
3664e98e3e1Schristos 	  val = regs.r_pc;
3674e98e3e1Schristos 	  break;
3684e98e3e1Schristos 	case m32c_sim_reg_intb:
3694e98e3e1Schristos 	  val = regs.r_intbl * 65536 + regs.r_intbl;
3704e98e3e1Schristos 	  break;
3714e98e3e1Schristos 	case m32c_sim_reg_flg:
3724e98e3e1Schristos 	  val = regs.r_flags;
3734e98e3e1Schristos 	  break;
3744e98e3e1Schristos 
3754e98e3e1Schristos 	  /* These registers aren't implemented by the minisim.  */
3764e98e3e1Schristos 	case m32c_sim_reg_svf:
3774e98e3e1Schristos 	case m32c_sim_reg_svp:
3784e98e3e1Schristos 	case m32c_sim_reg_vct:
3794e98e3e1Schristos 	case m32c_sim_reg_dmd0:
3804e98e3e1Schristos 	case m32c_sim_reg_dmd1:
3814e98e3e1Schristos 	case m32c_sim_reg_dct0:
3824e98e3e1Schristos 	case m32c_sim_reg_dct1:
3834e98e3e1Schristos 	case m32c_sim_reg_drc0:
3844e98e3e1Schristos 	case m32c_sim_reg_drc1:
3854e98e3e1Schristos 	case m32c_sim_reg_dma0:
3864e98e3e1Schristos 	case m32c_sim_reg_dma1:
3874e98e3e1Schristos 	case m32c_sim_reg_dsa0:
3884e98e3e1Schristos 	case m32c_sim_reg_dsa1:
3894e98e3e1Schristos 	case m32c_sim_reg_dra0:
3904e98e3e1Schristos 	case m32c_sim_reg_dra1:
3914e98e3e1Schristos 	  return 0;
3924e98e3e1Schristos 
3934e98e3e1Schristos 	default:
3944e98e3e1Schristos 	  fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
3954e98e3e1Schristos 		   regno);
3964e98e3e1Schristos 	  return -1;
3974e98e3e1Schristos 	}
3984e98e3e1Schristos 
3994e98e3e1Schristos       put_le (buf, length, val);
4004e98e3e1Schristos     }
4014e98e3e1Schristos 
4024e98e3e1Schristos   return size;
4034e98e3e1Schristos }
4044e98e3e1Schristos 
4054e98e3e1Schristos int
4064b169a6bSchristos sim_store_register (SIM_DESC sd, int regno, const void *buf, int length)
4074e98e3e1Schristos {
4084e98e3e1Schristos   size_t size;
4094e98e3e1Schristos 
4104e98e3e1Schristos   check_desc (sd);
4114e98e3e1Schristos 
4124e98e3e1Schristos   if (!check_regno (regno))
4134e98e3e1Schristos     return -1;
4144e98e3e1Schristos 
4154e98e3e1Schristos   size = reg_size (regno);
4164e98e3e1Schristos 
4174e98e3e1Schristos   if (length == size)
4184e98e3e1Schristos     {
4194e98e3e1Schristos       DI val = get_le (buf, length);
4204e98e3e1Schristos 
4214e98e3e1Schristos       switch (regno)
4224e98e3e1Schristos 	{
4234e98e3e1Schristos 	case m32c_sim_reg_r0_bank0:
4244e98e3e1Schristos 	  regs.r[0].r_r0 = val & 0xffff;
4254e98e3e1Schristos 	  break;
4264e98e3e1Schristos 	case m32c_sim_reg_r1_bank0:
4274e98e3e1Schristos 	  regs.r[0].r_r1 = val & 0xffff;
4284e98e3e1Schristos 	  break;
4294e98e3e1Schristos 	case m32c_sim_reg_r2_bank0:
4304e98e3e1Schristos 	  regs.r[0].r_r2 = val & 0xffff;
4314e98e3e1Schristos 	  break;
4324e98e3e1Schristos 	case m32c_sim_reg_r3_bank0:
4334e98e3e1Schristos 	  regs.r[0].r_r3 = val & 0xffff;
4344e98e3e1Schristos 	  break;
4354e98e3e1Schristos 	case m32c_sim_reg_a0_bank0:
4364e98e3e1Schristos 	  regs.r[0].r_a0 = val & addr_mask;
4374e98e3e1Schristos 	  break;
4384e98e3e1Schristos 	case m32c_sim_reg_a1_bank0:
4394e98e3e1Schristos 	  regs.r[0].r_a1 = val & addr_mask;
4404e98e3e1Schristos 	  break;
4414e98e3e1Schristos 	case m32c_sim_reg_fb_bank0:
4424e98e3e1Schristos 	  regs.r[0].r_fb = val & addr_mask;
4434e98e3e1Schristos 	  break;
4444e98e3e1Schristos 	case m32c_sim_reg_sb_bank0:
4454e98e3e1Schristos 	  regs.r[0].r_sb = val & addr_mask;
4464e98e3e1Schristos 	  break;
4474e98e3e1Schristos 	case m32c_sim_reg_r0_bank1:
4484e98e3e1Schristos 	  regs.r[1].r_r0 = val & 0xffff;
4494e98e3e1Schristos 	  break;
4504e98e3e1Schristos 	case m32c_sim_reg_r1_bank1:
4514e98e3e1Schristos 	  regs.r[1].r_r1 = val & 0xffff;
4524e98e3e1Schristos 	  break;
4534e98e3e1Schristos 	case m32c_sim_reg_r2_bank1:
4544e98e3e1Schristos 	  regs.r[1].r_r2 = val & 0xffff;
4554e98e3e1Schristos 	  break;
4564e98e3e1Schristos 	case m32c_sim_reg_r3_bank1:
4574e98e3e1Schristos 	  regs.r[1].r_r3 = val & 0xffff;
4584e98e3e1Schristos 	  break;
4594e98e3e1Schristos 	case m32c_sim_reg_a0_bank1:
4604e98e3e1Schristos 	  regs.r[1].r_a0 = val & addr_mask;
4614e98e3e1Schristos 	  break;
4624e98e3e1Schristos 	case m32c_sim_reg_a1_bank1:
4634e98e3e1Schristos 	  regs.r[1].r_a1 = val & addr_mask;
4644e98e3e1Schristos 	  break;
4654e98e3e1Schristos 	case m32c_sim_reg_fb_bank1:
4664e98e3e1Schristos 	  regs.r[1].r_fb = val & addr_mask;
4674e98e3e1Schristos 	  break;
4684e98e3e1Schristos 	case m32c_sim_reg_sb_bank1:
4694e98e3e1Schristos 	  regs.r[1].r_sb = val & addr_mask;
4704e98e3e1Schristos 	  break;
4714e98e3e1Schristos 
4724e98e3e1Schristos 	case m32c_sim_reg_usp:
4734e98e3e1Schristos 	  regs.r_usp = val & addr_mask;
4744e98e3e1Schristos 	  break;
4754e98e3e1Schristos 	case m32c_sim_reg_isp:
4764e98e3e1Schristos 	  regs.r_isp = val & addr_mask;
4774e98e3e1Schristos 	  break;
4784e98e3e1Schristos 	case m32c_sim_reg_pc:
4794e98e3e1Schristos 	  regs.r_pc = val & membus_mask;
4804e98e3e1Schristos 	  break;
4814e98e3e1Schristos 	case m32c_sim_reg_intb:
4824e98e3e1Schristos 	  regs.r_intbl = (val & membus_mask) & 0xffff;
4834e98e3e1Schristos 	  regs.r_intbh = (val & membus_mask) >> 16;
4844e98e3e1Schristos 	  break;
4854e98e3e1Schristos 	case m32c_sim_reg_flg:
4864e98e3e1Schristos 	  regs.r_flags = val & 0xffff;
4874e98e3e1Schristos 	  break;
4884e98e3e1Schristos 
4894e98e3e1Schristos 	  /* These registers aren't implemented by the minisim.  */
4904e98e3e1Schristos 	case m32c_sim_reg_svf:
4914e98e3e1Schristos 	case m32c_sim_reg_svp:
4924e98e3e1Schristos 	case m32c_sim_reg_vct:
4934e98e3e1Schristos 	case m32c_sim_reg_dmd0:
4944e98e3e1Schristos 	case m32c_sim_reg_dmd1:
4954e98e3e1Schristos 	case m32c_sim_reg_dct0:
4964e98e3e1Schristos 	case m32c_sim_reg_dct1:
4974e98e3e1Schristos 	case m32c_sim_reg_drc0:
4984e98e3e1Schristos 	case m32c_sim_reg_drc1:
4994e98e3e1Schristos 	case m32c_sim_reg_dma0:
5004e98e3e1Schristos 	case m32c_sim_reg_dma1:
5014e98e3e1Schristos 	case m32c_sim_reg_dsa0:
5024e98e3e1Schristos 	case m32c_sim_reg_dsa1:
5034e98e3e1Schristos 	case m32c_sim_reg_dra0:
5044e98e3e1Schristos 	case m32c_sim_reg_dra1:
5054e98e3e1Schristos 	  return 0;
5064e98e3e1Schristos 
5074e98e3e1Schristos 	default:
5084e98e3e1Schristos 	  fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
5094e98e3e1Schristos 		   regno);
5104e98e3e1Schristos 	  return 0;
5114e98e3e1Schristos 	}
5124e98e3e1Schristos     }
5134e98e3e1Schristos 
5144e98e3e1Schristos   return size;
5154e98e3e1Schristos }
5164e98e3e1Schristos 
5174e98e3e1Schristos static volatile int stop;
5184e98e3e1Schristos static enum sim_stop reason;
519212397c6Schristos static int siggnal;
5204e98e3e1Schristos 
5214e98e3e1Schristos 
5224e98e3e1Schristos /* Given a signal number used by the M32C bsp (that is, newlib),
5234e98e3e1Schristos    return a target signal number used by GDB.  */
524212397c6Schristos static int
5254e98e3e1Schristos m32c_signal_to_target (int m32c)
5264e98e3e1Schristos {
5274e98e3e1Schristos   switch (m32c)
5284e98e3e1Schristos     {
5294e98e3e1Schristos     case 4:
530a2e2270fSchristos       return GDB_SIGNAL_ILL;
5314e98e3e1Schristos 
5324e98e3e1Schristos     case 5:
533a2e2270fSchristos       return GDB_SIGNAL_TRAP;
5344e98e3e1Schristos 
5354e98e3e1Schristos     case 10:
536a2e2270fSchristos       return GDB_SIGNAL_BUS;
5374e98e3e1Schristos 
5384e98e3e1Schristos     case 11:
539a2e2270fSchristos       return GDB_SIGNAL_SEGV;
5404e98e3e1Schristos 
5414e98e3e1Schristos     case 24:
542a2e2270fSchristos       return GDB_SIGNAL_XCPU;
5434e98e3e1Schristos 
5444e98e3e1Schristos     case 2:
545a2e2270fSchristos       return GDB_SIGNAL_INT;
5464e98e3e1Schristos 
5474e98e3e1Schristos     case 8:
548a2e2270fSchristos       return GDB_SIGNAL_FPE;
5494e98e3e1Schristos 
5504e98e3e1Schristos     case 6:
551a2e2270fSchristos       return GDB_SIGNAL_ABRT;
5524e98e3e1Schristos     }
5534e98e3e1Schristos 
5544e98e3e1Schristos   return 0;
5554e98e3e1Schristos }
5564e98e3e1Schristos 
5574e98e3e1Schristos 
5584e98e3e1Schristos /* Take a step return code RC and set up the variables consulted by
5594e98e3e1Schristos    sim_stop_reason appropriately.  */
560212397c6Schristos static void
5614e98e3e1Schristos handle_step (int rc)
5624e98e3e1Schristos {
5634e98e3e1Schristos   if (M32C_STEPPED (rc) || M32C_HIT_BREAK (rc))
5644e98e3e1Schristos     {
5654e98e3e1Schristos       reason = sim_stopped;
566a2e2270fSchristos       siggnal = GDB_SIGNAL_TRAP;
5674e98e3e1Schristos     }
5684e98e3e1Schristos   else if (M32C_STOPPED (rc))
5694e98e3e1Schristos     {
5704e98e3e1Schristos       reason = sim_stopped;
5714e98e3e1Schristos       siggnal = m32c_signal_to_target (M32C_STOP_SIG (rc));
5724e98e3e1Schristos     }
5734e98e3e1Schristos   else
5744e98e3e1Schristos     {
5754e98e3e1Schristos       assert (M32C_EXITED (rc));
5764e98e3e1Schristos       reason = sim_exited;
5774e98e3e1Schristos       siggnal = M32C_EXIT_STATUS (rc);
5784e98e3e1Schristos     }
5794e98e3e1Schristos }
5804e98e3e1Schristos 
5814e98e3e1Schristos 
5824e98e3e1Schristos void
5834e98e3e1Schristos sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
5844e98e3e1Schristos {
5854e98e3e1Schristos   check_desc (sd);
5864e98e3e1Schristos 
5874e98e3e1Schristos   if (sig_to_deliver != 0)
5884e98e3e1Schristos     {
5894e98e3e1Schristos       fprintf (stderr,
5904e98e3e1Schristos 	       "Warning: the m32c minisim does not implement "
5914e98e3e1Schristos 	       "signal delivery yet.\n" "Resuming with no signal.\n");
5924e98e3e1Schristos     }
5934e98e3e1Schristos 
5944e98e3e1Schristos   if (step)
5954e98e3e1Schristos     {
5964e98e3e1Schristos       handle_step (decode_opcode ());
5974e98e3e1Schristos #ifdef TIMER_A
5984e98e3e1Schristos       update_timer_a ();
5994e98e3e1Schristos #endif
6004e98e3e1Schristos     }
6014e98e3e1Schristos   else
6024e98e3e1Schristos     {
6034e98e3e1Schristos       /* We don't clear 'stop' here, because then we would miss
6044e98e3e1Schristos          interrupts that arrived on the way here.  Instead, we clear
6054e98e3e1Schristos          the flag in sim_stop_reason, after GDB has disabled the
6064e98e3e1Schristos          interrupt signal handler.  */
6074e98e3e1Schristos       for (;;)
6084e98e3e1Schristos 	{
609212397c6Schristos 	  int rc;
610212397c6Schristos 
6114e98e3e1Schristos 	  if (stop)
6124e98e3e1Schristos 	    {
6134e98e3e1Schristos 	      stop = 0;
6144e98e3e1Schristos 	      reason = sim_stopped;
615a2e2270fSchristos 	      siggnal = GDB_SIGNAL_INT;
6164e98e3e1Schristos 	      break;
6174e98e3e1Schristos 	    }
6184e98e3e1Schristos 
619212397c6Schristos 	  rc = decode_opcode ();
6204e98e3e1Schristos #ifdef TIMER_A
6214e98e3e1Schristos 	  update_timer_a ();
6224e98e3e1Schristos #endif
6234e98e3e1Schristos 
6244e98e3e1Schristos 	  if (!M32C_STEPPED (rc))
6254e98e3e1Schristos 	    {
6264e98e3e1Schristos 	      handle_step (rc);
6274e98e3e1Schristos 	      break;
6284e98e3e1Schristos 	    }
6294e98e3e1Schristos 	}
6304e98e3e1Schristos     }
6314e98e3e1Schristos   m32c_sim_restore_console ();
6324e98e3e1Schristos }
6334e98e3e1Schristos 
6344e98e3e1Schristos int
6354e98e3e1Schristos sim_stop (SIM_DESC sd)
6364e98e3e1Schristos {
6374e98e3e1Schristos   stop = 1;
6384e98e3e1Schristos 
6394e98e3e1Schristos   return 1;
6404e98e3e1Schristos }
6414e98e3e1Schristos 
6424e98e3e1Schristos void
6434e98e3e1Schristos sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p)
6444e98e3e1Schristos {
6454e98e3e1Schristos   check_desc (sd);
6464e98e3e1Schristos 
6474e98e3e1Schristos   *reason_p = reason;
6484e98e3e1Schristos   *sigrc_p = siggnal;
6494e98e3e1Schristos }
6504e98e3e1Schristos 
6514e98e3e1Schristos void
652b23b2582Schristos sim_do_command (SIM_DESC sd, const char *cmd)
6534e98e3e1Schristos {
6544b169a6bSchristos   const char *arg;
6554b169a6bSchristos   char **argv = buildargv (cmd);
6564e98e3e1Schristos 
657b23b2582Schristos   check_desc (sd);
6584e98e3e1Schristos 
6594b169a6bSchristos   cmd = arg = "";
6604b169a6bSchristos   if (argv != NULL)
6614e98e3e1Schristos     {
6624b169a6bSchristos       if (argv[0] != NULL)
6634b169a6bSchristos 	cmd = argv[0];
6644b169a6bSchristos       if (argv[1] != NULL)
6654b169a6bSchristos 	arg = argv[1];
6664e98e3e1Schristos     }
6674e98e3e1Schristos 
6684e98e3e1Schristos   if (strcmp (cmd, "trace") == 0)
6694e98e3e1Schristos     {
6704b169a6bSchristos       if (strcmp (arg, "on") == 0)
6714e98e3e1Schristos 	trace = 1;
6724b169a6bSchristos       else if (strcmp (arg, "off") == 0)
6734e98e3e1Schristos 	trace = 0;
6744e98e3e1Schristos       else
6754e98e3e1Schristos 	printf ("The 'sim trace' command expects 'on' or 'off' "
6764e98e3e1Schristos 		"as an argument.\n");
6774e98e3e1Schristos     }
6784e98e3e1Schristos   else if (strcmp (cmd, "verbose") == 0)
6794e98e3e1Schristos     {
6804b169a6bSchristos       if (strcmp (arg, "on") == 0)
6814e98e3e1Schristos 	verbose = 1;
6824b169a6bSchristos       else if (strcmp (arg, "off") == 0)
6834e98e3e1Schristos 	verbose = 0;
6844e98e3e1Schristos       else
6854e98e3e1Schristos 	printf ("The 'sim verbose' command expects 'on' or 'off'"
6864e98e3e1Schristos 		" as an argument.\n");
6874e98e3e1Schristos     }
6884e98e3e1Schristos   else
6894e98e3e1Schristos     printf ("The 'sim' command expects either 'trace' or 'verbose'"
6904e98e3e1Schristos 	    " as a subcommand.\n");
691b23b2582Schristos 
6924b169a6bSchristos   freeargv (argv);
6934e98e3e1Schristos }
694a2e2270fSchristos 
695a2e2270fSchristos char **
69603467a24Schristos sim_complete_command (SIM_DESC sd, const char *text, const char *word)
697a2e2270fSchristos {
698a2e2270fSchristos   return NULL;
699a2e2270fSchristos }
700ba340e45Schristos 
7014b169a6bSchristos char *
7024b169a6bSchristos sim_memory_map (SIM_DESC sd)
7034b169a6bSchristos {
7044b169a6bSchristos   return NULL;
7054b169a6bSchristos }
7064b169a6bSchristos 
707ba340e45Schristos void
708*71f62182Schristos sim_info (SIM_DESC sd, bool verbose)
709ba340e45Schristos {
710ba340e45Schristos   printf ("The m32c minisim doesn't collect any statistics.\n");
711ba340e45Schristos }
712