17d9195a7SDavid du Colombier /* 27d9195a7SDavid du Colombier * power sim.h 37d9195a7SDavid du Colombier * 47d9195a7SDavid du Colombier * The integer instruction side of this emulator is portable if sizeof(long) >= 4 57d9195a7SDavid du Colombier * Floating point emulation assumes: 67d9195a7SDavid du Colombier * sizeof(ulong) == sizeof(float) 77d9195a7SDavid du Colombier * sizeof(ulong)*2 == sizeof(double) <= sizeof(vlong) 87d9195a7SDavid du Colombier * unions of double & vlong have no padding 97d9195a7SDavid du Colombier * vlongs provide at least 64 bits precision 107d9195a7SDavid du Colombier */ 117d9195a7SDavid du Colombier #include "/power/include/ureg.h" 127d9195a7SDavid du Colombier #define USERADDR 0xC0000000 137d9195a7SDavid du Colombier #define UREGADDR (USERADDR+BY2PG-4-0xA0) 147d9195a7SDavid du Colombier #define USER_REG(x) (UREGADDR+(ulong)(x)) 157d9195a7SDavid du Colombier #define REGOFF(x) (USER_REG(&((struct Ureg *) 0)->x)) 167d9195a7SDavid du Colombier 177d9195a7SDavid du Colombier typedef struct Registers Registers; 187d9195a7SDavid du Colombier typedef struct Segment Segment; 197d9195a7SDavid du Colombier typedef struct Memory Memory; 207d9195a7SDavid du Colombier typedef struct Inset Inset; 217d9195a7SDavid du Colombier typedef struct Inst Inst; 227d9195a7SDavid du Colombier typedef struct Icache Icache; 237d9195a7SDavid du Colombier typedef struct Breakpoint Breakpoint; 247d9195a7SDavid du Colombier 257d9195a7SDavid du Colombier enum 267d9195a7SDavid du Colombier { 277d9195a7SDavid du Colombier Instruction = 1, 287d9195a7SDavid du Colombier Read = 2, 297d9195a7SDavid du Colombier Write = 4, 307d9195a7SDavid du Colombier Access = 2|4, 317d9195a7SDavid du Colombier Equal = 4|8, 327d9195a7SDavid du Colombier }; 337d9195a7SDavid du Colombier 347d9195a7SDavid du Colombier struct Breakpoint 357d9195a7SDavid du Colombier { 367d9195a7SDavid du Colombier int type; /* Instruction/Read/Access/Write/Equal */ 377d9195a7SDavid du Colombier ulong addr; /* Place at address */ 387d9195a7SDavid du Colombier int count; /* To execute count times or value */ 397d9195a7SDavid du Colombier int done; /* How many times passed through */ 407d9195a7SDavid du Colombier Breakpoint *next; /* Link to next one */ 417d9195a7SDavid du Colombier }; 427d9195a7SDavid du Colombier 437d9195a7SDavid du Colombier enum 447d9195a7SDavid du Colombier { 457d9195a7SDavid du Colombier Iload, 467d9195a7SDavid du Colombier Istore, 477d9195a7SDavid du Colombier Iarith, 487d9195a7SDavid du Colombier Ilog, 497d9195a7SDavid du Colombier Ibranch, 507d9195a7SDavid du Colombier Ireg, 517d9195a7SDavid du Colombier Isyscall, 527d9195a7SDavid du Colombier Ifloat, 537d9195a7SDavid du Colombier Inop, 547d9195a7SDavid du Colombier Icontrol, 557d9195a7SDavid du Colombier }; 567d9195a7SDavid du Colombier 577d9195a7SDavid du Colombier struct Icache 587d9195a7SDavid du Colombier { 597d9195a7SDavid du Colombier int on; /* Turned on */ 607d9195a7SDavid du Colombier int linesize; /* Line size in bytes */ 617d9195a7SDavid du Colombier int stall; /* Cache stalls */ 627d9195a7SDavid du Colombier int *lines; /* Tag array */ 637d9195a7SDavid du Colombier int* (*hash)(ulong); /* Hash function */ 647d9195a7SDavid du Colombier char *hashtext; /* What the function looks like */ 657d9195a7SDavid du Colombier }; 667d9195a7SDavid du Colombier 677d9195a7SDavid du Colombier struct Inset 687d9195a7SDavid du Colombier { 697d9195a7SDavid du Colombier Inst *tab; /* indexed by extended opcode */ 707d9195a7SDavid du Colombier int nel; 717d9195a7SDavid du Colombier }; 727d9195a7SDavid du Colombier 737d9195a7SDavid du Colombier struct Inst 747d9195a7SDavid du Colombier { 757d9195a7SDavid du Colombier void (*func)(ulong); 767d9195a7SDavid du Colombier char *name; 777d9195a7SDavid du Colombier int type; 787d9195a7SDavid du Colombier int count; 797d9195a7SDavid du Colombier int taken; 807d9195a7SDavid du Colombier }; 817d9195a7SDavid du Colombier 827d9195a7SDavid du Colombier struct Registers 837d9195a7SDavid du Colombier { 847d9195a7SDavid du Colombier ulong pc; 857d9195a7SDavid du Colombier ulong ir; 867d9195a7SDavid du Colombier Inst *ip; 877d9195a7SDavid du Colombier long r[32]; 887d9195a7SDavid du Colombier ulong ctr; 897d9195a7SDavid du Colombier ulong cr; 907d9195a7SDavid du Colombier ulong xer; 917d9195a7SDavid du Colombier ulong lr; 927d9195a7SDavid du Colombier ulong fpscr; 937d9195a7SDavid du Colombier ulong dec; 947d9195a7SDavid du Colombier ulong tbl; 957d9195a7SDavid du Colombier ulong tbu; 967d9195a7SDavid du Colombier double fd[32]; 977d9195a7SDavid du Colombier }; 987d9195a7SDavid du Colombier 997d9195a7SDavid du Colombier enum 1007d9195a7SDavid du Colombier { 1017d9195a7SDavid du Colombier MemRead, 1027d9195a7SDavid du Colombier MemReadstring, 1037d9195a7SDavid du Colombier MemWrite, 1047d9195a7SDavid du Colombier }; 1057d9195a7SDavid du Colombier 1067d9195a7SDavid du Colombier enum 1077d9195a7SDavid du Colombier { 1087d9195a7SDavid du Colombier Stack, 1097d9195a7SDavid du Colombier Text, 1107d9195a7SDavid du Colombier Data, 1117d9195a7SDavid du Colombier Bss, 1127d9195a7SDavid du Colombier Nseg, 1137d9195a7SDavid du Colombier }; 1147d9195a7SDavid du Colombier 1157d9195a7SDavid du Colombier struct Segment 1167d9195a7SDavid du Colombier { 1177d9195a7SDavid du Colombier short type; 1187d9195a7SDavid du Colombier ulong base; 1197d9195a7SDavid du Colombier ulong end; 1207d9195a7SDavid du Colombier ulong fileoff; 1217d9195a7SDavid du Colombier ulong fileend; 1227d9195a7SDavid du Colombier int rss; 1237d9195a7SDavid du Colombier int refs; 1247d9195a7SDavid du Colombier uchar **table; 1257d9195a7SDavid du Colombier }; 1267d9195a7SDavid du Colombier 1277d9195a7SDavid du Colombier struct Memory 1287d9195a7SDavid du Colombier { 1297d9195a7SDavid du Colombier Segment seg[Nseg]; 1307d9195a7SDavid du Colombier }; 1317d9195a7SDavid du Colombier 1327d9195a7SDavid du Colombier void fatal(int, char*, ...); 133*6891d857SDavid du Colombier void fpreginit(void); 1347d9195a7SDavid du Colombier void run(void); 1357d9195a7SDavid du Colombier void undef(ulong); 1367d9195a7SDavid du Colombier void unimp(ulong); 1377d9195a7SDavid du Colombier void dumpreg(void); 1387d9195a7SDavid du Colombier void dumpfreg(void); 1397d9195a7SDavid du Colombier void dumpdreg(void); 1407d9195a7SDavid du Colombier void* emalloc(ulong); 1417d9195a7SDavid du Colombier void* erealloc(void*, ulong, ulong); 1427d9195a7SDavid du Colombier void* vaddr(ulong); 1437d9195a7SDavid du Colombier void itrace(char *, ...); 1447d9195a7SDavid du Colombier void segsum(void); 1457d9195a7SDavid du Colombier void sc(ulong); 1467d9195a7SDavid du Colombier char* memio(char*, ulong, int, int); 1477d9195a7SDavid du Colombier ulong getmem_w(ulong); 1487d9195a7SDavid du Colombier ulong ifetch(ulong); 1497d9195a7SDavid du Colombier ushort getmem_h(ulong); 1507d9195a7SDavid du Colombier void putmem_w(ulong, ulong); 1517d9195a7SDavid du Colombier uchar getmem_b(ulong); 1527d9195a7SDavid du Colombier void putmem_b(ulong, uchar); 1537d9195a7SDavid du Colombier uvlong getmem_v(ulong); 1547d9195a7SDavid du Colombier ulong getmem_4(ulong); 1557d9195a7SDavid du Colombier ulong getmem_2(ulong); 1567d9195a7SDavid du Colombier void putmem_v(ulong, uvlong); 1577d9195a7SDavid du Colombier void putmem_h(ulong, short); 1587d9195a7SDavid du Colombier void isum(void); 1597d9195a7SDavid du Colombier void initicache(void); 1607d9195a7SDavid du Colombier void updateicache(ulong addr); 1617d9195a7SDavid du Colombier long lnrand(long); 1627d9195a7SDavid du Colombier void randseed(long, long); 1637d9195a7SDavid du Colombier void cmd(void); 1647d9195a7SDavid du Colombier void brkchk(ulong, int); 1657d9195a7SDavid du Colombier void delbpt(char*); 1667d9195a7SDavid du Colombier void breakpoint(char*, char*); 1677d9195a7SDavid du Colombier char* nextc(char*); 1687d9195a7SDavid du Colombier ulong expr(char*); 1697d9195a7SDavid du Colombier void initstk(int, char**); 1707d9195a7SDavid du Colombier void initmap(void); 1717d9195a7SDavid du Colombier void inithdr(int); 1727d9195a7SDavid du Colombier void reset(void); 1737d9195a7SDavid du Colombier void dobplist(void); 1747d9195a7SDavid du Colombier void procinit(int); 1757d9195a7SDavid du Colombier void printsource(long); 1767d9195a7SDavid du Colombier void printparams(Symbol *, ulong); 1777d9195a7SDavid du Colombier void printlocals(Symbol *, ulong); 1787d9195a7SDavid du Colombier void stktrace(int); 1797d9195a7SDavid du Colombier void iprofile(void); 1807d9195a7SDavid du Colombier 1817d9195a7SDavid du Colombier /* Globals */ 1827d9195a7SDavid du Colombier Extern Registers reg; 1837d9195a7SDavid du Colombier Extern Memory memory; 1847d9195a7SDavid du Colombier Extern int text; 1857d9195a7SDavid du Colombier Extern int trace; 1867d9195a7SDavid du Colombier Extern int sysdbg; 1877d9195a7SDavid du Colombier Extern int calltree; 1887d9195a7SDavid du Colombier Extern Icache icache; 1897d9195a7SDavid du Colombier Extern int count; 1907d9195a7SDavid du Colombier Extern jmp_buf errjmp; 1917d9195a7SDavid du Colombier Extern Breakpoint *bplist; 1927d9195a7SDavid du Colombier Extern int atbpt; 1937d9195a7SDavid du Colombier Extern int membpt; 1947d9195a7SDavid du Colombier Extern int cmdcount; 1957d9195a7SDavid du Colombier Extern int nopcount; 1967d9195a7SDavid du Colombier Extern ulong dot; 1977d9195a7SDavid du Colombier extern char *file; 1987d9195a7SDavid du Colombier Extern Biobuf *bioout; 1997d9195a7SDavid du Colombier Extern Biobuf *bin; 2007d9195a7SDavid du Colombier Extern Inst *ci; 2017d9195a7SDavid du Colombier Extern ulong *iprof; 2027d9195a7SDavid du Colombier Extern ulong iprofsize; 2037d9195a7SDavid du Colombier Extern ulong loadlock; 2047d9195a7SDavid du Colombier extern int datasize; 2057d9195a7SDavid du Colombier extern int printcol; 2067d9195a7SDavid du Colombier Extern Map *symmap; 2077d9195a7SDavid du Colombier extern ulong bits[]; 2087d9195a7SDavid du Colombier 2097d9195a7SDavid du Colombier extern Inset ops0, ops19, ops31, ops59, ops63a, ops63b; 2107d9195a7SDavid du Colombier 2117d9195a7SDavid du Colombier /* Plan9 Kernel constants */ 2127d9195a7SDavid du Colombier #define BY2PG 4096 2137d9195a7SDavid du Colombier #define BY2WD 4 2147d9195a7SDavid du Colombier #define UTZERO 0x1000 2157d9195a7SDavid du Colombier #define TSTKSIZ 32 2167d9195a7SDavid du Colombier #define TSTACKTOP 0x20000000 2177d9195a7SDavid du Colombier #define STACKTOP (TSTACKTOP-TSTKSIZ*BY2PG) 2187d9195a7SDavid du Colombier #define STACKSIZE (4*1024*1024) 2197d9195a7SDavid du Colombier 2207d9195a7SDavid du Colombier #define PROFGRAN 4 2217d9195a7SDavid du Colombier #define NOP 0x80300000 2227d9195a7SDavid du Colombier #define SIGNBIT 0x80000000 2237d9195a7SDavid du Colombier 2247d9195a7SDavid du Colombier 2257d9195a7SDavid du Colombier enum { 2267d9195a7SDavid du Colombier CRLT = 1<<31, 2277d9195a7SDavid du Colombier CRGT = 1<<30, 2287d9195a7SDavid du Colombier CREQ = 1<<29, 2297d9195a7SDavid du Colombier CRSO = 1<<28, 2307d9195a7SDavid du Colombier CRFU = CRSO, 2317d9195a7SDavid du Colombier 2327d9195a7SDavid du Colombier CRFX = 1<<27, 2337d9195a7SDavid du Colombier CRFEX = 1<<26, 2347d9195a7SDavid du Colombier CRVX = 1<<25, 2357d9195a7SDavid du Colombier CROX = 1<<24, 2367d9195a7SDavid du Colombier }; 2377d9195a7SDavid du Colombier 2387d9195a7SDavid du Colombier #define getCR(x,w) (((w)>>(28-(x*4)))&0xF) 2397d9195a7SDavid du Colombier #define mkCR(x,v) (((v)&0xF)<<(28-(x*4))) 2407d9195a7SDavid du Colombier 2417d9195a7SDavid du Colombier #define simm(xx, ii) xx = (short)(ii&0xFFFF); 2427d9195a7SDavid du Colombier #define uimm(xx, ii) xx = ii&0xFFFF; 2437d9195a7SDavid du Colombier #define imms(xx, ii) xx = ii<<16; 2447d9195a7SDavid du Colombier #define getairr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; simm(imm,i) 2457d9195a7SDavid du Colombier #define getarrr(i) rd = (i>>21)&0x1f; ra = (i>>16)&0x1f; rb = (i>>11)&0x1f; 2467d9195a7SDavid du Colombier #define getbobi(i) bo = (i>>21)&0x1f; bi = (i>>16)&0x1f; xx = (i>>11)&0x1f; 2477d9195a7SDavid du Colombier #define getlirr(i) rs = (i>>21)&0x1f; ra = (i>>16)&0x1f; uimm(imm,i) 2487d9195a7SDavid du Colombier #define getlrrr(i) rs = (i>>21)&0x1f; ra = (i>>16)&0x1f; rb = (i>>11)&0x1f; 2497d9195a7SDavid du Colombier 2507d9195a7SDavid du Colombier #define OP(o,xo) ((o<<26)|(xo<<1)) /* build an operation */ 2517d9195a7SDavid du Colombier #define xop(a,b) ((b<<6)|a) /* compact form for use in a decoding switch on op/xo */ 2527d9195a7SDavid du Colombier #define getop(i) ((i>>26)&0x3F) 2537d9195a7SDavid du Colombier #define getxo(i) ((i>>1)&0x3FF) 2547d9195a7SDavid du Colombier 2557d9195a7SDavid du Colombier #define FPS_FX (1<<31) /* exception summary (sticky) */ 2567d9195a7SDavid du Colombier #define FPS_EX (1<<30) /* enabled exception summary */ 2577d9195a7SDavid du Colombier #define FPS_VX (1<<29) /* invalid operation exception summary */ 2587d9195a7SDavid du Colombier #define FPS_OX (1<<28) /* overflow exception OX (sticky) */ 2597d9195a7SDavid du Colombier #define FPS_UX (1<<27) /* underflow exception UX (sticky) */ 2607d9195a7SDavid du Colombier #define FPS_ZX (1<<26) /* zero divide exception ZX (sticky) */ 2617d9195a7SDavid du Colombier #define FPS_XX (1<<25) /* inexact exception XX (sticky) */ 2627d9195a7SDavid du Colombier #define FPS_VXSNAN (1<<24) /* invalid operation exception for SNaN (sticky) */ 2637d9195a7SDavid du Colombier #define FPS_VXISI (1<<23) /* invalid operation exception for ∞-∞ (sticky) */ 2647d9195a7SDavid du Colombier #define FPS_VXIDI (1<<22) /* invalid operation exception for ∞/∞ (sticky) */ 2657d9195a7SDavid du Colombier #define FPS_VXZDZ (1<<21) /* invalid operation exception for 0/0 (sticky) */ 2667d9195a7SDavid du Colombier #define FPS_VXIMZ (1<<20) /* invalid operation exception for ∞*0 (sticky) */ 2677d9195a7SDavid du Colombier #define FPS_VXVC (1<<19) /* invalid operation exception for invalid compare (sticky) */ 2687d9195a7SDavid du Colombier #define FPS_FR (1<<18) /* fraction rounded */ 2697d9195a7SDavid du Colombier #define FPS_FI (1<<17) /* fraction inexact */ 2707d9195a7SDavid du Colombier #define FPS_FPRF (1<<16) /* floating point result class */ 2717d9195a7SDavid du Colombier #define FPS_FPCC (0xF<<12) /* <, >, =, unordered */ 2727d9195a7SDavid du Colombier #define FPS_VXCVI (1<<8) /* enable exception for invalid integer convert (sticky) */ 2737d9195a7SDavid du Colombier #define FPS_VE (1<<7) /* invalid operation exception enable */ 2747d9195a7SDavid du Colombier #define FPS_OE (1<<6) /* enable overflow exceptions */ 2757d9195a7SDavid du Colombier #define FPS_UE (1<<5) /* enable underflow */ 2767d9195a7SDavid du Colombier #define FPS_ZE (1<<4) /* enable zero divide */ 2777d9195a7SDavid du Colombier #define FPS_XE (1<<3) /* enable inexact exceptions */ 2787d9195a7SDavid du Colombier #define FPS_RN (3<<0) /* rounding mode */ 2797d9195a7SDavid du Colombier 2807d9195a7SDavid du Colombier #define XER_SO (1<<31) 2817d9195a7SDavid du Colombier #define XER_OV (1<<30) 2827d9195a7SDavid du Colombier #define XER_CA (1<<29) 2837d9195a7SDavid du Colombier 2847d9195a7SDavid du Colombier #define Rc 1 2857d9195a7SDavid du Colombier #define OE 0x400 286