/* Simulator for the moxie processor
- Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2008-2018 Free Software Foundation, Inc.
Contributed by Anthony Green
This file is part of GDB, the GNU debugger.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
+#include "config.h"
+#include <fcntl.h>
#include <signal.h>
#include <stdlib.h>
-#include "sysdep.h"
+#include <string.h>
#include <sys/times.h>
#include <sys/param.h>
-#include <netinet/in.h> /* for byte ordering macros */
+#include <unistd.h>
#include "bfd.h"
-#include "gdb/callback.h"
#include "libiberty.h"
#include "gdb/remote-sim.h"
+#include "sim-main.h"
+#include "sim-base.h"
+#include "sim-options.h"
+
typedef int word;
typedef unsigned int uword;
-host_callback * callback;
-
-FILE *tracefile;
-
/* Extract the signed 10-bit offset from a 16-bit branch
instruction. */
#define INST2OFFSET(o) ((((signed short)((o & ((1<<10)-1))<<6))>>6)<<1)
-#define EXTRACT_WORD(addr) (((addr)[0] << 24) \
- + ((addr)[1] << 16) \
- + ((addr)[2] << 8) \
- + ((addr)[3]))
+#define EXTRACT_WORD(addr) \
+ ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 24) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1) << 16) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+2) << 8) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+3)))
-unsigned long
-moxie_extract_unsigned_integer (addr, len)
- unsigned char * addr;
- int len;
+#define EXTRACT_OFFSET(addr) \
+ (unsigned int) \
+ (((signed short) \
+ ((sim_core_read_aligned_1 (scpu, cia, read_map, addr) << 8) \
+ + (sim_core_read_aligned_1 (scpu, cia, read_map, addr+1))) << 16) >> 16)
+
+static unsigned long
+moxie_extract_unsigned_integer (unsigned char *addr, int len)
{
unsigned long retval;
unsigned char * p;
unsigned char * endaddr = startaddr + len;
if (len > (int) sizeof (unsigned long))
- printf ("That operation is not available on integers of more than %d bytes.",
+ printf ("That operation is not available on integers of more than %zu bytes.",
sizeof (unsigned long));
/* Start at the most significant end of the integer, and work towards
return retval;
}
-void
-moxie_store_unsigned_integer (addr, len, val)
- unsigned char * addr;
- int len;
- unsigned long val;
+static void
+moxie_store_unsigned_integer (unsigned char *addr, int len, unsigned long val)
{
unsigned char * p;
unsigned char * startaddr = (unsigned char *)addr;
/* The ordering of the moxie_regset structure is matched in the
gdb/config/moxie/tm-moxie.h file in the REGISTER_NAMES macro. */
+/* TODO: This should be moved to sim-main.h:_sim_cpu. */
struct moxie_regset
{
word regs[NUM_MOXIE_REGS + 1]; /* primary registers */
word sregs[256]; /* special registers */
word cc; /* the condition code reg */
- int exception;
- unsigned long msize;
- unsigned char * memory;
unsigned long long insts; /* instruction counter */
};
#define CC_GTU 1<<3
#define CC_LTU 1<<4
+/* TODO: This should be moved to sim-main.h:_sim_cpu. */
union
{
struct moxie_regset asregs;
word asints [1]; /* but accessed larger... */
} cpu;
-static char *myname;
-static SIM_OPEN_KIND sim_kind;
-static int issue_messages = 0;
-
-/* Default to a 16 Mbyte (== 2^23) memory space. */
-static int sim_memory_size = 24;
-
-#define MEM_SIZE_FLOOR 64
-void
-sim_size (power)
- int power;
-{
- sim_memory_size = power;
- cpu.asregs.msize = 1 << sim_memory_size;
-
- if (cpu.asregs.memory)
- free (cpu.asregs.memory);
-
- /* Watch out for the '0 count' problem. There's probably a better
- way.. e.g., why do we use 64 here? */
- if (cpu.asregs.msize < 64) /* Ensure a boundary. */
- cpu.asregs.memory = (unsigned char *) calloc (64, (64 + cpu.asregs.msize) / 64);
- else
- cpu.asregs.memory = (unsigned char *) calloc (64, cpu.asregs.msize / 64);
-
- if (!cpu.asregs.memory)
- {
- if (issue_messages)
- fprintf (stderr,
- "Not enough VM for simulation of %d bytes of RAM\n",
- cpu.asregs.msize);
-
- cpu.asregs.msize = 1;
- cpu.asregs.memory = (unsigned char *) calloc (1, 1);
- }
-}
-
static void
-init_pointers ()
-{
- if (cpu.asregs.msize != (1 << sim_memory_size))
- sim_size (sim_memory_size);
-}
-
-
-static void
-set_initial_gprs ()
+set_initial_gprs (void)
{
int i;
long space;
- unsigned long memsize;
- init_pointers ();
-
/* Set up machine just out of reset. */
cpu.asregs.regs[PC_REGNO] = 0;
- memsize = cpu.asregs.msize / (1024 * 1024);
-
- if (issue_messages > 1)
- fprintf (stderr, "Simulated memory of %d Mbytes (0x0 .. 0x%08x)\n",
- memsize, cpu.asregs.msize - 1);
-
/* Clean out the register contents. */
for (i = 0; i < NUM_MOXIE_REGS; i++)
cpu.asregs.regs[i] = 0;
cpu.asregs.sregs[i] = 0;
}
-static void
-interrupt ()
-{
- cpu.asregs.exception = SIGINT;
-}
-
/* Write a 1 byte value to memory. */
-static void INLINE
-wbat (pc, x, v)
- word pc, x, v;
+static INLINE void
+wbat (sim_cpu *scpu, word pc, word x, word v)
{
- if (((uword)x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "byte write to 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- }
- else
- {
- {
- unsigned char * p = cpu.asregs.memory + x;
- *p = v;
- }
- }
+ address_word cia = CPU_PC_GET (scpu);
+
+ sim_core_write_aligned_1 (scpu, cia, write_map, x, v);
}
/* Write a 2 byte value to memory. */
-static void INLINE
-wsat (pc, x, v)
- word pc, x, v;
+static INLINE void
+wsat (sim_cpu *scpu, word pc, word x, word v)
{
- if (((uword)x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "short word write to 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- }
- else
- {
- if ((x & 1) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "short word write to unaligned memory address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- p[0] = v >> 8;
- p[1] = v;
- }
- }
+ address_word cia = CPU_PC_GET (scpu);
+
+ sim_core_write_aligned_2 (scpu, cia, write_map, x, v);
}
/* Write a 4 byte value to memory. */
-static void INLINE
-wlat (pc, x, v)
- word pc, x, v;
+static INLINE void
+wlat (sim_cpu *scpu, word pc, word x, word v)
{
- if (((uword)x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "word write to 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- }
- else
- {
- if ((x & 1) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "word write to unaligned memory address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- p[0] = v >> 24;
- p[1] = v >> 16;
- p[2] = v >> 8;
- p[3] = v;
- }
- }
+ address_word cia = CPU_PC_GET (scpu);
+
+ sim_core_write_aligned_4 (scpu, cia, write_map, x, v);
}
/* Read 2 bytes from memory. */
-static int INLINE
-rsat (pc, x)
- word pc, x;
+static INLINE int
+rsat (sim_cpu *scpu, word pc, word x)
{
- if (((uword) x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "short word read from 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- return 0;
- }
- else
- {
- if ((x & 1) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "short word read from unaligned address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- return 0;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- return (p[0] << 8) | p[1];
- }
- }
+ address_word cia = CPU_PC_GET (scpu);
+
+ return (sim_core_read_aligned_2 (scpu, cia, read_map, x));
}
/* Read 1 byte from memory. */
-static int INLINE
-rbat (pc, x)
- word pc, x;
+static INLINE int
+rbat (sim_cpu *scpu, word pc, word x)
{
- if (((uword) x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "byte read from 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- return 0;
- }
- else
- {
- unsigned char * p = cpu.asregs.memory + x;
- return *p;
- }
+ address_word cia = CPU_PC_GET (scpu);
+
+ return (sim_core_read_aligned_1 (scpu, cia, read_map, x));
}
/* Read 4 bytes from memory. */
-static int INLINE
-rlat (pc, x)
- word pc, x;
+static INLINE int
+rlat (sim_cpu *scpu, word pc, word x)
{
- if (((uword) x) >= cpu.asregs.msize)
- {
- if (issue_messages)
- fprintf (stderr, "word read from 0x%x outside memory range\n", x);
-
- cpu.asregs.exception = SIGSEGV;
- return 0;
- }
- else
- {
- if ((x & 3) != 0)
- {
- if (issue_messages)
- fprintf (stderr, "word read from unaligned address: 0x%x\n", x);
-
- cpu.asregs.exception = SIGBUS;
- return 0;
- }
- {
- unsigned char * p = cpu.asregs.memory + x;
- return (EXTRACT_WORD(p));
- }
- }
+ address_word cia = CPU_PC_GET (scpu);
+
+ return (sim_core_read_aligned_4 (scpu, cia, read_map, x));
}
#define CHECK_FLAG(T,H) if (tflags & T) { hflags |= H; tflags ^= T; }
-unsigned int
+static unsigned int
convert_target_flags (unsigned int tflags)
{
unsigned int hflags = 0x0;
return hflags;
}
-#define TRACE(str) if (tracing) fprintf(tracefile,"0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], cpu.asregs.regs[14], cpu.asregs.regs[15]);
-
-static int tracing = 0;
+/* TODO: Split this up into finger trace levels than just insn. */
+#define MOXIE_TRACE_INSN(str) \
+ TRACE_INSN (scpu, "0x%08x, %s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x", \
+ opc, str, cpu.asregs.regs[0], cpu.asregs.regs[1], \
+ cpu.asregs.regs[2], cpu.asregs.regs[3], cpu.asregs.regs[4], \
+ cpu.asregs.regs[5], cpu.asregs.regs[6], cpu.asregs.regs[7], \
+ cpu.asregs.regs[8], cpu.asregs.regs[9], cpu.asregs.regs[10], \
+ cpu.asregs.regs[11], cpu.asregs.regs[12], cpu.asregs.regs[13], \
+ cpu.asregs.regs[14], cpu.asregs.regs[15])
void
-sim_resume (sd, step, siggnal)
- SIM_DESC sd;
- int step, siggnal;
+sim_engine_run (SIM_DESC sd,
+ int next_cpu_nr, /* ignore */
+ int nr_cpus, /* ignore */
+ int siggnal) /* ignore */
{
word pc, opc;
- unsigned long long insts;
unsigned short inst;
- void (* sigsave)();
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+ address_word cia = CPU_PC_GET (scpu);
- sigsave = signal (SIGINT, interrupt);
- cpu.asregs.exception = step ? SIGTRAP: 0;
pc = cpu.asregs.regs[PC_REGNO];
- insts = cpu.asregs.insts;
- unsigned char *memory = cpu.asregs.memory;
/* Run instructions here. */
do
opc = pc;
/* Fetch the instruction at pc. */
- inst = (memory[pc] << 8) + memory[pc + 1];
+ inst = (sim_core_read_aligned_1 (scpu, cia, read_map, pc) << 8)
+ + sim_core_read_aligned_1 (scpu, cia, read_map, pc+1);
/* Decode instruction. */
if (inst & (1 << 15))
{
case 0x00: /* beq */
{
- TRACE("beq");
+ MOXIE_TRACE_INSN ("beq");
if (cpu.asregs.cc & CC_EQ)
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x01: /* bne */
{
- TRACE("bne");
+ MOXIE_TRACE_INSN ("bne");
if (! (cpu.asregs.cc & CC_EQ))
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x02: /* blt */
{
- TRACE("blt");
+ MOXIE_TRACE_INSN ("blt");
if (cpu.asregs.cc & CC_LT)
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
} break;
case 0x03: /* bgt */
{
- TRACE("bgt");
+ MOXIE_TRACE_INSN ("bgt");
if (cpu.asregs.cc & CC_GT)
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x04: /* bltu */
{
- TRACE("bltu");
+ MOXIE_TRACE_INSN ("bltu");
if (cpu.asregs.cc & CC_LTU)
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x05: /* bgtu */
{
- TRACE("bgtu");
+ MOXIE_TRACE_INSN ("bgtu");
if (cpu.asregs.cc & CC_GTU)
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x06: /* bge */
{
- TRACE("bge");
+ MOXIE_TRACE_INSN ("bge");
if (cpu.asregs.cc & (CC_GT | CC_EQ))
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x07: /* ble */
{
- TRACE("ble");
+ MOXIE_TRACE_INSN ("ble");
if (cpu.asregs.cc & (CC_LT | CC_EQ))
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x08: /* bgeu */
{
- TRACE("bgeu");
+ MOXIE_TRACE_INSN ("bgeu");
if (cpu.asregs.cc & (CC_GTU | CC_EQ))
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
case 0x09: /* bleu */
{
- TRACE("bleu");
+ MOXIE_TRACE_INSN ("bleu");
if (cpu.asregs.cc & (CC_LTU | CC_EQ))
- pc += INST2OFFSET(inst) - 2;
+ pc += INST2OFFSET(inst);
}
break;
default:
{
- TRACE("SIGILL3");
- cpu.asregs.exception = SIGILL;
+ MOXIE_TRACE_INSN ("SIGILL3");
+ sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
break;
}
}
int a = (inst >> 8) & 0xf;
unsigned av = cpu.asregs.regs[a];
unsigned v = (inst & 0xff);
- TRACE("inc");
+
+ MOXIE_TRACE_INSN ("inc");
cpu.asregs.regs[a] = av + v;
}
break;
int a = (inst >> 8) & 0xf;
unsigned av = cpu.asregs.regs[a];
unsigned v = (inst & 0xff);
- TRACE("dec");
+
+ MOXIE_TRACE_INSN ("dec");
cpu.asregs.regs[a] = av - v;
}
break;
{
int a = (inst >> 8) & 0xf;
unsigned v = (inst & 0xff);
- TRACE("gsr");
+
+ MOXIE_TRACE_INSN ("gsr");
cpu.asregs.regs[a] = cpu.asregs.sregs[v];
}
break;
{
int a = (inst >> 8) & 0xf;
unsigned v = (inst & 0xff);
- TRACE("ssr");
+
+ MOXIE_TRACE_INSN ("ssr");
cpu.asregs.sregs[v] = cpu.asregs.regs[a];
}
break;
default:
- TRACE("SIGILL2");
- cpu.asregs.exception = SIGILL;
+ MOXIE_TRACE_INSN ("SIGILL2");
+ sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
break;
}
}
int opcode = inst >> 8;
switch (opcode)
{
- case 0x00: /* nop */
+ case 0x00: /* bad */
+ opc = opcode;
+ MOXIE_TRACE_INSN ("SIGILL0");
+ sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
break;
case 0x01: /* ldi.l (immediate) */
{
int reg = (inst >> 4) & 0xf;
- TRACE("ldi.l");
- unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
+ unsigned int val = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("ldi.l");
cpu.asregs.regs[reg] = val;
pc += 4;
}
{
int dest = (inst >> 4) & 0xf;
int src = (inst ) & 0xf;
- TRACE("mov");
+
+ MOXIE_TRACE_INSN ("mov");
cpu.asregs.regs[dest] = cpu.asregs.regs[src];
}
break;
case 0x03: /* jsra */
{
- unsigned int fn = EXTRACT_WORD(&(memory[pc + 2]));
+ unsigned int fn = EXTRACT_WORD(pc+2);
unsigned int sp = cpu.asregs.regs[1];
- TRACE("jsra");
+
+ MOXIE_TRACE_INSN ("jsra");
/* Save a slot for the static chain. */
sp -= 4;
/* Push the return address. */
sp -= 4;
- wlat (opc, sp, pc + 6);
+ wlat (scpu, opc, sp, pc + 6);
/* Push the current frame pointer. */
sp -= 4;
- wlat (opc, sp, cpu.asregs.regs[0]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[0]);
/* Uncache the stack pointer and set the pc and $fp. */
cpu.asregs.regs[1] = sp;
{
unsigned int sp = cpu.asregs.regs[0];
- TRACE("ret");
+ MOXIE_TRACE_INSN ("ret");
/* Pop the frame pointer. */
- cpu.asregs.regs[0] = rlat (opc, sp);
+ cpu.asregs.regs[0] = rlat (scpu, opc, sp);
sp += 4;
/* Pop the return address. */
- pc = rlat (opc, sp) - 2;
+ pc = rlat (scpu, opc, sp) - 2;
sp += 4;
/* Skip over the static chain slot. */
int b = inst & 0xf;
unsigned av = cpu.asregs.regs[a];
unsigned bv = cpu.asregs.regs[b];
- TRACE("add.l");
+
+ MOXIE_TRACE_INSN ("add.l");
cpu.asregs.regs[a] = av + bv;
}
break;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int sp = cpu.asregs.regs[a] - 4;
- TRACE("push");
- wlat (opc, sp, cpu.asregs.regs[b]);
+
+ MOXIE_TRACE_INSN ("push");
+ wlat (scpu, opc, sp, cpu.asregs.regs[b]);
cpu.asregs.regs[a] = sp;
}
break;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int sp = cpu.asregs.regs[a];
- TRACE("pop");
- cpu.asregs.regs[b] = rlat (opc, sp);
+
+ MOXIE_TRACE_INSN ("pop");
+ cpu.asregs.regs[b] = rlat (scpu, opc, sp);
cpu.asregs.regs[a] = sp + 4;
}
break;
case 0x08: /* lda.l */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
- TRACE("lda.l");
- cpu.asregs.regs[reg] = rlat (opc, addr);
+ unsigned int addr = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("lda.l");
+ cpu.asregs.regs[reg] = rlat (scpu, opc, addr);
pc += 4;
}
break;
case 0x09: /* sta.l */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
- TRACE("sta.l");
- wlat (opc, addr, cpu.asregs.regs[reg]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("sta.l");
+ wlat (scpu, opc, addr, cpu.asregs.regs[reg]);
pc += 4;
}
break;
int src = inst & 0xf;
int dest = (inst >> 4) & 0xf;
int xv;
- TRACE("ld.l");
+
+ MOXIE_TRACE_INSN ("ld.l");
xv = cpu.asregs.regs[src];
- cpu.asregs.regs[dest] = rlat (opc, xv);
+ cpu.asregs.regs[dest] = rlat (scpu, opc, xv);
}
break;
case 0x0b: /* st.l */
{
int dest = (inst >> 4) & 0xf;
int val = inst & 0xf;
- TRACE("st.l");
- wlat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+
+ MOXIE_TRACE_INSN ("st.l");
+ wlat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
}
break;
case 0x0c: /* ldo.l */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_OFFSET(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
- TRACE("ldo.l");
+
+ MOXIE_TRACE_INSN ("ldo.l");
addr += cpu.asregs.regs[b];
- cpu.asregs.regs[a] = rlat(opc, addr);
- pc += 4;
+ cpu.asregs.regs[a] = rlat (scpu, opc, addr);
+ pc += 2;
}
break;
case 0x0d: /* sto.l */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_OFFSET(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
- TRACE("sto.l");
+
+ MOXIE_TRACE_INSN ("sto.l");
addr += cpu.asregs.regs[a];
- wlat(opc, addr, cpu.asregs.regs[b]);
- pc += 4;
+ wlat (scpu, opc, addr, cpu.asregs.regs[b]);
+ pc += 2;
}
break;
case 0x0e: /* cmp */
int va = cpu.asregs.regs[a];
int vb = cpu.asregs.regs[b];
- TRACE("cmp");
-
+ MOXIE_TRACE_INSN ("cmp");
if (va == vb)
cc = CC_EQ;
else
cpu.asregs.cc = cc;
}
break;
- case 0x0f:
- case 0x10:
- case 0x11:
- case 0x12:
- case 0x13:
- case 0x14:
- case 0x15:
- case 0x16:
- case 0x17:
- case 0x18:
+ case 0x0f: /* nop */
+ break;
+ case 0x10: /* sex.b */
+ {
+ int a = (inst >> 4) & 0xf;
+ int b = inst & 0xf;
+ signed char bv = cpu.asregs.regs[b];
+
+ MOXIE_TRACE_INSN ("sex.b");
+ cpu.asregs.regs[a] = (int) bv;
+ }
+ break;
+ case 0x11: /* sex.s */
+ {
+ int a = (inst >> 4) & 0xf;
+ int b = inst & 0xf;
+ signed short bv = cpu.asregs.regs[b];
+
+ MOXIE_TRACE_INSN ("sex.s");
+ cpu.asregs.regs[a] = (int) bv;
+ }
+ break;
+ case 0x12: /* zex.b */
+ {
+ int a = (inst >> 4) & 0xf;
+ int b = inst & 0xf;
+ signed char bv = cpu.asregs.regs[b];
+
+ MOXIE_TRACE_INSN ("zex.b");
+ cpu.asregs.regs[a] = (int) bv & 0xff;
+ }
+ break;
+ case 0x13: /* zex.s */
+ {
+ int a = (inst >> 4) & 0xf;
+ int b = inst & 0xf;
+ signed short bv = cpu.asregs.regs[b];
+
+ MOXIE_TRACE_INSN ("zex.s");
+ cpu.asregs.regs[a] = (int) bv & 0xffff;
+ }
+ break;
+ case 0x14: /* umul.x */
+ {
+ int a = (inst >> 4) & 0xf;
+ int b = inst & 0xf;
+ unsigned av = cpu.asregs.regs[a];
+ unsigned bv = cpu.asregs.regs[b];
+ unsigned long long r =
+ (unsigned long long) av * (unsigned long long) bv;
+
+ MOXIE_TRACE_INSN ("umul.x");
+ cpu.asregs.regs[a] = r >> 32;
+ }
+ break;
+ case 0x15: /* mul.x */
+ {
+ int a = (inst >> 4) & 0xf;
+ int b = inst & 0xf;
+ unsigned av = cpu.asregs.regs[a];
+ unsigned bv = cpu.asregs.regs[b];
+ signed long long r =
+ (signed long long) av * (signed long long) bv;
+
+ MOXIE_TRACE_INSN ("mul.x");
+ cpu.asregs.regs[a] = r >> 32;
+ }
+ break;
+ case 0x16: /* bad */
+ case 0x17: /* bad */
+ case 0x18: /* bad */
{
opc = opcode;
- TRACE("SIGILL0");
- cpu.asregs.exception = SIGILL;
+ MOXIE_TRACE_INSN ("SIGILL0");
+ sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
break;
}
case 0x19: /* jsr */
unsigned int fn = cpu.asregs.regs[(inst >> 4) & 0xf];
unsigned int sp = cpu.asregs.regs[1];
- TRACE("jsr");
+ MOXIE_TRACE_INSN ("jsr");
/* Save a slot for the static chain. */
sp -= 4;
/* Push the return address. */
sp -= 4;
- wlat (opc, sp, pc + 2);
+ wlat (scpu, opc, sp, pc + 2);
/* Push the current frame pointer. */
sp -= 4;
- wlat (opc, sp, cpu.asregs.regs[0]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[0]);
/* Uncache the stack pointer and set the fp & pc. */
cpu.asregs.regs[1] = sp;
break;
case 0x1a: /* jmpa */
{
- unsigned int tgt = EXTRACT_WORD(&memory[pc+2]);
- TRACE("jmpa");
+ unsigned int tgt = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("jmpa");
pc = tgt - 2;
}
break;
case 0x1b: /* ldi.b (immediate) */
{
int reg = (inst >> 4) & 0xf;
+ unsigned int val = EXTRACT_WORD(pc+2);
- unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
- TRACE("ldi.b");
+ MOXIE_TRACE_INSN ("ldi.b");
cpu.asregs.regs[reg] = val;
pc += 4;
}
int src = inst & 0xf;
int dest = (inst >> 4) & 0xf;
int xv;
- TRACE("ld.b");
+
+ MOXIE_TRACE_INSN ("ld.b");
xv = cpu.asregs.regs[src];
- cpu.asregs.regs[dest] = rbat (opc, xv);
+ cpu.asregs.regs[dest] = rbat (scpu, opc, xv);
}
break;
case 0x1d: /* lda.b */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
- TRACE("lda.b");
- cpu.asregs.regs[reg] = rbat (opc, addr);
+ unsigned int addr = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("lda.b");
+ cpu.asregs.regs[reg] = rbat (scpu, opc, addr);
pc += 4;
}
break;
{
int dest = (inst >> 4) & 0xf;
int val = inst & 0xf;
- TRACE("st.b");
- wbat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+
+ MOXIE_TRACE_INSN ("st.b");
+ wbat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
}
break;
case 0x1f: /* sta.b */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
- TRACE("sta.b");
- wbat (opc, addr, cpu.asregs.regs[reg]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("sta.b");
+ wbat (scpu, opc, addr, cpu.asregs.regs[reg]);
pc += 4;
}
break;
{
int reg = (inst >> 4) & 0xf;
- unsigned int val = EXTRACT_WORD(&(memory[pc + 2]));
- TRACE("ldi.s");
+ unsigned int val = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("ldi.s");
cpu.asregs.regs[reg] = val;
pc += 4;
}
int src = inst & 0xf;
int dest = (inst >> 4) & 0xf;
int xv;
- TRACE("ld.s");
+
+ MOXIE_TRACE_INSN ("ld.s");
xv = cpu.asregs.regs[src];
- cpu.asregs.regs[dest] = rsat (opc, xv);
+ cpu.asregs.regs[dest] = rsat (scpu, opc, xv);
}
break;
case 0x22: /* lda.s */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
- TRACE("lda.s");
- cpu.asregs.regs[reg] = rsat (opc, addr);
+ unsigned int addr = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("lda.s");
+ cpu.asregs.regs[reg] = rsat (scpu, opc, addr);
pc += 4;
}
break;
{
int dest = (inst >> 4) & 0xf;
int val = inst & 0xf;
- TRACE("st.s");
- wsat (opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
+
+ MOXIE_TRACE_INSN ("st.s");
+ wsat (scpu, opc, cpu.asregs.regs[dest], cpu.asregs.regs[val]);
}
break;
case 0x24: /* sta.s */
{
int reg = (inst >> 4) & 0xf;
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
- TRACE("sta.s");
- wsat (opc, addr, cpu.asregs.regs[reg]);
+ unsigned int addr = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("sta.s");
+ wsat (scpu, opc, addr, cpu.asregs.regs[reg]);
pc += 4;
}
break;
case 0x25: /* jmp */
{
int reg = (inst >> 4) & 0xf;
- TRACE("jmp");
+
+ MOXIE_TRACE_INSN ("jmp");
pc = cpu.asregs.regs[reg] - 2;
}
break;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int av, bv;
- TRACE("and");
+
+ MOXIE_TRACE_INSN ("and");
av = cpu.asregs.regs[a];
bv = cpu.asregs.regs[b];
cpu.asregs.regs[a] = av & bv;
int b = inst & 0xf;
int av = cpu.asregs.regs[a];
int bv = cpu.asregs.regs[b];
- TRACE("lshr");
+
+ MOXIE_TRACE_INSN ("lshr");
cpu.asregs.regs[a] = (unsigned) ((unsigned) av >> bv);
}
break;
int b = inst & 0xf;
int av = cpu.asregs.regs[a];
int bv = cpu.asregs.regs[b];
- TRACE("ashl");
+
+ MOXIE_TRACE_INSN ("ashl");
cpu.asregs.regs[a] = av << bv;
}
break;
int b = inst & 0xf;
unsigned av = cpu.asregs.regs[a];
unsigned bv = cpu.asregs.regs[b];
- TRACE("sub.l");
+
+ MOXIE_TRACE_INSN ("sub.l");
cpu.asregs.regs[a] = av - bv;
}
break;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int bv = cpu.asregs.regs[b];
- TRACE("neg");
+
+ MOXIE_TRACE_INSN ("neg");
cpu.asregs.regs[a] = - bv;
}
break;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int av, bv;
- TRACE("or");
+
+ MOXIE_TRACE_INSN ("or");
av = cpu.asregs.regs[a];
bv = cpu.asregs.regs[b];
cpu.asregs.regs[a] = av | bv;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int bv = cpu.asregs.regs[b];
- TRACE("not");
+
+ MOXIE_TRACE_INSN ("not");
cpu.asregs.regs[a] = 0xffffffff ^ bv;
}
break;
int b = inst & 0xf;
int av = cpu.asregs.regs[a];
int bv = cpu.asregs.regs[b];
- TRACE("ashr");
+
+ MOXIE_TRACE_INSN ("ashr");
cpu.asregs.regs[a] = av >> bv;
}
break;
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
int av, bv;
- TRACE("xor");
+
+ MOXIE_TRACE_INSN ("xor");
av = cpu.asregs.regs[a];
bv = cpu.asregs.regs[b];
cpu.asregs.regs[a] = av ^ bv;
int b = inst & 0xf;
unsigned av = cpu.asregs.regs[a];
unsigned bv = cpu.asregs.regs[b];
- TRACE("mul.l");
+
+ MOXIE_TRACE_INSN ("mul.l");
cpu.asregs.regs[a] = av * bv;
}
break;
case 0x30: /* swi */
{
- unsigned int inum = EXTRACT_WORD(&memory[pc+2]);
- TRACE("swi");
+ unsigned int inum = EXTRACT_WORD(pc+2);
+
+ MOXIE_TRACE_INSN ("swi");
+ /* Set the special registers appropriately. */
+ cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
+ cpu.asregs.sregs[3] = inum;
switch (inum)
{
case 0x1: /* SYS_exit */
{
- cpu.asregs.exception = SIGQUIT;
+ sim_engine_halt (sd, scpu, NULL, pc, sim_exited,
+ cpu.asregs.regs[2]);
break;
}
case 0x2: /* SYS_open */
{
- char *fname = &memory[cpu.asregs.regs[2]];
+ char fname[1024];
int mode = (int) convert_target_flags ((unsigned) cpu.asregs.regs[3]);
int perm = (int) cpu.asregs.regs[4];
int fd = open (fname, mode, perm);
+ sim_core_read_buffer (sd, scpu, read_map, fname,
+ cpu.asregs.regs[2], 1024);
/* FIXME - set errno */
cpu.asregs.regs[2] = fd;
break;
case 0x4: /* SYS_read */
{
int fd = cpu.asregs.regs[2];
- char *buf = &memory[cpu.asregs.regs[3]];
unsigned len = (unsigned) cpu.asregs.regs[4];
+ char *buf = malloc (len);
cpu.asregs.regs[2] = read (fd, buf, len);
+ sim_core_write_buffer (sd, scpu, write_map, buf,
+ cpu.asregs.regs[3], len);
+ free (buf);
break;
}
case 0x5: /* SYS_write */
{
- char *str = &memory[cpu.asregs.regs[3]];
+ char *str;
/* String length is at 0x12($fp) */
unsigned count, len = (unsigned) cpu.asregs.regs[4];
+ str = malloc (len);
+ sim_core_read_buffer (sd, scpu, read_map, str,
+ cpu.asregs.regs[3], len);
count = write (cpu.asregs.regs[2], str, len);
+ free (str);
cpu.asregs.regs[2] = count;
break;
}
{
unsigned int handler = cpu.asregs.sregs[1];
unsigned int sp = cpu.asregs.regs[1];
- cpu.asregs.sregs[2] = 3; /* MOXIE_EX_SWI */
/* Save a slot for the static chain. */
sp -= 4;
/* Push the return address. */
sp -= 4;
- wlat (opc, sp, pc + 6);
+ wlat (scpu, opc, sp, pc + 6);
/* Push the current frame pointer. */
sp -= 4;
- wlat (opc, sp, cpu.asregs.regs[0]);
+ wlat (scpu, opc, sp, cpu.asregs.regs[0]);
/* Uncache the stack pointer and set the fp & pc. */
cpu.asregs.regs[1] = sp;
int b = inst & 0xf;
int av = cpu.asregs.regs[a];
int bv = cpu.asregs.regs[b];
- TRACE("div.l");
+
+ MOXIE_TRACE_INSN ("div.l");
cpu.asregs.regs[a] = av / bv;
}
break;
int b = inst & 0xf;
unsigned int av = cpu.asregs.regs[a];
unsigned int bv = cpu.asregs.regs[b];
- TRACE("udiv.l");
+
+ MOXIE_TRACE_INSN ("udiv.l");
cpu.asregs.regs[a] = (av / bv);
}
break;
int b = inst & 0xf;
int av = cpu.asregs.regs[a];
int bv = cpu.asregs.regs[b];
- TRACE("mod.l");
+
+ MOXIE_TRACE_INSN ("mod.l");
cpu.asregs.regs[a] = av % bv;
}
break;
int b = inst & 0xf;
unsigned int av = cpu.asregs.regs[a];
unsigned int bv = cpu.asregs.regs[b];
- TRACE("umod.l");
+
+ MOXIE_TRACE_INSN ("umod.l");
cpu.asregs.regs[a] = (av % bv);
}
break;
case 0x35: /* brk */
- TRACE("brk");
- cpu.asregs.exception = SIGTRAP;
+ MOXIE_TRACE_INSN ("brk");
+ sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGTRAP);
pc -= 2; /* Adjust pc */
break;
case 0x36: /* ldo.b */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_OFFSET(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
- TRACE("ldo.b");
+
+ MOXIE_TRACE_INSN ("ldo.b");
addr += cpu.asregs.regs[b];
- cpu.asregs.regs[a] = rbat(opc, addr);
- pc += 4;
+ cpu.asregs.regs[a] = rbat (scpu, opc, addr);
+ pc += 2;
}
break;
case 0x37: /* sto.b */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_OFFSET(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
- TRACE("sto.b");
+
+ MOXIE_TRACE_INSN ("sto.b");
addr += cpu.asregs.regs[a];
- wbat(opc, addr, cpu.asregs.regs[b]);
- pc += 4;
+ wbat (scpu, opc, addr, cpu.asregs.regs[b]);
+ pc += 2;
}
break;
case 0x38: /* ldo.s */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_OFFSET(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
- TRACE("ldo.s");
+
+ MOXIE_TRACE_INSN ("ldo.s");
addr += cpu.asregs.regs[b];
- cpu.asregs.regs[a] = rsat(opc, addr);
- pc += 4;
+ cpu.asregs.regs[a] = rsat (scpu, opc, addr);
+ pc += 2;
}
break;
case 0x39: /* sto.s */
{
- unsigned int addr = EXTRACT_WORD(&memory[pc+2]);
+ unsigned int addr = EXTRACT_OFFSET(pc+2);
int a = (inst >> 4) & 0xf;
int b = inst & 0xf;
- TRACE("sto.s");
+
+ MOXIE_TRACE_INSN ("sto.s");
addr += cpu.asregs.regs[a];
- wsat(opc, addr, cpu.asregs.regs[b]);
- pc += 4;
+ wsat (scpu, opc, addr, cpu.asregs.regs[b]);
+ pc += 2;
}
break;
default:
opc = opcode;
- TRACE("SIGILL1");
- cpu.asregs.exception = SIGILL;
+ MOXIE_TRACE_INSN ("SIGILL1");
+ sim_engine_halt (sd, scpu, NULL, pc, sim_stopped, SIM_SIGILL);
break;
}
}
- insts++;
+ cpu.asregs.insts++;
pc += 2;
+ cpu.asregs.regs[PC_REGNO] = pc;
- } while (!cpu.asregs.exception);
-
- /* Hide away the things we've cached while executing. */
- cpu.asregs.regs[PC_REGNO] = pc;
- cpu.asregs.insts += insts; /* instructions done ... */
+ if (sim_events_tick (sd))
+ sim_events_process (sd);
- signal (SIGINT, sigsave);
+ } while (1);
}
-int
-sim_write (sd, addr, buffer, size)
- SIM_DESC sd;
- SIM_ADDR addr;
- unsigned char * buffer;
- int size;
+static int
+moxie_reg_store (SIM_CPU *scpu, int rn, unsigned char *memory, int length)
{
- int i;
- init_pointers ();
-
- memcpy (& cpu.asregs.memory[addr], buffer, size);
-
- return size;
-}
-
-int
-sim_read (sd, addr, buffer, size)
- SIM_DESC sd;
- SIM_ADDR addr;
- unsigned char * buffer;
- int size;
-{
- int i;
- init_pointers ();
-
- memcpy (buffer, & cpu.asregs.memory[addr], size);
-
- return size;
-}
-
-
-int
-sim_store_register (sd, rn, memory, length)
- SIM_DESC sd;
- int rn;
- unsigned char * memory;
- int length;
-{
- init_pointers ();
-
if (rn < NUM_MOXIE_REGS && rn >= 0)
{
if (length == 4)
return 0;
}
-int
-sim_fetch_register (sd, rn, memory, length)
- SIM_DESC sd;
- int rn;
- unsigned char * memory;
- int length;
+static int
+moxie_reg_fetch (SIM_CPU *scpu, int rn, unsigned char *memory, int length)
{
- init_pointers ();
-
if (rn < NUM_MOXIE_REGS && rn >= 0)
{
if (length == 4)
return 0;
}
-
-int
-sim_trace (sd)
- SIM_DESC sd;
+static sim_cia
+moxie_pc_get (sim_cpu *cpu)
{
- if (tracefile == 0)
- tracefile = fopen("trace.csv", "wb");
+ return cpu->registers[PCIDX];
+}
- tracing = 1;
-
- sim_resume (sd, 0, 0);
+static void
+moxie_pc_set (sim_cpu *cpu, sim_cia pc)
+{
+ cpu->registers[PCIDX] = pc;
+}
- tracing = 0;
-
- return 1;
+static void
+free_state (SIM_DESC sd)
+{
+ if (STATE_MODULES (sd) != NULL)
+ sim_module_uninstall (sd);
+ sim_cpu_free_all (sd);
+ sim_state_free (sd);
}
-void
-sim_stop_reason (sd, reason, sigrc)
- SIM_DESC sd;
- enum sim_stop * reason;
- int * sigrc;
+SIM_DESC
+sim_open (SIM_OPEN_KIND kind, host_callback *cb,
+ struct bfd *abfd, char * const *argv)
{
- if (cpu.asregs.exception == SIGQUIT)
+ int i;
+ SIM_DESC sd = sim_state_alloc (kind, cb);
+ SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
+
+ /* The cpu data is kept in a separately allocated chunk of memory. */
+ if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
{
- * reason = sim_exited;
- * sigrc = cpu.asregs.regs[2];
+ free_state (sd);
+ return 0;
}
- else
+
+ STATE_WATCHPOINTS (sd)->pc = &cpu.asregs.regs[PC_REGNO];
+ STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (word);
+
+ if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
{
- * reason = sim_stopped;
- * sigrc = cpu.asregs.exception;
+ free_state (sd);
+ return 0;
}
-}
+ /* The parser will print an error message for us, so we silently return. */
+ if (sim_parse_args (sd, argv) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
-int
-sim_stop (sd)
- SIM_DESC sd;
-{
- cpu.asregs.exception = SIGINT;
- return 1;
-}
+ sim_do_command(sd," memory region 0x00000000,0x4000000") ;
+ sim_do_command(sd," memory region 0xE0000000,0x10000") ;
+ /* Check for/establish the a reference program image. */
+ if (sim_analyze_program (sd,
+ (STATE_PROG_ARGV (sd) != NULL
+ ? *STATE_PROG_ARGV (sd)
+ : NULL), abfd) != SIM_RC_OK)
+ {
+ free_state (sd);
+ return 0;
+ }
-void
-sim_info (sd, verbose)
- SIM_DESC sd;
- int verbose;
-{
- callback->printf_filtered (callback, "\n\n# instructions executed %llu\n",
- cpu.asregs.insts);
-}
+ /* Configure/verify the target byte order and other runtime
+ configuration options. */
+ if (sim_config (sd) != SIM_RC_OK)
+ {
+ sim_module_uninstall (sd);
+ return 0;
+ }
+ if (sim_post_argv_init (sd) != SIM_RC_OK)
+ {
+ /* Uninstall the modules to avoid memory leaks,
+ file descriptor leaks, etc. */
+ sim_module_uninstall (sd);
+ return 0;
+ }
-SIM_DESC
-sim_open (kind, cb, abfd, argv)
- SIM_OPEN_KIND kind;
- host_callback * cb;
- struct bfd * abfd;
- char ** argv;
-{
- int osize = sim_memory_size;
- myname = argv[0];
- callback = cb;
-
- if (kind == SIM_OPEN_STANDALONE)
- issue_messages = 1;
-
- /* Discard and reacquire memory -- start with a clean slate. */
- sim_size (1); /* small */
- sim_size (osize); /* and back again */
+ /* CPU specific initialization. */
+ for (i = 0; i < MAX_NR_PROCESSORS; ++i)
+ {
+ SIM_CPU *cpu = STATE_CPU (sd, i);
- set_initial_gprs (); /* Reset the GPR registers. */
-
- /* Fudge our descriptor for now. */
- return (SIM_DESC) 1;
-}
+ CPU_REG_FETCH (cpu) = moxie_reg_fetch;
+ CPU_REG_STORE (cpu) = moxie_reg_store;
+ CPU_PC_FETCH (cpu) = moxie_pc_get;
+ CPU_PC_STORE (cpu) = moxie_pc_set;
-void
-sim_close (sd, quitting)
- SIM_DESC sd;
- int quitting;
-{
- /* nothing to do */
-}
+ set_initial_gprs (); /* Reset the GPR registers. */
+ }
-SIM_RC
-sim_load (sd, prog, abfd, from_tty)
- SIM_DESC sd;
- char * prog;
- bfd * abfd;
- int from_tty;
-{
+ return sd;
+}
- /* Do the right thing for ELF executables; this turns out to be
- just about the right thing for any object format that:
- - we crack using BFD routines
- - follows the traditional UNIX text/data/bss layout
- - calls the bss section ".bss". */
-
- extern bfd * sim_load_file (); /* ??? Don't know where this should live. */
- bfd * prog_bfd;
-
- {
- bfd * handle;
- handle = bfd_openr (prog, 0); /* could be "moxie" */
-
- if (!handle)
- {
- printf("``%s'' could not be opened.\n", prog);
- return SIM_RC_FAIL;
- }
-
- /* Makes sure that we have an object file, also cleans gets the
- section headers in place. */
- if (!bfd_check_format (handle, bfd_object))
- {
- /* wasn't an object file */
- bfd_close (handle);
- printf ("``%s'' is not appropriate object file.\n", prog);
- return SIM_RC_FAIL;
- }
-
- /* Clean up after ourselves. */
- bfd_close (handle);
- }
-
- /* from sh -- dac */
- prog_bfd = sim_load_file (sd, myname, callback, prog, abfd,
- sim_kind == SIM_OPEN_DEBUG,
- 0, sim_write);
- if (prog_bfd == NULL)
- return SIM_RC_FAIL;
-
- if (abfd == NULL)
- bfd_close (prog_bfd);
+/* Load the device tree blob. */
- return SIM_RC_OK;
+static void
+load_dtb (SIM_DESC sd, const char *filename)
+{
+ int size = 0;
+ FILE *f = fopen (filename, "rb");
+ char *buf;
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
+
+ /* Don't warn as the sim works fine w/out a device tree. */
+ if (f == NULL)
+ return;
+ fseek (f, 0, SEEK_END);
+ size = ftell(f);
+ fseek (f, 0, SEEK_SET);
+ buf = alloca (size);
+ if (size != fread (buf, 1, size, f))
+ {
+ sim_io_eprintf (sd, "ERROR: error reading ``%s''.\n", filename);
+ fclose (f);
+ return;
+ }
+ sim_core_write_buffer (sd, scpu, write_map, buf, 0xE0000000, size);
+ cpu.asregs.sregs[9] = 0xE0000000;
+ fclose (f);
}
SIM_RC
-sim_create_inferior (sd, prog_bfd, argv, env)
- SIM_DESC sd;
- struct bfd * prog_bfd;
- char ** argv;
- char ** env;
+sim_create_inferior (SIM_DESC sd, struct bfd *prog_bfd,
+ char * const *argv, char * const *env)
{
char ** avp;
int l, argc, i, tp;
+ sim_cpu *scpu = STATE_CPU (sd, 0); /* FIXME */
- /* Set the initial register set. */
- l = issue_messages;
- issue_messages = 0;
- set_initial_gprs ();
- issue_messages = l;
-
- cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
+ if (prog_bfd != NULL)
+ cpu.asregs.regs[PC_REGNO] = bfd_get_start_address (prog_bfd);
/* Copy args into target memory. */
avp = argv;
- for (argc = 0; *avp; avp++)
+ for (argc = 0; avp && *avp; avp++)
argc++;
/* Target memory looks like this:
0x0000???? zero word
0x0000???? start of data pointed to by argv */
- wlat (0, 0, 0);
- wlat (0, 4, argc);
+ wlat (scpu, 0, 0, 0);
+ wlat (scpu, 0, 4, argc);
/* tp is the offset of our first argv data. */
tp = 4 + 4 + argc * 4 + 4;
for (i = 0; i < argc; i++)
{
/* Set the argv value. */
- wlat (0, 4 + 4 + i * 4, tp);
+ wlat (scpu, 0, 4 + 4 + i * 4, tp);
/* Store the string. */
- strcpy (&cpu.asregs.memory[tp], argv[i]);
+ sim_core_write_buffer (sd, scpu, write_map, argv[i],
+ tp, strlen(argv[i])+1);
tp += strlen (argv[i]) + 1;
}
- wlat (0, 4 + 4 + i * 4, 0);
+ wlat (scpu, 0, 4 + 4 + i * 4, 0);
- return SIM_RC_OK;
-}
+ load_dtb (sd, DTB);
-void
-sim_kill (sd)
- SIM_DESC sd;
-{
- if (tracefile)
- fclose(tracefile);
-}
-
-void
-sim_do_command (sd, cmd)
- SIM_DESC sd;
- char * cmd;
-{
- /* Nothing there yet; it's all an error. */
-
- if (cmd != NULL)
- {
- char ** simargv = buildargv (cmd);
- if (strcmp (simargv[0], "verbose") == 0)
- {
- issue_messages = 2;
- }
- else
- {
- fprintf (stderr,"Error: \"%s\" is not a valid moxie simulator command.\n",
- cmd);
- }
- }
- else
- {
- fprintf (stderr, "moxie sim commands: \n");
- fprintf (stderr, " verbose\n");
- }
-}
-
-void
-sim_set_callbacks (ptr)
- host_callback * ptr;
-{
- callback = ptr;
+ return SIM_RC_OK;
}