sim/ChangeLog:
2005-10-06 Jim Blandy <jimb@redhat.com> Add simulator for Renesas M32C and M16C. * m32c: New directory. * configure.ac: Add entry for Renesas M32C. * configure: Regenerate. sim/m32c/ChangeLog: 2005-10-06 Jim Blandy <jimb@redhat.com> Simulator for Renesas M32C and M16C, by DJ Delorie <dj@redhat.com>, with further work from Jim Blandy <jimb@redhat.com> and Kevin Buettner <kevinb@redhat.com>. * ChangeLog: New. * Makefile.in: New. * blinky.S: New. * config.in: New. * configure: New. * configure.in: New. * cpu.h: New. * gdb-if.c: New. * gloss.S: New. * int.c: New. * int.h: New. * load.c: New. * load.h: New. * m32c.opc: New. * main.c: New. * mem.c: New. * mem.h: New. * misc.c: New. * misc.h: New. * opc2c.c: New. * r8c.opc: New. * reg.c: New. * safe-fgets.c: New. * safe-fgets.h: New. * sample.S: New. * sample.ld: New. * sample2.c: New. * srcdest.c: New. * syscalls.c: New. * syscalls.h: New. * trace.c: New. * trace.h: New.
This commit is contained in:
parent
dda6380765
commit
d45a4bef83
35 changed files with 17347 additions and 0 deletions
710
sim/m32c/gdb-if.c
Normal file
710
sim/m32c/gdb-if.c
Normal file
|
@ -0,0 +1,710 @@
|
|||
/* gdb.c --- sim interface to GDB.
|
||||
|
||||
Copyright (C) 2005 Free Software Foundation, Inc.
|
||||
Contributed by Red Hat, Inc.
|
||||
|
||||
This file is part of the GNU simulators.
|
||||
|
||||
The GNU simulators are free software; you can redistribute them and/or
|
||||
modify them 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.
|
||||
|
||||
The GNU simulators are distributed in the hope that they 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 the GNU simulators; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301, USA */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "ansidecl.h"
|
||||
#include "gdb/callback.h"
|
||||
#include "gdb/remote-sim.h"
|
||||
#include "gdb/signals.h"
|
||||
#include "gdb/sim-m32c.h"
|
||||
|
||||
#include "cpu.h"
|
||||
#include "mem.h"
|
||||
#include "load.h"
|
||||
#include "syscalls.h"
|
||||
|
||||
/* I don't want to wrap up all the minisim's data structures in an
|
||||
object and pass that around. That'd be a big change, and neither
|
||||
GDB nor run needs that ability.
|
||||
|
||||
So we just have one instance, that lives in global variables, and
|
||||
each time we open it, we re-initialize it. */
|
||||
struct sim_state
|
||||
{
|
||||
const char *message;
|
||||
};
|
||||
|
||||
static struct sim_state the_minisim = {
|
||||
"This is the sole m32c minisim instance. See libsim.a's global variables."
|
||||
};
|
||||
|
||||
static int open;
|
||||
|
||||
SIM_DESC
|
||||
sim_open (SIM_OPEN_KIND kind,
|
||||
struct host_callback_struct *callback,
|
||||
struct bfd *abfd, char **argv)
|
||||
{
|
||||
if (open)
|
||||
fprintf (stderr, "m32c minisim: re-opened sim\n");
|
||||
|
||||
/* The 'run' interface doesn't use this function, so we don't care
|
||||
about KIND; it's always SIM_OPEN_DEBUG. */
|
||||
if (kind != SIM_OPEN_DEBUG)
|
||||
fprintf (stderr, "m32c minisim: sim_open KIND != SIM_OPEN_DEBUG: %d\n",
|
||||
kind);
|
||||
|
||||
if (abfd)
|
||||
m32c_set_mach (bfd_get_mach (abfd));
|
||||
|
||||
/* We can use ABFD, if non-NULL to select the appropriate
|
||||
architecture. But we only support the r8c right now. */
|
||||
|
||||
set_callbacks (callback);
|
||||
|
||||
/* We don't expect any command-line arguments. */
|
||||
|
||||
init_mem ();
|
||||
init_regs ();
|
||||
|
||||
open = 1;
|
||||
return &the_minisim;
|
||||
}
|
||||
|
||||
static void
|
||||
check_desc (SIM_DESC sd)
|
||||
{
|
||||
if (sd != &the_minisim)
|
||||
fprintf (stderr, "m32c minisim: desc != &the_minisim\n");
|
||||
}
|
||||
|
||||
void
|
||||
sim_close (SIM_DESC sd, int quitting)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
/* Not much to do. At least free up our memory. */
|
||||
init_mem ();
|
||||
|
||||
open = 0;
|
||||
}
|
||||
|
||||
static bfd *
|
||||
open_objfile (const char *filename)
|
||||
{
|
||||
bfd *prog = bfd_openr (filename, 0);
|
||||
|
||||
if (!prog)
|
||||
{
|
||||
fprintf (stderr, "Can't read %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!bfd_check_format (prog, bfd_object))
|
||||
{
|
||||
fprintf (stderr, "%s not a m32c program\n", filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return prog;
|
||||
}
|
||||
|
||||
|
||||
SIM_RC
|
||||
sim_load (SIM_DESC sd, char *prog, struct bfd *abfd, int from_tty)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
if (!abfd)
|
||||
abfd = open_objfile (prog);
|
||||
if (!abfd)
|
||||
return SIM_RC_FAIL;
|
||||
|
||||
m32c_load (abfd);
|
||||
|
||||
return SIM_RC_OK;
|
||||
}
|
||||
|
||||
SIM_RC
|
||||
sim_create_inferior (SIM_DESC sd, struct bfd *abfd, char **argv, char **env)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
if (abfd)
|
||||
m32c_load (abfd);
|
||||
|
||||
return SIM_RC_OK;
|
||||
}
|
||||
|
||||
int
|
||||
sim_read (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
if (mem == 0)
|
||||
return 0;
|
||||
|
||||
mem_get_blk ((int) mem, buf, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
int
|
||||
sim_write (SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
mem_put_blk ((int) mem, buf, length);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
/* Read the LENGTH bytes at BUF as an little-endian value. */
|
||||
static DI
|
||||
get_le (unsigned char *buf, int length)
|
||||
{
|
||||
DI acc = 0;
|
||||
while (--length >= 0)
|
||||
acc = (acc << 8) + buf[length];
|
||||
|
||||
return acc;
|
||||
}
|
||||
|
||||
/* Store VAL as a little-endian value in the LENGTH bytes at BUF. */
|
||||
static void
|
||||
put_le (unsigned char *buf, int length, DI val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
buf[i] = val & 0xff;
|
||||
val >>= 8;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
check_regno (enum m32c_sim_reg regno)
|
||||
{
|
||||
return 0 <= regno && regno < m32c_sim_reg_num_regs;
|
||||
}
|
||||
|
||||
static size_t
|
||||
mask_size (int addr_mask)
|
||||
{
|
||||
switch (addr_mask)
|
||||
{
|
||||
case 0xffff:
|
||||
return 2;
|
||||
case 0xfffff:
|
||||
case 0xffffff:
|
||||
return 3;
|
||||
default:
|
||||
fprintf (stderr,
|
||||
"m32c minisim: addr_mask_size: unexpected mask 0x%x\n",
|
||||
addr_mask);
|
||||
return sizeof (addr_mask);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t
|
||||
reg_size (enum m32c_sim_reg regno)
|
||||
{
|
||||
switch (regno)
|
||||
{
|
||||
case m32c_sim_reg_r0_bank0:
|
||||
case m32c_sim_reg_r1_bank0:
|
||||
case m32c_sim_reg_r2_bank0:
|
||||
case m32c_sim_reg_r3_bank0:
|
||||
case m32c_sim_reg_r0_bank1:
|
||||
case m32c_sim_reg_r1_bank1:
|
||||
case m32c_sim_reg_r2_bank1:
|
||||
case m32c_sim_reg_r3_bank1:
|
||||
case m32c_sim_reg_flg:
|
||||
case m32c_sim_reg_svf:
|
||||
return 2;
|
||||
|
||||
case m32c_sim_reg_a0_bank0:
|
||||
case m32c_sim_reg_a1_bank0:
|
||||
case m32c_sim_reg_fb_bank0:
|
||||
case m32c_sim_reg_sb_bank0:
|
||||
case m32c_sim_reg_a0_bank1:
|
||||
case m32c_sim_reg_a1_bank1:
|
||||
case m32c_sim_reg_fb_bank1:
|
||||
case m32c_sim_reg_sb_bank1:
|
||||
case m32c_sim_reg_usp:
|
||||
case m32c_sim_reg_isp:
|
||||
return mask_size (addr_mask);
|
||||
|
||||
case m32c_sim_reg_pc:
|
||||
case m32c_sim_reg_intb:
|
||||
case m32c_sim_reg_svp:
|
||||
case m32c_sim_reg_vct:
|
||||
return mask_size (membus_mask);
|
||||
|
||||
case m32c_sim_reg_dmd0:
|
||||
case m32c_sim_reg_dmd1:
|
||||
return 1;
|
||||
|
||||
case m32c_sim_reg_dct0:
|
||||
case m32c_sim_reg_dct1:
|
||||
case m32c_sim_reg_drc0:
|
||||
case m32c_sim_reg_drc1:
|
||||
return 2;
|
||||
|
||||
case m32c_sim_reg_dma0:
|
||||
case m32c_sim_reg_dma1:
|
||||
case m32c_sim_reg_dsa0:
|
||||
case m32c_sim_reg_dsa1:
|
||||
case m32c_sim_reg_dra0:
|
||||
case m32c_sim_reg_dra1:
|
||||
return 3;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
|
||||
regno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sim_fetch_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
check_desc (sd);
|
||||
|
||||
if (!check_regno (regno))
|
||||
return 0;
|
||||
|
||||
size = reg_size (regno);
|
||||
if (length == size)
|
||||
{
|
||||
DI val;
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case m32c_sim_reg_r0_bank0:
|
||||
val = regs.r[0].r_r0;
|
||||
break;
|
||||
case m32c_sim_reg_r1_bank0:
|
||||
val = regs.r[0].r_r1;
|
||||
break;
|
||||
case m32c_sim_reg_r2_bank0:
|
||||
val = regs.r[0].r_r2;
|
||||
break;
|
||||
case m32c_sim_reg_r3_bank0:
|
||||
val = regs.r[0].r_r3;
|
||||
break;
|
||||
case m32c_sim_reg_a0_bank0:
|
||||
val = regs.r[0].r_a0;
|
||||
break;
|
||||
case m32c_sim_reg_a1_bank0:
|
||||
val = regs.r[0].r_a1;
|
||||
break;
|
||||
case m32c_sim_reg_fb_bank0:
|
||||
val = regs.r[0].r_fb;
|
||||
break;
|
||||
case m32c_sim_reg_sb_bank0:
|
||||
val = regs.r[0].r_sb;
|
||||
break;
|
||||
case m32c_sim_reg_r0_bank1:
|
||||
val = regs.r[1].r_r0;
|
||||
break;
|
||||
case m32c_sim_reg_r1_bank1:
|
||||
val = regs.r[1].r_r1;
|
||||
break;
|
||||
case m32c_sim_reg_r2_bank1:
|
||||
val = regs.r[1].r_r2;
|
||||
break;
|
||||
case m32c_sim_reg_r3_bank1:
|
||||
val = regs.r[1].r_r3;
|
||||
break;
|
||||
case m32c_sim_reg_a0_bank1:
|
||||
val = regs.r[1].r_a0;
|
||||
break;
|
||||
case m32c_sim_reg_a1_bank1:
|
||||
val = regs.r[1].r_a1;
|
||||
break;
|
||||
case m32c_sim_reg_fb_bank1:
|
||||
val = regs.r[1].r_fb;
|
||||
break;
|
||||
case m32c_sim_reg_sb_bank1:
|
||||
val = regs.r[1].r_sb;
|
||||
break;
|
||||
|
||||
case m32c_sim_reg_usp:
|
||||
val = regs.r_usp;
|
||||
break;
|
||||
case m32c_sim_reg_isp:
|
||||
val = regs.r_isp;
|
||||
break;
|
||||
case m32c_sim_reg_pc:
|
||||
val = regs.r_pc;
|
||||
break;
|
||||
case m32c_sim_reg_intb:
|
||||
val = regs.r_intbl * 65536 + regs.r_intbl;
|
||||
break;
|
||||
case m32c_sim_reg_flg:
|
||||
val = regs.r_flags;
|
||||
break;
|
||||
|
||||
/* These registers aren't implemented by the minisim. */
|
||||
case m32c_sim_reg_svf:
|
||||
case m32c_sim_reg_svp:
|
||||
case m32c_sim_reg_vct:
|
||||
case m32c_sim_reg_dmd0:
|
||||
case m32c_sim_reg_dmd1:
|
||||
case m32c_sim_reg_dct0:
|
||||
case m32c_sim_reg_dct1:
|
||||
case m32c_sim_reg_drc0:
|
||||
case m32c_sim_reg_drc1:
|
||||
case m32c_sim_reg_dma0:
|
||||
case m32c_sim_reg_dma1:
|
||||
case m32c_sim_reg_dsa0:
|
||||
case m32c_sim_reg_dsa1:
|
||||
case m32c_sim_reg_dra0:
|
||||
case m32c_sim_reg_dra1:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
|
||||
regno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
put_le (buf, length, val);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int
|
||||
sim_store_register (SIM_DESC sd, int regno, unsigned char *buf, int length)
|
||||
{
|
||||
size_t size;
|
||||
|
||||
check_desc (sd);
|
||||
|
||||
if (!check_regno (regno))
|
||||
return 0;
|
||||
|
||||
size = reg_size (regno);
|
||||
|
||||
if (length == size)
|
||||
{
|
||||
DI val = get_le (buf, length);
|
||||
|
||||
switch (regno)
|
||||
{
|
||||
case m32c_sim_reg_r0_bank0:
|
||||
regs.r[0].r_r0 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_r1_bank0:
|
||||
regs.r[0].r_r1 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_r2_bank0:
|
||||
regs.r[0].r_r2 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_r3_bank0:
|
||||
regs.r[0].r_r3 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_a0_bank0:
|
||||
regs.r[0].r_a0 = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_a1_bank0:
|
||||
regs.r[0].r_a1 = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_fb_bank0:
|
||||
regs.r[0].r_fb = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_sb_bank0:
|
||||
regs.r[0].r_sb = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_r0_bank1:
|
||||
regs.r[1].r_r0 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_r1_bank1:
|
||||
regs.r[1].r_r1 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_r2_bank1:
|
||||
regs.r[1].r_r2 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_r3_bank1:
|
||||
regs.r[1].r_r3 = val & 0xffff;
|
||||
break;
|
||||
case m32c_sim_reg_a0_bank1:
|
||||
regs.r[1].r_a0 = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_a1_bank1:
|
||||
regs.r[1].r_a1 = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_fb_bank1:
|
||||
regs.r[1].r_fb = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_sb_bank1:
|
||||
regs.r[1].r_sb = val & addr_mask;
|
||||
break;
|
||||
|
||||
case m32c_sim_reg_usp:
|
||||
regs.r_usp = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_isp:
|
||||
regs.r_isp = val & addr_mask;
|
||||
break;
|
||||
case m32c_sim_reg_pc:
|
||||
regs.r_pc = val & membus_mask;
|
||||
break;
|
||||
case m32c_sim_reg_intb:
|
||||
regs.r_intbl = (val & membus_mask) & 0xffff;
|
||||
regs.r_intbh = (val & membus_mask) >> 16;
|
||||
break;
|
||||
case m32c_sim_reg_flg:
|
||||
regs.r_flags = val & 0xffff;
|
||||
break;
|
||||
|
||||
/* These registers aren't implemented by the minisim. */
|
||||
case m32c_sim_reg_svf:
|
||||
case m32c_sim_reg_svp:
|
||||
case m32c_sim_reg_vct:
|
||||
case m32c_sim_reg_dmd0:
|
||||
case m32c_sim_reg_dmd1:
|
||||
case m32c_sim_reg_dct0:
|
||||
case m32c_sim_reg_dct1:
|
||||
case m32c_sim_reg_drc0:
|
||||
case m32c_sim_reg_drc1:
|
||||
case m32c_sim_reg_dma0:
|
||||
case m32c_sim_reg_dma1:
|
||||
case m32c_sim_reg_dsa0:
|
||||
case m32c_sim_reg_dsa1:
|
||||
case m32c_sim_reg_dra0:
|
||||
case m32c_sim_reg_dra1:
|
||||
return 0;
|
||||
|
||||
default:
|
||||
fprintf (stderr, "m32c minisim: unrecognized register number: %d\n",
|
||||
regno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
void
|
||||
sim_info (SIM_DESC sd, int verbose)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
printf ("The m32c minisim doesn't collect any statistics.\n");
|
||||
}
|
||||
|
||||
static volatile int stop;
|
||||
static enum sim_stop reason;
|
||||
int siggnal;
|
||||
|
||||
|
||||
/* Given a signal number used by the M32C bsp (that is, newlib),
|
||||
return a host signal number. (Oddly, the gdb/sim interface uses
|
||||
host signal numbers...) */
|
||||
int
|
||||
m32c_signal_to_host (int m32c)
|
||||
{
|
||||
switch (m32c)
|
||||
{
|
||||
case 4:
|
||||
#ifdef SIGILL
|
||||
return SIGILL;
|
||||
#else
|
||||
return SIGSEGV;
|
||||
#endif
|
||||
|
||||
case 5:
|
||||
return SIGTRAP;
|
||||
|
||||
case 10:
|
||||
#ifdef SIGBUS
|
||||
return SIGBUS;
|
||||
#else
|
||||
return SIGSEGV;
|
||||
#endif
|
||||
|
||||
case 11:
|
||||
return SIGSEGV;
|
||||
|
||||
case 24:
|
||||
#ifdef SIGXCPU
|
||||
return SIGXCPU;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 2:
|
||||
return SIGINT;
|
||||
|
||||
case 8:
|
||||
#ifdef SIGFPE
|
||||
return SIGFPE;
|
||||
#else
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 6:
|
||||
return SIGABRT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Take a step return code RC and set up the variables consulted by
|
||||
sim_stop_reason appropriately. */
|
||||
void
|
||||
handle_step (int rc)
|
||||
{
|
||||
if (M32C_STEPPED (rc) || M32C_HIT_BREAK (rc))
|
||||
{
|
||||
reason = sim_stopped;
|
||||
siggnal = TARGET_SIGNAL_TRAP;
|
||||
}
|
||||
else if (M32C_STOPPED (rc))
|
||||
{
|
||||
reason = sim_stopped;
|
||||
siggnal = m32c_signal_to_host (M32C_STOP_SIG (rc));
|
||||
}
|
||||
else
|
||||
{
|
||||
assert (M32C_EXITED (rc));
|
||||
reason = sim_exited;
|
||||
siggnal = M32C_EXIT_STATUS (rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sim_resume (SIM_DESC sd, int step, int sig_to_deliver)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
if (sig_to_deliver != 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"Warning: the m32c minisim does not implement "
|
||||
"signal delivery yet.\n" "Resuming with no signal.\n");
|
||||
}
|
||||
|
||||
if (step)
|
||||
handle_step (decode_opcode ());
|
||||
else
|
||||
{
|
||||
/* We don't clear 'stop' here, because then we would miss
|
||||
interrupts that arrived on the way here. Instead, we clear
|
||||
the flag in sim_stop_reason, after GDB has disabled the
|
||||
interrupt signal handler. */
|
||||
for (;;)
|
||||
{
|
||||
if (stop)
|
||||
{
|
||||
stop = 0;
|
||||
reason = sim_stopped;
|
||||
siggnal = TARGET_SIGNAL_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
int rc = decode_opcode ();
|
||||
|
||||
if (!M32C_STEPPED (rc))
|
||||
{
|
||||
handle_step (rc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
sim_stop (SIM_DESC sd)
|
||||
{
|
||||
stop = 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
sim_stop_reason (SIM_DESC sd, enum sim_stop *reason_p, int *sigrc_p)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
*reason_p = reason;
|
||||
*sigrc_p = siggnal;
|
||||
}
|
||||
|
||||
void
|
||||
sim_do_command (SIM_DESC sd, char *cmd)
|
||||
{
|
||||
check_desc (sd);
|
||||
|
||||
char *p = cmd;
|
||||
|
||||
/* Skip leading whitespace. */
|
||||
while (isspace (*p))
|
||||
p++;
|
||||
|
||||
/* Find the extent of the command word. */
|
||||
for (p = cmd; *p; p++)
|
||||
if (isspace (*p))
|
||||
break;
|
||||
|
||||
/* Null-terminate the command word, and record the start of any
|
||||
further arguments. */
|
||||
char *args;
|
||||
if (*p)
|
||||
{
|
||||
*p = '\0';
|
||||
args = p + 1;
|
||||
while (isspace (*args))
|
||||
args++;
|
||||
}
|
||||
else
|
||||
args = p;
|
||||
|
||||
if (strcmp (cmd, "trace") == 0)
|
||||
{
|
||||
if (strcmp (args, "on") == 0)
|
||||
trace = 1;
|
||||
else if (strcmp (args, "off") == 0)
|
||||
trace = 0;
|
||||
else
|
||||
printf ("The 'sim trace' command expects 'on' or 'off' "
|
||||
"as an argument.\n");
|
||||
}
|
||||
else if (strcmp (cmd, "verbose") == 0)
|
||||
{
|
||||
if (strcmp (args, "on") == 0)
|
||||
verbose = 1;
|
||||
else if (strcmp (args, "off") == 0)
|
||||
verbose = 0;
|
||||
else
|
||||
printf ("The 'sim verbose' command expects 'on' or 'off'"
|
||||
" as an argument.\n");
|
||||
}
|
||||
else
|
||||
printf ("The 'sim' command expects either 'trace' or 'verbose'"
|
||||
" as a subcommand.\n");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue