* interp.c (BUSERROR): New macro.
([r|w][bwl]at[little|big]) New functions. (sim_resume): If GO32 check for interrupt every now and again. Decrement PC if SIGBUS seen. * run.c (main): Return result of simulated _exit.
This commit is contained in:
parent
582d2a4d37
commit
4d0be1f5d4
|
@ -1,3 +1,19 @@
|
||||||
|
Wed Dec 28 21:25:31 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
||||||
|
|
||||||
|
* interp.c (BUSERROR): New macro.
|
||||||
|
([r|w][bwl]at[little|big]) New functions.
|
||||||
|
(sim_resume): If GO32 check for interrupt every now
|
||||||
|
and again. Decrement PC if SIGBUS seen.
|
||||||
|
* run.c (main): Return result of simulated _exit.
|
||||||
|
|
||||||
|
Mon Dec 5 21:59:51 1994 Doug Evans <dje@canuck.cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in (gencode): Allow build in different directory.
|
||||||
|
|
||||||
|
Wed Nov 30 17:47:13 1994 Jim Wilson <wilson@chestnut.cygnus.com>
|
||||||
|
|
||||||
|
* Makefile.in (gencode): Change $< to gencode.c for portability.
|
||||||
|
|
||||||
Wed Nov 23 21:31:55 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
Wed Nov 23 21:31:55 1994 Steve Chamberlain (sac@jonny.cygnus.com)
|
||||||
|
|
||||||
* interp.c ([wr][bwl]at): New functions.
|
* interp.c ([wr][bwl]at): New functions.
|
||||||
|
|
599
sim/sh/interp.c
599
sim/sh/interp.c
|
@ -27,7 +27,7 @@
|
||||||
#include "../../newlib/libc/sys/sh/sys/syscall.h"
|
#include "../../newlib/libc/sys/sh/sys/syscall.h"
|
||||||
#define O_RECOMPILE 85
|
#define O_RECOMPILE 85
|
||||||
#define DEFINE_TABLE
|
#define DEFINE_TABLE
|
||||||
|
/*#define ACE_FAST*/
|
||||||
#define DISASSEMBLER_TABLE
|
#define DISASSEMBLER_TABLE
|
||||||
|
|
||||||
#define SBIT(x) ((x)&sbit)
|
#define SBIT(x) ((x)&sbit)
|
||||||
|
@ -51,19 +51,21 @@
|
||||||
#define PC pc
|
#define PC pc
|
||||||
#define C cycles
|
#define C cycles
|
||||||
|
|
||||||
char *fail()
|
int
|
||||||
|
fail ()
|
||||||
{
|
{
|
||||||
|
abort ();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define BUSERROR(addr, mask) \
|
||||||
|
if (addr & ~mask) { saved_state.asregs.exception = SIGBUS;}
|
||||||
|
|
||||||
/* Define this to enable register lifetime checking.
|
/* Define this to enable register lifetime checking.
|
||||||
The compiler generates "add #0,rn" insns to mark registers as invalid,
|
The compiler generates "add #0,rn" insns to mark registers as invalid,
|
||||||
the simulator uses this info to call fail if it finds a ref to an invalid
|
the simulator uses this info to call fail if it finds a ref to an invalid
|
||||||
register before a def
|
register before a def
|
||||||
|
|
||||||
#define PARANOID
|
#define PARANOID
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -78,62 +80,222 @@ int valid[16];
|
||||||
#define UNDEF(x)
|
#define UNDEF(x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
#ifdef TARGET_BIG_ENDIAN
|
#define INLINE inline
|
||||||
#if 0
|
|
||||||
#define LMEM(x) *((long *)(memory+((x)&maskl)))
|
|
||||||
#define BMEM(x) *((char *)(memory+((x)&maskb)))
|
|
||||||
#define UWMEM(x) *((unsigned short *)(memory+((x)&maskw)))
|
|
||||||
#define SWMEM(x) *((short *)(memory+((x)&maskw)))
|
|
||||||
#define WLAT(x,value) (LMEM(x) = value)
|
|
||||||
#define RLAT(x) (LMEM(x))
|
|
||||||
#define WWAT(x,value) (UWMEM(x) = value)
|
|
||||||
#define RSWAT(x) (SWMEM(x))
|
|
||||||
#define RUWAT(x) (UWMEM(x))
|
|
||||||
#define WBAT(x,value) (BMEM(x) = value)
|
|
||||||
#define RBAT(x) (BMEM(x))
|
|
||||||
#else
|
#else
|
||||||
#define LMEM(x) ((x)&maskl ? fail() : *((long *)(memory+((x)&maskl))))
|
#define INLINE
|
||||||
#define BMEM(x) ((x) &maskb ? fail() : *((char *)(memory+((x)&maskb))))
|
|
||||||
#define UWMEM(x) ((x)&maskw ? fail() : *((unsigned short *)(memory+((x)&maskw))))
|
|
||||||
#define SWMEM(x) ((x)&maskw ? fail() : *((short *)(memory+((x)&maskw))))
|
|
||||||
#define WLAT(x,value) (LMEM(x) = value)
|
|
||||||
#define RLAT(x) (LMEM(x))
|
|
||||||
#define WWAT(x,value) (UWMEM(x) = value)
|
|
||||||
#define RSWAT(x) (SWMEM(x))
|
|
||||||
#define RUWAT(x) (UWMEM(x))
|
|
||||||
#define WBAT(x,value) (BMEM(x) = value)
|
|
||||||
#define RBAT(x) (BMEM(x))
|
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
/* For little endian or unknown host machines */
|
|
||||||
#define WLAT(x,value)\
|
|
||||||
{ int v = value; unsigned char *p = memory + ((x) & maskl);\
|
|
||||||
p[0] =v>>24;p[1] = v>>16;p[2]=v>>8;p[3]=v; }
|
|
||||||
|
|
||||||
#define WWAT(x,value)\
|
/* These variables are at file scope so that functions other than
|
||||||
{ int v = value; unsigned char *p = memory + (x & maskw);p[0] =v>>8;p[1] = v ;}
|
sim_resume can use the fetch/store macros */
|
||||||
|
|
||||||
#define WBAT(x,value)\
|
static int little_endian;
|
||||||
{ unsigned char *p = memory + (x & maskb);p[0] =value;}
|
|
||||||
|
|
||||||
#define RLAT(x)\
|
#if 1
|
||||||
((memory[x&maskl]<<24)|(memory[(x&maskl)+1]<<16)|(memory[(x&maskl)+2]<<8)| (memory[(x&maskl)+3]))
|
static int maskl = ~0;
|
||||||
|
static int maskw = ~0;
|
||||||
|
#endif
|
||||||
|
typedef union
|
||||||
|
{
|
||||||
|
|
||||||
#define RWAT(x)\
|
struct
|
||||||
((memory[x&maskw]<<8)|(memory[(x&maskw)+1]))
|
{
|
||||||
|
|
||||||
#define RBAT(x)\
|
int regs[16];
|
||||||
((memory[x&maskb]))
|
int pc;
|
||||||
|
int pr;
|
||||||
|
|
||||||
|
int gbr;
|
||||||
|
int vbr;
|
||||||
|
int mach;
|
||||||
|
int macl;
|
||||||
|
|
||||||
|
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
unsigned int d0:22;
|
||||||
|
unsigned int m:1;
|
||||||
|
unsigned int q:1;
|
||||||
|
unsigned int i:4;
|
||||||
|
unsigned int d1:2;
|
||||||
|
unsigned int s:1;
|
||||||
|
unsigned int t:1;
|
||||||
|
}
|
||||||
|
bits;
|
||||||
|
int word;
|
||||||
|
}
|
||||||
|
sr;
|
||||||
|
int ticks;
|
||||||
|
int stalls;
|
||||||
|
int cycles;
|
||||||
|
int insts;
|
||||||
|
|
||||||
|
|
||||||
|
int prevlock;
|
||||||
|
int thislock;
|
||||||
|
int exception;
|
||||||
|
int msize;
|
||||||
|
#define PROFILE_FREQ 1
|
||||||
|
#define PROFILE_SHIFT 2
|
||||||
|
int profile;
|
||||||
|
unsigned short *profile_hist;
|
||||||
|
unsigned char *memory;
|
||||||
|
|
||||||
|
}
|
||||||
|
asregs;
|
||||||
|
int asints[28];
|
||||||
|
|
||||||
|
} saved_state_type;
|
||||||
|
saved_state_type saved_state;
|
||||||
|
|
||||||
|
static void INLINE
|
||||||
|
wlat_little (memory, x, value, maskl)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
int v = value;
|
||||||
|
unsigned char *p = memory + ((x) & maskl);
|
||||||
|
BUSERROR(x, maskl);
|
||||||
|
p[3] = v >> 24;
|
||||||
|
p[2] = v >> 16;
|
||||||
|
p[1] = v >> 8;
|
||||||
|
p[0] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void INLINE
|
||||||
|
wwat_little (memory, x, value, maskw)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
int v = value;
|
||||||
|
unsigned char *p = memory + ((x) & maskw);
|
||||||
|
BUSERROR(x, maskw);
|
||||||
|
|
||||||
|
p[1] = v >> 8;
|
||||||
|
p[0] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void INLINE
|
||||||
|
wbat_any (memory, x, value, maskb)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + (x & maskb);
|
||||||
|
if (x > 0x5000000)
|
||||||
|
IOMEM (x, 1, value);
|
||||||
|
BUSERROR(x, maskb);
|
||||||
|
|
||||||
|
p[0] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void INLINE
|
||||||
|
wlat_big (memory, x, value, maskl)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
int v = value;
|
||||||
|
unsigned char *p = memory + ((x) & maskl);
|
||||||
|
BUSERROR(x, maskl);
|
||||||
|
|
||||||
|
p[0] = v >> 24;
|
||||||
|
p[1] = v >> 16;
|
||||||
|
p[2] = v >> 8;
|
||||||
|
p[3] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void INLINE
|
||||||
|
wwat_big (memory, x, value, maskw)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
int v = value;
|
||||||
|
unsigned char *p = memory + ((x) & maskw);
|
||||||
|
BUSERROR(x, maskw);
|
||||||
|
|
||||||
|
p[0] = v >> 8;
|
||||||
|
p[1] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void INLINE
|
||||||
|
wbat_big (memory, x, value, maskb)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + (x & maskb);
|
||||||
|
BUSERROR(x, maskb);
|
||||||
|
|
||||||
|
if (x > 0x5000000)
|
||||||
|
IOMEM (x, 1, value);
|
||||||
|
p[0] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Read functions */
|
||||||
|
static int INLINE
|
||||||
|
rlat_little (memory, x, maskl)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + ((x) & maskl);
|
||||||
|
BUSERROR(x, maskl);
|
||||||
|
|
||||||
|
return (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int INLINE
|
||||||
|
rwat_little (memory, x, maskw)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + ((x) & maskw);
|
||||||
|
BUSERROR(x, maskw);
|
||||||
|
|
||||||
|
return (p[1] << 8) | p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int INLINE
|
||||||
|
rbat_any (memory, x, maskb)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + ((x) & maskb);
|
||||||
|
BUSERROR(x, maskb);
|
||||||
|
|
||||||
|
return p[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
static int INLINE
|
||||||
|
rlat_big (memory, x, maskl)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + ((x) & maskl);
|
||||||
|
BUSERROR(x, maskl);
|
||||||
|
|
||||||
|
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int INLINE
|
||||||
|
rwat_big (memory, x, maskw)
|
||||||
|
unsigned char *memory;
|
||||||
|
{
|
||||||
|
unsigned char *p = memory + ((x) & maskw);
|
||||||
|
BUSERROR(x, maskw);
|
||||||
|
|
||||||
|
return (p[0] << 8) | p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define RWAT(x) (little_endian ? rwat_little(memory, x, maskw): rwat_big(memory, x, maskw))
|
||||||
|
#define RLAT(x) (little_endian ? rlat_little(memory, x, maskl): rlat_big(memory, x, maskl))
|
||||||
|
#define RBAT(x) (rbat_any (memory, x, maskb))
|
||||||
|
#define WWAT(x,v) (little_endian ? wwat_little(memory, x, v, maskw): wwat_big(memory, x, v, maskw))
|
||||||
|
#define WLAT(x,v) (little_endian ? wlat_little(memory, x, v, maskl): wlat_big(memory, x, v, maskl))
|
||||||
|
#define WBAT(x,v) (wbat_any (memory, x, v, maskb))
|
||||||
|
|
||||||
#define RUWAT(x) (RWAT(x) & 0xffff)
|
#define RUWAT(x) (RWAT(x) & 0xffff)
|
||||||
#define RSWAT(x) ((short)(RWAT(x)))
|
#define RSWAT(x) ((short)(RWAT(x)))
|
||||||
#define RSBAT(x) (SEXT(RBAT(x)))
|
#define RSBAT(x) (SEXT(RBAT(x)))
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
|
#define SEXT(x) (((x&0xff) ^ (~0x7f))+0x80)
|
||||||
#define SEXTW(y) ((int)((short)y))
|
#define SEXTW(y) ((int)((short)y))
|
||||||
|
|
||||||
|
@ -154,69 +316,60 @@ int sim_memory_size = 24;
|
||||||
|
|
||||||
static int sim_profile_size = 17;
|
static int sim_profile_size = 17;
|
||||||
static int nsamples;
|
static int nsamples;
|
||||||
static int sim_timeout;
|
|
||||||
|
|
||||||
typedef union
|
#undef TB
|
||||||
|
#define TB(x,y)
|
||||||
|
|
||||||
|
#define SMR1 (0x05FFFEC8) /* Channel 1 serial mode register */
|
||||||
|
#define BRR1 (0x05FFFEC9) /* Channel 1 bit rate register */
|
||||||
|
#define SCR1 (0x05FFFECA) /* Channel 1 serial control register */
|
||||||
|
#define TDR1 (0x05FFFECB) /* Channel 1 transmit data register */
|
||||||
|
#define SSR1 (0x05FFFECC) /* Channel 1 serial status register */
|
||||||
|
#define RDR1 (0x05FFFECD) /* Channel 1 receive data register */
|
||||||
|
|
||||||
|
#define SCI_RDRF 0x40 /* Recieve data register full */
|
||||||
|
#define SCI_TDRE 0x80 /* Transmit data register empty */
|
||||||
|
|
||||||
|
static int
|
||||||
|
IOMEM (addr, write, value)
|
||||||
|
int addr;
|
||||||
|
int write;
|
||||||
|
int value;
|
||||||
{
|
{
|
||||||
|
static int io;
|
||||||
|
static char ssr1;
|
||||||
|
int x;
|
||||||
|
static char lastchar;
|
||||||
|
|
||||||
struct
|
if (write)
|
||||||
{
|
{
|
||||||
|
switch (addr)
|
||||||
int regs[16];
|
|
||||||
int pc;
|
|
||||||
int pr;
|
|
||||||
|
|
||||||
int gbr;
|
|
||||||
int vbr;
|
|
||||||
int mach;
|
|
||||||
int macl;
|
|
||||||
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
{
|
||||||
struct
|
case TDR1:
|
||||||
|
if (value != '\r')
|
||||||
{
|
{
|
||||||
unsigned int d0:22;
|
putchar (value);
|
||||||
unsigned int m:1;
|
fflush (stdout);
|
||||||
unsigned int q:1;
|
|
||||||
unsigned int i:4;
|
|
||||||
unsigned int d1:2;
|
|
||||||
unsigned int s:1;
|
|
||||||
unsigned int t:1;
|
|
||||||
}
|
}
|
||||||
bits;
|
break;
|
||||||
int word;
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (addr)
|
||||||
|
{
|
||||||
|
case RDR1:
|
||||||
|
return getchar ();
|
||||||
}
|
}
|
||||||
sr;
|
|
||||||
int ticks;
|
|
||||||
int stalls;
|
|
||||||
int cycles;
|
|
||||||
int insts;
|
|
||||||
|
|
||||||
|
|
||||||
int prevlock;
|
|
||||||
int thislock;
|
|
||||||
int exception;
|
|
||||||
int msize;
|
|
||||||
#define PROFILE_FREQ 1
|
|
||||||
#define PROFILE_SHIFT 2
|
|
||||||
int profile;
|
|
||||||
unsigned short *profile_hist;
|
|
||||||
unsigned char *memory;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
asregs;
|
|
||||||
int asints[28];
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
saved_state_type;
|
|
||||||
saved_state_type saved_state;
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_now ()
|
get_now ()
|
||||||
{
|
{
|
||||||
return time((long*)0);
|
return time ((long *) 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -229,23 +382,19 @@ now_persec ()
|
||||||
|
|
||||||
static FILE *profile_file;
|
static FILE *profile_file;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
swap (b, n)
|
swap (memory, n)
|
||||||
unsigned char *b;
|
unsigned char *memory;
|
||||||
int n;
|
int n;
|
||||||
{
|
{
|
||||||
b[0] = n >> 24;
|
WLAT (0, n);
|
||||||
b[1] = n >> 16;
|
|
||||||
b[2] = n >> 8;
|
|
||||||
b[3] = n >> 0;
|
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
swap16 (b, n)
|
swap16 (memory, n)
|
||||||
unsigned char *b;
|
unsigned char *memory;
|
||||||
int n;
|
int n;
|
||||||
{
|
{
|
||||||
b[0] = n >> 8;
|
WWAT (0, n);
|
||||||
b[1] = n >> 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -279,32 +428,13 @@ ptr (x)
|
||||||
return (char *) (x + saved_state.asregs.memory);
|
return (char *) (x + saved_state.asregs.memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *wwat(ptr, val)
|
|
||||||
char *ptr;
|
|
||||||
int val;
|
|
||||||
{
|
|
||||||
ptr[0] = val >> 8;
|
|
||||||
ptr[1] = val;
|
|
||||||
return ptr+2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *wlat(ptr,val)
|
|
||||||
char *ptr;
|
|
||||||
int val;
|
|
||||||
{
|
|
||||||
ptr[0] = val>> 24;
|
|
||||||
ptr[1] = val >> 16;
|
|
||||||
ptr[2] = val >>8;
|
|
||||||
ptr[3] = val;
|
|
||||||
return ptr+4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Simulate a monitor trap, put the result into r0 and errno into r1 */
|
/* Simulate a monitor trap, put the result into r0 and errno into r1 */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
trap (i, regs)
|
trap (i, regs, memory, maskl, maskw, little_endian)
|
||||||
int i;
|
int i;
|
||||||
int *regs;
|
int *regs;
|
||||||
|
unsigned char *memory;
|
||||||
{
|
{
|
||||||
switch (i)
|
switch (i)
|
||||||
{
|
{
|
||||||
|
@ -314,6 +444,23 @@ trap (i, regs)
|
||||||
case 2:
|
case 2:
|
||||||
saved_state.asregs.exception = SIGQUIT;
|
saved_state.asregs.exception = SIGQUIT;
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
case 8:
|
||||||
|
trap8 (ptr (regs[4]));
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
trap9 (ptr (regs[4]));
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
trap10 ();
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
regs[0] = trap11 ();
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
regs[0] = trap12 ();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
extern int errno;
|
extern int errno;
|
||||||
|
@ -322,35 +469,38 @@ trap (i, regs)
|
||||||
|
|
||||||
switch (regs[4])
|
switch (regs[4])
|
||||||
{
|
{
|
||||||
#ifndef __GO32__
|
|
||||||
case SYS_fork:
|
|
||||||
regs[0] = fork();
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
#ifndef __GO32__
|
||||||
|
|
||||||
|
case SYS_fork:
|
||||||
|
regs[0] = fork ();
|
||||||
|
break;
|
||||||
case SYS_execve:
|
case SYS_execve:
|
||||||
regs[0] = execve(ptr(regs[5]), ptr(regs[6]), ptr(regs[7]));
|
regs[0] = execve (ptr (regs[5]), ptr (regs[6]), ptr (regs[7]));
|
||||||
break;
|
break;
|
||||||
case SYS_execv:
|
case SYS_execv:
|
||||||
regs[0] = execv(ptr(regs[5]), ptr(regs[6]));
|
regs[0] = execv (ptr (regs[5]), ptr (regs[6]));
|
||||||
break;
|
break;
|
||||||
case SYS_pipe:
|
case SYS_pipe:
|
||||||
{
|
{
|
||||||
char* buf;
|
char *buf;
|
||||||
int host_fd[2];
|
int host_fd[2];
|
||||||
|
|
||||||
buf = ptr(regs[5]);
|
buf = ptr (regs[5]);
|
||||||
|
|
||||||
regs[0] = pipe(host_fd);
|
regs[0] = pipe (host_fd);
|
||||||
|
|
||||||
buf = wlat(buf, host_fd[0]);
|
WLAT (buf, host_fd[0]);
|
||||||
buf = wlat(buf, host_fd[1]);
|
buf += 4;
|
||||||
|
WLAT (buf, host_fd[1]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_wait:
|
case SYS_wait:
|
||||||
regs[0] = wait(ptr(regs[5]));
|
regs[0] = wait (ptr (regs[5]));
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case SYS_read:
|
case SYS_read:
|
||||||
regs[0] = read (regs[5], ptr (regs[6]), regs[7]);
|
regs[0] = read (regs[5], ptr (regs[6]), regs[7]);
|
||||||
break;
|
break;
|
||||||
|
@ -367,53 +517,65 @@ trap (i, regs)
|
||||||
regs[0] = open (ptr (regs[5]), regs[6]);
|
regs[0] = open (ptr (regs[5]), regs[6]);
|
||||||
break;
|
break;
|
||||||
case SYS_exit:
|
case SYS_exit:
|
||||||
/* EXIT */
|
/* EXIT - caller can look in r5 to work out the
|
||||||
|
reason */
|
||||||
saved_state.asregs.exception = SIGQUIT;
|
saved_state.asregs.exception = SIGQUIT;
|
||||||
errno = regs[5];
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SYS_stat: /* added at hmsi */
|
case SYS_stat: /* added at hmsi */
|
||||||
/* stat system call */
|
/* stat system call */
|
||||||
{
|
{
|
||||||
struct stat host_stat;
|
struct stat host_stat;
|
||||||
char *buf;
|
char *buf;
|
||||||
|
|
||||||
regs[0] = stat( ptr(regs[5]), &host_stat);
|
regs[0] = stat (ptr (regs[5]), &host_stat);
|
||||||
|
|
||||||
buf = ptr(regs[6]);
|
buf = ptr (regs[6]);
|
||||||
|
|
||||||
buf = wwat(buf, host_stat.st_dev);
|
WWAT (buf, host_stat.st_dev);
|
||||||
buf = wwat(buf, host_stat.st_ino);
|
buf += 2;
|
||||||
|
WWAT (buf, host_stat.st_ino);
|
||||||
|
buf += 2;
|
||||||
|
WLAT (buf, host_stat.st_mode);
|
||||||
|
buf += 4;
|
||||||
|
WWAT (buf, host_stat.st_nlink);
|
||||||
|
buf += 2;
|
||||||
|
WWAT (buf, host_stat.st_uid);
|
||||||
|
buf += 2;
|
||||||
|
WWAT (buf, host_stat.st_gid);
|
||||||
|
buf += 2;
|
||||||
|
WWAT (buf, host_stat.st_rdev);
|
||||||
|
buf += 2;
|
||||||
|
WLAT (buf, host_stat.st_size);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, host_stat.st_atime);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, 0);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, host_stat.st_mtime);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, 0);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, host_stat.st_ctime);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, 0);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, 0);
|
||||||
|
buf += 4;
|
||||||
|
WLAT (buf, 0);
|
||||||
|
buf += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
buf = wlat(buf, host_stat.st_mode);
|
case SYS_chown:
|
||||||
|
regs[0] = chown (ptr (regs[5]), regs[6], regs[7]);
|
||||||
buf = wwat(buf, host_stat.st_nlink);
|
|
||||||
buf = wwat(buf, host_stat.st_uid);
|
|
||||||
buf = wwat(buf, host_stat.st_gid);
|
|
||||||
buf = wwat(buf, host_stat.st_rdev);
|
|
||||||
|
|
||||||
buf = wlat(buf, host_stat.st_size);
|
|
||||||
buf = wlat(buf, host_stat.st_atime);
|
|
||||||
buf = wlat(buf, 0);
|
|
||||||
buf = wlat(buf, host_stat.st_mtime);
|
|
||||||
buf = wlat(buf, 0);
|
|
||||||
buf = wlat(buf, host_stat.st_ctime);
|
|
||||||
buf = wlat(buf, 0);
|
|
||||||
buf = wlat(buf, host_stat.st_blksize);
|
|
||||||
buf = wlat(buf, host_stat.st_blocks);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SYS_chown:
|
|
||||||
regs[0] = chown( ptr(regs[5]), regs[6], regs[7] );
|
|
||||||
break;
|
break;
|
||||||
case SYS_chmod:
|
case SYS_chmod:
|
||||||
regs[0] = chmod( ptr(regs[5]), regs[6]);
|
regs[0] = chmod (ptr (regs[5]), regs[6]);
|
||||||
break;
|
break;
|
||||||
case SYS_utime:
|
case SYS_utime:
|
||||||
regs[0] = utime (ptr(regs[5]), ptr(regs[6]));
|
regs[0] = utime (ptr (regs[5]), ptr (regs[6]));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
abort ();
|
abort ();
|
||||||
}
|
}
|
||||||
|
@ -423,9 +585,9 @@ trap (i, regs)
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xc3:
|
||||||
case 255:
|
case 255:
|
||||||
saved_state.asregs.exception = SIGTRAP;
|
saved_state.asregs.exception = SIGTRAP;
|
||||||
saved_state.asregs.exception = 5;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +692,7 @@ div1 (R, iRn2, iRn1, T)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dmul (sign, rm, rn)
|
dmul (sign, rm, rn)
|
||||||
int sign;
|
int sign;
|
||||||
unsigned int rm;
|
unsigned int rm;
|
||||||
|
@ -569,7 +731,16 @@ dmul (sign, rm, rn)
|
||||||
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
#ifdef __GNUC__
|
||||||
|
long long res;
|
||||||
|
long long a = rn;
|
||||||
|
long long b = rm;
|
||||||
|
res = a * b;
|
||||||
|
MACH = res >> 32;
|
||||||
|
MACL = res & 0xffffffff;
|
||||||
|
#else
|
||||||
abort ();
|
abort ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -598,7 +769,7 @@ sim_size (power)
|
||||||
if (!saved_state.asregs.memory)
|
if (!saved_state.asregs.memory)
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
"Not enough VM for simuation of %d bytes of RAM\n",
|
"Not enough VM for simulation of %d bytes of RAM\n",
|
||||||
saved_state.asregs.msize);
|
saved_state.asregs.msize);
|
||||||
|
|
||||||
saved_state.asregs.msize = 1;
|
saved_state.asregs.msize = 1;
|
||||||
|
@ -607,11 +778,21 @@ sim_size (power)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extern int target_byte_order;
|
||||||
|
|
||||||
|
static void
|
||||||
|
set_static_little_endian(x)
|
||||||
|
int x;
|
||||||
|
{
|
||||||
|
little_endian = x;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
init_pointers ()
|
init_pointers ()
|
||||||
{
|
{
|
||||||
|
register int little_endian = target_byte_order == 1234;
|
||||||
|
set_static_little_endian (little_endian);
|
||||||
if (saved_state.asregs.msize != 1 << sim_memory_size)
|
if (saved_state.asregs.msize != 1 << sim_memory_size)
|
||||||
{
|
{
|
||||||
sim_size (sim_memory_size);
|
sim_size (sim_memory_size);
|
||||||
|
@ -662,7 +843,7 @@ dump_profile ()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gotcall (from, to)
|
gotcall (from, to)
|
||||||
int from;
|
int from;
|
||||||
int to;
|
int to;
|
||||||
|
@ -674,6 +855,7 @@ gotcall (from, to)
|
||||||
|
|
||||||
#define MMASKB ((saved_state.asregs.msize -1) & ~0)
|
#define MMASKB ((saved_state.asregs.msize -1) & ~0)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sim_resume (step, siggnal)
|
sim_resume (step, siggnal)
|
||||||
int step, siggnal;
|
int step, siggnal;
|
||||||
|
@ -685,6 +867,11 @@ sim_resume (step, siggnal)
|
||||||
register int prevlock;
|
register int prevlock;
|
||||||
register int thislock;
|
register int thislock;
|
||||||
register unsigned int doprofile;
|
register unsigned int doprofile;
|
||||||
|
#ifdef __GO32__
|
||||||
|
register int pollcount = 0;
|
||||||
|
#endif
|
||||||
|
register int little_endian = target_byte_order == 1234;
|
||||||
|
|
||||||
|
|
||||||
int tick_start = get_now ();
|
int tick_start = get_now ();
|
||||||
void (*prev) ();
|
void (*prev) ();
|
||||||
|
@ -699,7 +886,7 @@ sim_resume (step, siggnal)
|
||||||
register int maskb = ((saved_state.asregs.msize - 1) & ~0);
|
register int maskb = ((saved_state.asregs.msize - 1) & ~0);
|
||||||
register int maskw = ((saved_state.asregs.msize - 1) & ~1);
|
register int maskw = ((saved_state.asregs.msize - 1) & ~1);
|
||||||
register int maskl = ((saved_state.asregs.msize - 1) & ~3);
|
register int maskl = ((saved_state.asregs.msize - 1) & ~3);
|
||||||
register unsigned char *memory ;
|
register unsigned char *memory;
|
||||||
register unsigned int sbit = (1 << 31);
|
register unsigned int sbit = (1 << 31);
|
||||||
|
|
||||||
prev = signal (SIGINT, control_c);
|
prev = signal (SIGINT, control_c);
|
||||||
|
@ -733,23 +920,38 @@ sim_resume (step, siggnal)
|
||||||
{
|
{
|
||||||
register unsigned int iword = RUWAT (pc);
|
register unsigned int iword = RUWAT (pc);
|
||||||
register unsigned int ult;
|
register unsigned int ult;
|
||||||
|
#ifndef ACE_FAST
|
||||||
insts++;
|
insts++;
|
||||||
|
#endif
|
||||||
top:
|
top:
|
||||||
|
|
||||||
#include "code.c"
|
#include "code.c"
|
||||||
|
|
||||||
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
|
|
||||||
|
#ifdef __GO32__
|
||||||
|
pollcount++;
|
||||||
|
if (pollcount > 1000)
|
||||||
|
{
|
||||||
|
pollcount = 0;
|
||||||
|
if (kbhit()) {
|
||||||
|
int k = getkey();
|
||||||
|
if (k == 1)
|
||||||
|
saved_state.asregs.exception = SIGINT;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef ACE_FAST
|
||||||
prevlock = thislock;
|
prevlock = thislock;
|
||||||
thislock = 30;
|
thislock = 30;
|
||||||
cycles++;
|
cycles++;
|
||||||
|
|
||||||
if (cycles >= doprofile)
|
if (cycles >= doprofile)
|
||||||
{
|
{
|
||||||
if (cycles > sim_timeout)
|
|
||||||
saved_state.asregs.exception = SIGQUIT;
|
|
||||||
|
|
||||||
saved_state.asregs.cycles += doprofile;
|
saved_state.asregs.cycles += doprofile;
|
||||||
cycles -= doprofile;
|
cycles -= doprofile;
|
||||||
if (saved_state.asregs.profile_hist)
|
if (saved_state.asregs.profile_hist)
|
||||||
|
@ -764,10 +966,13 @@ sim_resume (step, siggnal)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
while (!saved_state.asregs.exception);
|
while (!saved_state.asregs.exception);
|
||||||
|
|
||||||
if (saved_state.asregs.exception == SIGILL)
|
if (saved_state.asregs.exception == SIGILL
|
||||||
|
|| saved_state.asregs.exception == SIGBUS
|
||||||
|
|| (saved_state.asregs.exception == SIGTRAP && !step))
|
||||||
{
|
{
|
||||||
pc -= 2;
|
pc -= 2;
|
||||||
}
|
}
|
||||||
|
@ -830,21 +1035,21 @@ sim_read (addr, buffer, size)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
sim_store_register (rn, value)
|
sim_store_register (rn, memory)
|
||||||
int rn;
|
int rn;
|
||||||
unsigned char *value;
|
unsigned char *memory;
|
||||||
{
|
{
|
||||||
saved_state.asregs.regs[rn] = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | (value[3]);
|
init_pointers();
|
||||||
|
saved_state.asregs.regs[rn]=RLAT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
sim_fetch_register (rn, buf)
|
sim_fetch_register (rn, memory)
|
||||||
int rn;
|
int rn;
|
||||||
unsigned char *buf;
|
unsigned char *memory;
|
||||||
{
|
{
|
||||||
int value = ((int *) (&saved_state))[rn];
|
init_pointers();
|
||||||
|
WLAT (0, saved_state.asregs.regs[rn]);
|
||||||
swap (buf, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,11 @@ main (ac, av)
|
||||||
if (verbose)
|
if (verbose)
|
||||||
sim_info (0);
|
sim_info (0);
|
||||||
|
|
||||||
/* Find out what was in r0 and return that */
|
/* Assume we left through the exit system call,
|
||||||
|
in which case r5 has the exit code */
|
||||||
{
|
{
|
||||||
unsigned char b[4];
|
unsigned char b[4];
|
||||||
sim_fetch_register (0, b);
|
sim_fetch_register (5, b);
|
||||||
return b[3];
|
return b[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue