xref: /plan9/sys/src/cmd/qi/power.h (revision 6891d8578618fb7ccda4a131c122d4d0e6580c4b)
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