13e12c5d1SDavid du Colombier /* 23e12c5d1SDavid du Colombier * sparc sim.h 33e12c5d1SDavid du Colombier * 43e12c5d1SDavid du Colombier * The integer instruction side of this emulator is portable if sizeof(long) >= 4 53e12c5d1SDavid du Colombier * Floating point emulation however is not. Assumptions made are: 63e12c5d1SDavid du Colombier * sizeof(ulong) == sizeof(float) 73e12c5d1SDavid du Colombier * sizeof(ulong)*2 == sizeof(double) 83e12c5d1SDavid du Colombier * bits of floating point in memory may be reversed lsw/msw 93e12c5d1SDavid du Colombier * unions of double & 2*float & 2*long have no padding 103e12c5d1SDavid du Colombier */ 113e12c5d1SDavid du Colombier #include "/sparc/include/ureg.h" 123e12c5d1SDavid du Colombier #define USERADDR 0xC0000000 133e12c5d1SDavid du Colombier #define UREGADDR (USERADDR+BY2PG-4-0xA0) 143e12c5d1SDavid du Colombier #define USER_REG(x) (UREGADDR+(ulong)(x)) 153e12c5d1SDavid du Colombier #define REGOFF(x) (USER_REG(&((struct Ureg *) 0)->x)) 163e12c5d1SDavid du Colombier 173e12c5d1SDavid du Colombier typedef struct Registers Registers; 183e12c5d1SDavid du Colombier typedef struct Segment Segment; 193e12c5d1SDavid du Colombier typedef struct Memory Memory; 203e12c5d1SDavid du Colombier typedef struct Mul Mul; 213e12c5d1SDavid du Colombier typedef struct Mulu Mulu; 223e12c5d1SDavid du Colombier typedef struct Inst Inst; 233e12c5d1SDavid du Colombier typedef struct Icache Icache; 243e12c5d1SDavid du Colombier typedef struct Breakpoint Breakpoint; 253e12c5d1SDavid du Colombier 263e12c5d1SDavid du Colombier enum 273e12c5d1SDavid du Colombier { 283e12c5d1SDavid du Colombier Instruction = 1, 293e12c5d1SDavid du Colombier Read = 2, 303e12c5d1SDavid du Colombier Write = 4, 313e12c5d1SDavid du Colombier Access = 2|4, 323e12c5d1SDavid du Colombier Equal = 4|8, 333e12c5d1SDavid du Colombier }; 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier struct Breakpoint 363e12c5d1SDavid du Colombier { 373e12c5d1SDavid du Colombier int type; /* Instruction/Read/Access/Write/Equal */ 383e12c5d1SDavid du Colombier ulong addr; /* Place at address */ 393e12c5d1SDavid du Colombier int count; /* To execute count times or value */ 403e12c5d1SDavid du Colombier int done; /* How many times passed through */ 413e12c5d1SDavid du Colombier Breakpoint *next; /* Link to next one */ 423e12c5d1SDavid du Colombier }; 433e12c5d1SDavid du Colombier 443e12c5d1SDavid du Colombier enum 453e12c5d1SDavid du Colombier { 463e12c5d1SDavid du Colombier Iload, 473e12c5d1SDavid du Colombier Istore, 483e12c5d1SDavid du Colombier Iarith, 493e12c5d1SDavid du Colombier Ibranch, 503e12c5d1SDavid du Colombier Ireg, 513e12c5d1SDavid du Colombier Isyscall, 523e12c5d1SDavid du Colombier Ifloat, 533e12c5d1SDavid du Colombier Inop, 543e12c5d1SDavid du Colombier }; 553e12c5d1SDavid du Colombier 563e12c5d1SDavid du Colombier struct Icache 573e12c5d1SDavid du Colombier { 583e12c5d1SDavid du Colombier int on; /* Turned on */ 593e12c5d1SDavid du Colombier int linesize; /* Line size in bytes */ 603e12c5d1SDavid du Colombier int stall; /* Cache stalls */ 613e12c5d1SDavid du Colombier int *lines; /* Tag array */ 623e12c5d1SDavid du Colombier int* (*hash)(ulong); /* Hash function */ 633e12c5d1SDavid du Colombier char *hashtext; /* What the function looks like */ 643e12c5d1SDavid du Colombier }; 653e12c5d1SDavid du Colombier 663e12c5d1SDavid du Colombier struct Inst 673e12c5d1SDavid du Colombier { 683e12c5d1SDavid du Colombier void (*func)(ulong); 693e12c5d1SDavid du Colombier char *name; 703e12c5d1SDavid du Colombier int type; 713e12c5d1SDavid du Colombier int count; 723e12c5d1SDavid du Colombier int taken; 733e12c5d1SDavid du Colombier int useddelay; 743e12c5d1SDavid du Colombier }; 753e12c5d1SDavid du Colombier 763e12c5d1SDavid du Colombier struct Registers 773e12c5d1SDavid du Colombier { 783e12c5d1SDavid du Colombier ulong pc; 793e12c5d1SDavid du Colombier ulong ir; 803e12c5d1SDavid du Colombier Inst *ip; 813e12c5d1SDavid du Colombier long r[32]; 823e12c5d1SDavid du Colombier ulong Y; 833e12c5d1SDavid du Colombier ulong psr; 843e12c5d1SDavid du Colombier ulong fpsr; 853e12c5d1SDavid du Colombier 863e12c5d1SDavid du Colombier union { 873e12c5d1SDavid du Colombier double fd[16]; 883e12c5d1SDavid du Colombier float fl[32]; 893e12c5d1SDavid du Colombier ulong di[32]; 903e12c5d1SDavid du Colombier }; 913e12c5d1SDavid du Colombier }; 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier struct Mulu{ 943e12c5d1SDavid du Colombier ulong lo; 953e12c5d1SDavid du Colombier ulong hi; 963e12c5d1SDavid du Colombier }; 973e12c5d1SDavid du Colombier 983e12c5d1SDavid du Colombier struct Mul{ 993e12c5d1SDavid du Colombier long lo; 1003e12c5d1SDavid du Colombier long hi; 1013e12c5d1SDavid du Colombier }; 1023e12c5d1SDavid du Colombier 1033e12c5d1SDavid du Colombier enum 1043e12c5d1SDavid du Colombier { 1053e12c5d1SDavid du Colombier MemRead, 1063e12c5d1SDavid du Colombier MemReadstring, 1073e12c5d1SDavid du Colombier MemWrite, 1083e12c5d1SDavid du Colombier }; 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier enum 1113e12c5d1SDavid du Colombier { 1123e12c5d1SDavid du Colombier Stack, 1133e12c5d1SDavid du Colombier Text, 1143e12c5d1SDavid du Colombier Data, 1153e12c5d1SDavid du Colombier Bss, 1163e12c5d1SDavid du Colombier Nseg, 1173e12c5d1SDavid du Colombier }; 1183e12c5d1SDavid du Colombier 1193e12c5d1SDavid du Colombier struct Segment 1203e12c5d1SDavid du Colombier { 1213e12c5d1SDavid du Colombier short type; 1223e12c5d1SDavid du Colombier ulong base; 1233e12c5d1SDavid du Colombier ulong end; 1243e12c5d1SDavid du Colombier ulong fileoff; 1253e12c5d1SDavid du Colombier ulong fileend; 1263e12c5d1SDavid du Colombier int rss; 1273e12c5d1SDavid du Colombier int refs; 1283e12c5d1SDavid du Colombier uchar **table; 1293e12c5d1SDavid du Colombier }; 1303e12c5d1SDavid du Colombier 1313e12c5d1SDavid du Colombier struct Memory 1323e12c5d1SDavid du Colombier { 1333e12c5d1SDavid du Colombier Segment seg[Nseg]; 1343e12c5d1SDavid du Colombier }; 1353e12c5d1SDavid du Colombier 1363e12c5d1SDavid du Colombier void fatal(int, char*, ...); 1373e12c5d1SDavid du Colombier void run(void); 1383e12c5d1SDavid du Colombier void undef(ulong); 1393e12c5d1SDavid du Colombier void dumpreg(void); 1403e12c5d1SDavid du Colombier void dumpfreg(void); 1413e12c5d1SDavid du Colombier void dumpdreg(void); 1423e12c5d1SDavid du Colombier void* emalloc(ulong); 1433e12c5d1SDavid du Colombier void* erealloc(void*, ulong, ulong); 1443e12c5d1SDavid du Colombier void* vaddr(ulong); 1453e12c5d1SDavid du Colombier void itrace(char *, ...); 1463e12c5d1SDavid du Colombier void segsum(void); 1473e12c5d1SDavid du Colombier void ta(ulong); 1483e12c5d1SDavid du Colombier char* memio(char*, ulong, int, int); 1493e12c5d1SDavid du Colombier ulong getmem_w(ulong); 1503e12c5d1SDavid du Colombier ulong ifetch(ulong); 1513e12c5d1SDavid du Colombier ushort getmem_h(ulong); 1523e12c5d1SDavid du Colombier void putmem_w(ulong, ulong); 1533e12c5d1SDavid du Colombier uchar getmem_b(ulong); 1543e12c5d1SDavid du Colombier void putmem_b(ulong, uchar); 1553e12c5d1SDavid du Colombier ulong getmem_4(ulong); 1563e12c5d1SDavid du Colombier ulong getmem_2(ulong); 1573e12c5d1SDavid du Colombier void putmem_h(ulong, short); 1583e12c5d1SDavid du Colombier Mul mul(long, long); 1593e12c5d1SDavid du Colombier Mulu mulu(ulong, ulong); 1603e12c5d1SDavid du Colombier void isum(void); 1613e12c5d1SDavid du Colombier void initicache(void); 1623e12c5d1SDavid du Colombier void updateicache(ulong addr); 1633e12c5d1SDavid du Colombier long lnrand(long); 1643e12c5d1SDavid du Colombier void randseed(long, long); 1653e12c5d1SDavid du Colombier void cmd(void); 1663e12c5d1SDavid du Colombier void brkchk(ulong, int); 1673e12c5d1SDavid du Colombier void delbpt(char*); 1683e12c5d1SDavid du Colombier void breakpoint(char*, char*); 1693e12c5d1SDavid du Colombier char* nextc(char*); 1703e12c5d1SDavid du Colombier ulong expr(char*); 171*219b2ee8SDavid du Colombier void initstk(int, char**); 172*219b2ee8SDavid du Colombier void initmap(void); 173*219b2ee8SDavid du Colombier void inithdr(int); 1743e12c5d1SDavid du Colombier void reset(void); 1753e12c5d1SDavid du Colombier void dobplist(void); 1763e12c5d1SDavid du Colombier void procinit(int); 1773e12c5d1SDavid du Colombier void printsource(long); 1783e12c5d1SDavid du Colombier void printparams(Symbol *, ulong); 1793e12c5d1SDavid du Colombier void printlocals(Symbol *, ulong); 1803e12c5d1SDavid du Colombier void stktrace(int); 181bd389b36SDavid du Colombier void delay(ulong); 1823e12c5d1SDavid du Colombier void iprofile(void); 1833e12c5d1SDavid du Colombier 1843e12c5d1SDavid du Colombier /* Globals */ 1853e12c5d1SDavid du Colombier Extern Registers reg; 1863e12c5d1SDavid du Colombier Extern Memory memory; 1873e12c5d1SDavid du Colombier Extern int text; 1883e12c5d1SDavid du Colombier Extern int trace; 1893e12c5d1SDavid du Colombier Extern int sysdbg; 1903e12c5d1SDavid du Colombier Extern int calltree; 1913e12c5d1SDavid du Colombier Extern Icache icache; 1923e12c5d1SDavid du Colombier Extern int count; 1933e12c5d1SDavid du Colombier Extern jmp_buf errjmp; 1943e12c5d1SDavid du Colombier Extern Breakpoint *bplist; 1953e12c5d1SDavid du Colombier Extern int atbpt; 1963e12c5d1SDavid du Colombier Extern int membpt; 1973e12c5d1SDavid du Colombier Extern int cmdcount; 1983e12c5d1SDavid du Colombier Extern int nopcount; 1993e12c5d1SDavid du Colombier Extern ulong dot; 2003e12c5d1SDavid du Colombier extern char *file; 2013e12c5d1SDavid du Colombier Extern Biobuf *bioout; 2023e12c5d1SDavid du Colombier Extern Biobuf *bin; 2033e12c5d1SDavid du Colombier Extern Inst *ci; 2043e12c5d1SDavid du Colombier Extern ulong *iprof; 2053e12c5d1SDavid du Colombier Extern ulong loadlock; 2063e12c5d1SDavid du Colombier Extern ulong anulled; 2073e12c5d1SDavid du Colombier extern int datasize; 2083e12c5d1SDavid du Colombier extern int printcol; 209*219b2ee8SDavid du Colombier Extern Map *symmap; 2103e12c5d1SDavid du Colombier 2113e12c5d1SDavid du Colombier /* Plan9 Kernel constants */ 2123e12c5d1SDavid du Colombier #define BY2PG 4096 2133e12c5d1SDavid du Colombier #define BY2WD 4 2143e12c5d1SDavid du Colombier #define UTZERO 0x1000 215*219b2ee8SDavid du Colombier #define TSTKSIZ 32 216*219b2ee8SDavid du Colombier #define TSTACKTOP 0x10000000 217*219b2ee8SDavid du Colombier #define STACKTOP (TSTACKTOP-TSTKSIZ*BY2PG) 218*219b2ee8SDavid du Colombier #define STACKSIZE (4*1024*1024) 2193e12c5d1SDavid du Colombier 2203e12c5d1SDavid du Colombier #define ANUL (1<<29) 2213e12c5d1SDavid du Colombier #define PROFGRAN 4 2223e12c5d1SDavid du Colombier #define NOP 0x80300000 2233e12c5d1SDavid du Colombier #define SIGNBIT 0x80000000 2243e12c5d1SDavid du Colombier #define IMMBIT (1<<13) 2253e12c5d1SDavid du Colombier #define getrop23(i) rd = (i>>25)&0x1f; rs1 = (i>>14)&0x1f; rs2 = i&0x1f; 2263e12c5d1SDavid du Colombier #define ximm(xx, ii) xx = ii&0x1FFF; if(xx&0x1000) xx |= ~0x1FFF 2273e12c5d1SDavid du Colombier 2283e12c5d1SDavid du Colombier #define PSR_n (1<<23) 2293e12c5d1SDavid du Colombier #define PSR_z (1<<22) 2303e12c5d1SDavid du Colombier #define PSR_v (1<<21) 2313e12c5d1SDavid du Colombier #define PSR_c (1<<20) 2323e12c5d1SDavid du Colombier 2333e12c5d1SDavid du Colombier #define FP_U 3 2343e12c5d1SDavid du Colombier #define FP_L 1 2353e12c5d1SDavid du Colombier #define FP_G 2 2363e12c5d1SDavid du Colombier #define FP_E 0 237