$Revision$
$Author$
- $Date$
+ $Date$
NOTEs:
#include "getopt.h"
#include "libiberty.h"
-#include "remote-sim.h" /* GDB simulator interface */
#include "callback.h" /* GDB simulator callback interface */
+#include "remote-sim.h" /* GDB simulator interface */
#include "support.h" /* internal support manifests */
order that the tools are built, we cannot rely on a configured GDB
world whilst constructing the simulator. This means we have to
assume the GDB register number mapping. */
+#ifndef TM_MIPS_H
#define LAST_EMBED_REGNUM (89)
+#endif
/* To keep this default simulator simple, and fast, we use a direct
vector of registers. The internal simulator engine then uses
static int pending_slot_reg[PSLOTS];
static ut_reg pending_slot_value[PSLOTS];
+/*---------------------------------------------------------------------------*/
+/*-- GDB simulator interface ------------------------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+static void dotrace PARAMS((FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...));
+static void sim_warning PARAMS((char *fmt,...));
+extern void sim_error PARAMS((char *fmt,...));
+static void ColdReset PARAMS((void));
+static int AddressTranslation PARAMS((uword64 vAddr,int IorD,int LorS,uword64 *pAddr,int *CCA,int host,int raw));
+static void StoreMemory PARAMS((int CCA,int AccessLength,uword64 MemElem,uword64 pAddr,uword64 vAddr,int raw));
+static uword64 LoadMemory PARAMS((int CCA,int AccessLength,uword64 pAddr,uword64 vAddr,int IorD,int raw));
+static void SignalException PARAMS((int exception,...));
+static void simulate PARAMS((void));
+static long getnum PARAMS((char *value));
+extern void sim_size PARAMS((unsigned int newsize));
+extern void sim_set_profile PARAMS((int frequency));
+static unsigned int power2 PARAMS((unsigned int value));
+
+/*---------------------------------------------------------------------------*/
+
/* The following are not used for MIPS IV onwards: */
#define PENDING_FILL(r,v) {\
/* printf("DBG: FILL BEFORE pending_in = %d, pending_out = %d, pending_total = %d\n",pending_in,pending_out,pending_total); */\
/*-- GDB simulator interface ------------------------------------------------*/
/*---------------------------------------------------------------------------*/
-static void dotrace PARAMS((FILE *tracefh,int type,unsigned int address,int width,char *comment,...));
-static void sim_warning PARAMS((char *fmt,...));
-extern void sim_error PARAMS((char *fmt,...));
-static void ColdReset PARAMS((void));
-static int AddressTranslation PARAMS((uword64 vAddr,int IorD,int LorS,uword64 *pAddr,int *CCA,int host,int raw));
-static void StoreMemory PARAMS((int CCA,int AccessLength,uword64 MemElem,uword64 pAddr,uword64 vAddr,int raw));
-static uword64 LoadMemory PARAMS((int CCA,int AccessLength,uword64 pAddr,uword64 vAddr,int IorD,int raw));
-static void SignalException PARAMS((int exception,...));
-static void simulate PARAMS((void));
-static long getnum PARAMS((char *value));
-extern void sim_size PARAMS((unsigned int newsize));
-extern void sim_set_profile PARAMS((int frequency));
-static unsigned int power2 PARAMS((unsigned int value));
-
-/*---------------------------------------------------------------------------*/
-
void
sim_open (args)
char *args;
if (!monitor) {
fprintf(stderr,"Not enough VM for monitor simulation (%d bytes)\n",monitor_size);
} else {
- int loop;
+ unsigned loop;
/* Entry into the IDT monitor is via fixed address vectors, and
not using machine instructions. To avoid clashing with use of
the MIPS TRAP system, we place our own (simulator specific)
value = 17;
break;
}
- value = (monitor_base + (value * 8));
+ /* FIXME - should monitor_base be SIM_ADDR?? */
+ value = ((unsigned int)monitor_base + (value * 8));
if (AddressTranslation(vaddr,isDATA,isSTORE,&paddr,&cca,isTARGET,isRAW))
StoreMemory(cca,AccessLength_WORD,value,paddr,vaddr,isRAW);
else
if ((state & simPROFILE) && (profile_hist != NULL)) {
unsigned short *p = profile_hist;
FILE *pf = fopen("gmon.out","wb");
- int loop;
+ unsigned loop;
if (pf == NULL)
sim_warning("Failed to open \"gmon.out\" profile file");
#endif /* PROFILE */
#if defined(TRACE)
- if (tracefh != stderr)
+ if (tracefh != NULL && tracefh != stderr)
fclose(tracefh);
+ tracefh = NULL;
state &= ~simTRACE;
#endif /* TRACE */
sim_warning("Invalid register width for %d (register fetch ignored)",rn);
else {
if (register_widths[rn] == 32)
- *((unsigned int *)memory) = host_swap_word(registers[rn] & 0xFFFFFFFF);
+ *((unsigned int *)memory) = host_swap_word((unsigned int)(registers[rn] & 0xFFFFFFFF));
else /* 64bit register */
*((uword64 *)memory) = host_swap_long(registers[rn]);
}
return;
}
-int
+ut_reg
sim_get_quit_code ()
{
/* The standard MIPS PCS (Procedure Calling Standard) uses V0(r2) as
switch (reason) {
case 6: /* int open(char *path,int flags) */
{
- const char *ptr;
uword64 paddr;
int cca;
if (AddressTranslation(A0,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
case 7: /* int read(int file,char *ptr,int len) */
{
- const char *ptr;
uword64 paddr;
int cca;
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
case 8: /* int write(int file,char *ptr,int len) */
{
- const char *ptr;
uword64 paddr;
int cca;
if (AddressTranslation(A1,isDATA,isLOAD,&paddr,&cca,isHOST,isREAL))
char tmp;
if (callback->read_stdin(callback,&tmp,sizeof(char)) != sizeof(char)) {
sim_error("Invalid return from character read");
- V0 = -1;
+ V0 = (ut_reg)-1;
}
else
- V0 = tmp;
+ V0 = (ut_reg)tmp;
}
break;
}
}
if (strchr ("dobxXu", *s)) {
- long long lv = (long long)*ap++;
+ word64 lv = (word64) *ap++;
if (*s == 'b')
callback->printf_filtered(callback,"<binary not supported>");
else {
callback->printf_filtered(callback,tmp,(int)lv);
}
} else if (strchr ("eEfgG", *s)) {
+#ifdef _MSC_VER /* MSVC version 2.x can't convert from uword64 directly */
+ double dbl = (double)((word64)*ap++);
+#else
double dbl = (double)*ap++;
+#endif
sprintf(tmp,"%%%d.%d%c",width,trunc,*s);
callback->printf_filtered(callback,tmp,dbl);
trunc = 0;
}
void
+#ifdef _MSC_VER
+sim_warning(char *fmt,...)
+#else
sim_warning(fmt)
char *fmt;
+#endif
{
va_list ap;
va_start(ap,fmt);
}
void
+#ifdef _MSC_VER
+sim_error(char *fmt,...)
+#else
sim_error(fmt)
char *fmt;
+#endif
{
va_list ap;
va_start(ap,fmt);
to construct an end product, rather than a processor). They
currently have an ARM version of their tool called ChARM. */
+
static
+#ifdef _MSC_VER
+void dotrace(FILE *tracefh,int type,SIM_ADDR address,int width,char *comment,...)
+#else
void dotrace(tracefh,type,address,width,comment)
FILE *tracefh;
int type;
- unsigned int address;
+ SIM_ADDR address;
int width;
char *comment;
+#endif
{
if (state & simTRACE) {
va_list ap;
- fprintf(tracefh,"%d %08x ; width %d ; ",type,address,width);
+ fprintf(tracefh,"%d %08x%08x ; width %d ; ",
+ type,(unsigned long)(address>>32),(unsigned long)(address&0xffffffff),width);
va_start(ap,comment);
fprintf(tracefh,comment,ap);
va_end(ap);
simulation, at the cost of increasing the image and source size. */
static unsigned int
+#ifdef _MSC_VER
+xfer_direct_word(unsigned char *memory)
+#else
xfer_direct_word(memory)
unsigned char *memory;
+#endif
{
return *((unsigned int *)memory);
}
static uword64
+#ifdef _MSC_VER
+xfer_direct_long(unsigned char *memory)
+#else
xfer_direct_long(memory)
unsigned char *memory;
+#endif
{
return *((uword64 *)memory);
}
static unsigned int
+#ifdef _MSC_VER
+swap_direct_word(unsigned int data)
+#else
swap_direct_word(data)
unsigned int data;
+#endif
{
return data;
}
static uword64
+#ifdef _MSC_VER
+swap_direct_long(uword64 data)
+#else
swap_direct_long(data)
uword64 data;
+#endif
{
return data;
}
static unsigned int
+#ifdef _MSC_VER
+xfer_big_word(unsigned char *memory)
+#else
xfer_big_word(memory)
unsigned char *memory;
+#endif
{
return ((memory[0] << 24) | (memory[1] << 16) | (memory[2] << 8) | memory[3]);
}
static uword64
+#ifdef _MSC_VER
+xfer_big_long(unsigned char *memory)
+#else
xfer_big_long(memory)
unsigned char *memory;
+#endif
{
return (((uword64)memory[0] << 56) | ((uword64)memory[1] << 48)
| ((uword64)memory[2] << 40) | ((uword64)memory[3] << 32)
- | (memory[4] << 24) | (memory[5] << 16) | (memory[6] << 8) | memory[7]);
+ | ((uword64)memory[4] << 24) | ((uword64)memory[5] << 16)
+ | ((uword64)memory[6] << 8) | ((uword64)memory[7]));
}
static unsigned int
+#ifdef _MSC_VER
+xfer_little_word(unsigned char *memory)
+#else
xfer_little_word(memory)
unsigned char *memory;
+#endif
{
return ((memory[3] << 24) | (memory[2] << 16) | (memory[1] << 8) | memory[0]);
}
static uword64
+#ifdef _MSC_VER
+xfer_little_long(unsigned char *memory)
+#else
xfer_little_long(memory)
unsigned char *memory;
+#endif
{
return (((uword64)memory[7] << 56) | ((uword64)memory[6] << 48)
| ((uword64)memory[5] << 40) | ((uword64)memory[4] << 32)
- | (memory[3] << 24) | (memory[2] << 16) | (memory[1] << 8) | memory[0]);
+ | ((uword64)memory[3] << 24) | ((uword64)memory[2] << 16)
+ | ((uword64)memory[1] << 8) | (uword64)memory[0]);
}
static unsigned int
+#ifdef _MSC_VER
+swap_word(unsigned int data)
+#else
swap_word(data)
unsigned int data;
+#endif
{
unsigned int result;
result = data ^ ((data << 16) | (data >> 16));
}
static uword64
+#ifdef _MSC_VER
+swap_long(uword64 data)
+#else
swap_long(data)
uword64 data;
+#endif
{
unsigned int tmphi = WORD64HI(data);
unsigned int tmplo = WORD64LO(data);
sim_warning("Failed: AddressTranslation(0x%08X%08X,%s,%s,...) IPC = 0x%08X%08X",WORD64HI(vAddr),WORD64LO(vAddr),(IorD ? "isDATA" : "isINSTRUCTION"),(LorS ? "isSTORE" : "isLOAD"),WORD64HI(IPC),WORD64LO(IPC));
#endif /* DEBUG */
res = 0; /* AddressTranslation has failed */
- *pAddr = -1;
+ *pAddr = (SIM_ADDR)-1;
if (!raw) /* only generate exceptions on real memory transfers */
SignalException((LorS == isSTORE) ? AddressStore : AddressLoad);
else
that aborts the instruction. The instruction operation pseudocode
will never see a return from this function call. */
static void
+#ifdef _MSC_VER
+SignalException (int exception,...)
+#else
SignalException(exception)
int exception;
+#endif
{
/* Ensure that any active atomic read/modify/write operation will fail: */
LLBIT = 0;
}
default:
-#if 1 /* def DEBUG */
+#ifdef DEBUG
if (exception != BreakPoint)
callback->printf_filtered(callback,"DBG: SignalException(%d) IPC = 0x%08X%08X\n",exception,WORD64HI(IPC),WORD64LO(IPC));
#endif /* DEBUG */
/* TODO: If not simulating exceptions then stop the simulator
execution. At the moment we always stop the simulation. */
-#if 1 /* bodge to allow exit() code to be returned, by assuming that a breakpoint exception after a monitor exit() call should be silent */
-/* further bodged since the standard libgloss/mips world doesn't use the _exit() monitor call, it just uses a break instruction */
- if (exception == BreakPoint /* && state & simEXIT */)
- {
- state |= simSTOP;
-#if 1 /* since the _exit() monitor call may not be called */
- state |= simEXIT;
- rcexit = (unsigned int)(A0 & 0xFFFFFFFF);
-#endif
- }
- else
- state |= (simSTOP | simEXCEPTION);
-#else
state |= (simSTOP | simEXCEPTION);
-#endif
+
+ /* Keep a copy of the current A0 in-case this is the program exit
+ breakpoint: */
+ if (exception == BreakPoint) {
+ va_list ap;
+ unsigned int instruction;
+ va_start(ap,exception);
+ instruction = va_arg(ap,unsigned int);
+ va_end(ap);
+ /* Check for our special terminating BREAK: */
+ if ((instruction & 0x03FFFFC0) == 0x03ff0000) {
+ rcexit = (unsigned int)(A0 & 0xFFFFFFFF);
+ state &= ~simEXCEPTION;
+ state |= simEXIT;
+ }
+ }
+
+ /* Store exception code into current exception id variable (used
+ by exit code): */
CAUSE = (exception << 2);
if (state & simDELAYSLOT) {
CAUSE |= cause_BD;
case fmt_single:
{
unsigned int wop = (unsigned int)op;
+#ifdef HAVE_SQRT
float tmp = ((float)sqrt((double)*(float *)&wop));
result = (uword64)*(unsigned int *)&tmp;
+#else
+ /* TODO: Provide square-root */
+ result = (uword64)0;
+#endif
}
break;
case fmt_double:
{
+#ifdef HAVE_SQRT
double tmp = (sqrt(*(double *)&op));
result = *(uword64 *)&tmp;
+#else
+ /* TODO: Provide square-root */
+ result = (uword64)0;
+#endif
}
break;
}
break;
case fmt_long:
- tmp = (float)((int)op);
+ tmp = (float)((word64)op);
break;
}
case fmt_word:
xxx = SIGNEXTEND((op & 0xFFFFFFFF),32);
- tmp = xxx;
+ tmp = (double)xxx;
break;
case fmt_long:
SignalException(FPE);
} else {
if (to == fmt_word) {
- unsigned int tmp;
+ int tmp;
switch (from) {
case fmt_single:
{
unsigned int wop = (unsigned int)op;
- tmp = (unsigned int)*((float *)&wop);
+ tmp = (int)*((float *)&wop);
}
break;
case fmt_double:
- tmp = (unsigned int)*((double *)&op);
+ tmp = (int)*((double *)&op);
#ifdef DEBUG
printf("DBG: from double %.30f (0x%08X%08X) to word: 0x%08X\n",*((double *)&op),WORD64HI(op),WORD64LO(op),tmp);
#endif /* DEBUG */
}
result = (uword64)tmp;
} else { /* fmt_long */
+ word64 tmp;
switch (from) {
case fmt_single:
{
unsigned int wop = (unsigned int)op;
- result = (uword64)*((float *)&wop);
+ tmp = (word64)*((float *)&wop);
}
break;
case fmt_double:
- result = (uword64)*((double *)&op);
+ tmp = (word64)*((double *)&op);
break;
}
+ result = (uword64)tmp;
}
}
break;
instruction_fetch_overflow++;
#if defined(PROFILE)
if ((state & simPROFILE) && ((instruction_fetches % profile_frequency) == 0) && profile_hist) {
- int n = ((unsigned int)(PC - profile_minpc) >> (profile_shift + 2));
+ unsigned n = ((unsigned int)(PC - profile_minpc) >> (profile_shift + 2));
if (n < profile_nsamples) {
/* NOTE: The counts for the profiling bins are only 16bits wide */
if (profile_hist[n] != USHRT_MAX)