xref: /plan9/sys/src/cmd/qi/run.c (revision 7d9195a7bc3493d7fc3e1166ef25bf446be66b1a)
1*7d9195a7SDavid du Colombier #include <u.h>
2*7d9195a7SDavid du Colombier #include <libc.h>
3*7d9195a7SDavid du Colombier #include <bio.h>
4*7d9195a7SDavid du Colombier #include <mach.h>
5*7d9195a7SDavid du Colombier #define Extern extern
6*7d9195a7SDavid du Colombier #include "power.h"
7*7d9195a7SDavid du Colombier 
8*7d9195a7SDavid du Colombier 
9*7d9195a7SDavid du Colombier void	lfs(ulong);
10*7d9195a7SDavid du Colombier void	lfd(ulong);
11*7d9195a7SDavid du Colombier void	stfs(ulong);
12*7d9195a7SDavid du Colombier void	stfd(ulong);
13*7d9195a7SDavid du Colombier /* indexed versions are in 31 */
14*7d9195a7SDavid du Colombier 
15*7d9195a7SDavid du Colombier void	addic(ulong);
16*7d9195a7SDavid du Colombier void	addiccc(ulong);
17*7d9195a7SDavid du Colombier void	addi(ulong);
18*7d9195a7SDavid du Colombier void	addis(ulong);
19*7d9195a7SDavid du Colombier void	andicc(ulong);
20*7d9195a7SDavid du Colombier void	andiscc(ulong);
21*7d9195a7SDavid du Colombier void	bcx(ulong);
22*7d9195a7SDavid du Colombier void	bx(ulong);
23*7d9195a7SDavid du Colombier void	cmpi(ulong);
24*7d9195a7SDavid du Colombier void	cmpli(ulong);
25*7d9195a7SDavid du Colombier void	lbz(ulong);
26*7d9195a7SDavid du Colombier void	lha(ulong);
27*7d9195a7SDavid du Colombier void	lhz(ulong);
28*7d9195a7SDavid du Colombier void	lmw(ulong);
29*7d9195a7SDavid du Colombier void	lwz(ulong);
30*7d9195a7SDavid du Colombier void	mulli(ulong);
31*7d9195a7SDavid du Colombier void	ori(ulong);
32*7d9195a7SDavid du Colombier void	oris(ulong);
33*7d9195a7SDavid du Colombier void	rlwimi(ulong);
34*7d9195a7SDavid du Colombier void	rlwinm(ulong);
35*7d9195a7SDavid du Colombier void	rlwnm(ulong);
36*7d9195a7SDavid du Colombier void	sc(ulong);
37*7d9195a7SDavid du Colombier void	stb(ulong);
38*7d9195a7SDavid du Colombier void	sth(ulong);
39*7d9195a7SDavid du Colombier void	stmw(ulong);
40*7d9195a7SDavid du Colombier void	stw(ulong);
41*7d9195a7SDavid du Colombier void	subfic(ulong);
42*7d9195a7SDavid du Colombier void	twi(ulong);
43*7d9195a7SDavid du Colombier void	xori(ulong);
44*7d9195a7SDavid du Colombier void	xoris(ulong);
45*7d9195a7SDavid du Colombier 
46*7d9195a7SDavid du Colombier Inst	op0[] = {
47*7d9195a7SDavid du Colombier [3] {twi, "twi", Ibranch},
48*7d9195a7SDavid du Colombier [7] {mulli, "mulli", Iarith},
49*7d9195a7SDavid du Colombier [8] {subfic, "subfic", Iarith},
50*7d9195a7SDavid du Colombier [10] {cmpli, "cmpli", Iarith},
51*7d9195a7SDavid du Colombier [11] {cmpi, "cmpi", Iarith},
52*7d9195a7SDavid du Colombier [12] {addic, "addic", Iarith},
53*7d9195a7SDavid du Colombier [13] {addiccc, "addic.", Iarith},
54*7d9195a7SDavid du Colombier [14] {addi, "addi", Iarith},
55*7d9195a7SDavid du Colombier [15] {addis, "addis", Iarith},
56*7d9195a7SDavid du Colombier [16] {bcx, "bc⋯", Ibranch},
57*7d9195a7SDavid du Colombier [17] {sc, "sc", Isyscall},
58*7d9195a7SDavid du Colombier [18] {bx, "b⋯", Ibranch},
59*7d9195a7SDavid du Colombier /* group 19; branch unit */
60*7d9195a7SDavid du Colombier [20] {rlwimi, "rlwimi", Ilog},
61*7d9195a7SDavid du Colombier [21] {rlwinm, "rlwinm", Ilog},
62*7d9195a7SDavid du Colombier [23] {rlwnm, "rlwnm", Ilog},
63*7d9195a7SDavid du Colombier [24] {ori, "ori", Ilog},
64*7d9195a7SDavid du Colombier [25] {oris, "oris", Ilog},
65*7d9195a7SDavid du Colombier [26] {xori, "xori", Ilog},
66*7d9195a7SDavid du Colombier [27] {xoris, "xoris", Ilog},
67*7d9195a7SDavid du Colombier [28] {andicc, "andi.", Ilog},
68*7d9195a7SDavid du Colombier [29] {andiscc, "andis.", Ilog},
69*7d9195a7SDavid du Colombier /* group 31; integer & misc. */
70*7d9195a7SDavid du Colombier [32] {lwz, "lwz", Iload},
71*7d9195a7SDavid du Colombier [33] {lwz, "lwzu", Iload},
72*7d9195a7SDavid du Colombier [34] {lbz, "lbz", Iload},
73*7d9195a7SDavid du Colombier [35] {lbz, "lbzu", Iload},
74*7d9195a7SDavid du Colombier [36] {stw, "stw", Istore},
75*7d9195a7SDavid du Colombier [37] {stw, "stwu", Istore},
76*7d9195a7SDavid du Colombier [38] {stb, "stb", Istore},
77*7d9195a7SDavid du Colombier [39] {stb, "stbu", Istore},
78*7d9195a7SDavid du Colombier [40] {lhz, "lhz", Iload},
79*7d9195a7SDavid du Colombier [41] {lhz, "lhzu", Iload},
80*7d9195a7SDavid du Colombier [42] {lha, "lha", Iload},
81*7d9195a7SDavid du Colombier [43] {lha, "lhau", Iload},
82*7d9195a7SDavid du Colombier [44] {sth, "sth", Istore},
83*7d9195a7SDavid du Colombier [45] {sth, "sthu", Istore},
84*7d9195a7SDavid du Colombier [46] {lmw, "lmw", Iload},
85*7d9195a7SDavid du Colombier [47] {stmw, "stmw", Istore},
86*7d9195a7SDavid du Colombier [48] {lfs, "lfs", Iload},
87*7d9195a7SDavid du Colombier [49] {lfs, "lfsu", Iload},
88*7d9195a7SDavid du Colombier [50] {lfd, "lfd", Iload},
89*7d9195a7SDavid du Colombier [51] {lfd, "lfdu", Iload},
90*7d9195a7SDavid du Colombier [52] {stfs, "stfs", Istore},
91*7d9195a7SDavid du Colombier [53] {stfs, "stfsu", Istore},
92*7d9195a7SDavid du Colombier [54] {stfd, "stfd", Istore},
93*7d9195a7SDavid du Colombier [55] {stfd, "stfdu", Istore},
94*7d9195a7SDavid du Colombier /* group 59; single precision floating point */
95*7d9195a7SDavid du Colombier /* group 63; double precision floating point; fpscr */
96*7d9195a7SDavid du Colombier 	{0, 0, 0},
97*7d9195a7SDavid du Colombier };
98*7d9195a7SDavid du Colombier 
99*7d9195a7SDavid du Colombier Inset	ops0 = {op0, nelem(op0)-1};
100*7d9195a7SDavid du Colombier 
101*7d9195a7SDavid du Colombier static	char	oemflag[] = {
102*7d9195a7SDavid du Colombier 	[104] 1,
103*7d9195a7SDavid du Colombier 	[10] 1,
104*7d9195a7SDavid du Colombier 	[136] 1,
105*7d9195a7SDavid du Colombier 	[138] 1,
106*7d9195a7SDavid du Colombier 	[200] 1,
107*7d9195a7SDavid du Colombier 	[202] 1,
108*7d9195a7SDavid du Colombier 	[232] 1,
109*7d9195a7SDavid du Colombier 	[234] 1,
110*7d9195a7SDavid du Colombier 	[235] 1,
111*7d9195a7SDavid du Colombier 	[266] 1,
112*7d9195a7SDavid du Colombier 	[40] 1,
113*7d9195a7SDavid du Colombier 	[459] 1,
114*7d9195a7SDavid du Colombier 	[491] 1,
115*7d9195a7SDavid du Colombier 	[8] 1,
116*7d9195a7SDavid du Colombier };
117*7d9195a7SDavid du Colombier 
118*7d9195a7SDavid du Colombier 
119*7d9195a7SDavid du Colombier void
run(void)120*7d9195a7SDavid du Colombier run(void)
121*7d9195a7SDavid du Colombier {
122*7d9195a7SDavid du Colombier 	int xo, f;
123*7d9195a7SDavid du Colombier 
124*7d9195a7SDavid du Colombier 	do {
125*7d9195a7SDavid du Colombier 		reg.ir = ifetch(reg.pc);
126*7d9195a7SDavid du Colombier 		ci = 0;
127*7d9195a7SDavid du Colombier 		switch(reg.ir>>26) {
128*7d9195a7SDavid du Colombier 		default:
129*7d9195a7SDavid du Colombier 			xo = reg.ir>>26;
130*7d9195a7SDavid du Colombier 			if(xo >= nelem(op0))
131*7d9195a7SDavid du Colombier 				break;
132*7d9195a7SDavid du Colombier 			ci = &op0[xo];
133*7d9195a7SDavid du Colombier 			break;
134*7d9195a7SDavid du Colombier 		case 19:
135*7d9195a7SDavid du Colombier 			xo = getxo(reg.ir);
136*7d9195a7SDavid du Colombier 			if(xo >= ops19.nel)
137*7d9195a7SDavid du Colombier 				break;
138*7d9195a7SDavid du Colombier 			ci = &ops19.tab[xo];
139*7d9195a7SDavid du Colombier 			break;
140*7d9195a7SDavid du Colombier 		case 31:
141*7d9195a7SDavid du Colombier 			xo = getxo(reg.ir);
142*7d9195a7SDavid du Colombier 			f = xo & ~getxo(OE);
143*7d9195a7SDavid du Colombier 			if(reg.ir&OE && f < sizeof(oemflag) && oemflag[f])
144*7d9195a7SDavid du Colombier 				xo = f;
145*7d9195a7SDavid du Colombier 			if(xo >= ops31.nel)
146*7d9195a7SDavid du Colombier 				break;
147*7d9195a7SDavid du Colombier 			ci = &ops31.tab[xo];
148*7d9195a7SDavid du Colombier 			break;
149*7d9195a7SDavid du Colombier 		case 59:
150*7d9195a7SDavid du Colombier 			xo = getxo(reg.ir) & 0x1F;
151*7d9195a7SDavid du Colombier 			if(xo >= ops59.nel)
152*7d9195a7SDavid du Colombier 				break;
153*7d9195a7SDavid du Colombier 			ci = &ops59.tab[xo];
154*7d9195a7SDavid du Colombier 			break;
155*7d9195a7SDavid du Colombier 		case 63:
156*7d9195a7SDavid du Colombier 			xo = getxo(reg.ir) & 0x1F;
157*7d9195a7SDavid du Colombier 			if(xo < ops63a.nel) {
158*7d9195a7SDavid du Colombier 				ci = &ops63a.tab[xo];
159*7d9195a7SDavid du Colombier 				if(ci->func || ci->name)
160*7d9195a7SDavid du Colombier 					break;
161*7d9195a7SDavid du Colombier 				ci = 0;
162*7d9195a7SDavid du Colombier 			}
163*7d9195a7SDavid du Colombier 			xo = getxo(reg.ir);
164*7d9195a7SDavid du Colombier 			if(xo >= ops63b.nel)
165*7d9195a7SDavid du Colombier 				break;
166*7d9195a7SDavid du Colombier 			ci = &ops63b.tab[xo];
167*7d9195a7SDavid du Colombier 			break;
168*7d9195a7SDavid du Colombier 		}
169*7d9195a7SDavid du Colombier 		if(ci && ci->func){
170*7d9195a7SDavid du Colombier 			ci->count++;
171*7d9195a7SDavid du Colombier 			(*ci->func)(reg.ir);
172*7d9195a7SDavid du Colombier 		} else {
173*7d9195a7SDavid du Colombier 			if(ci && ci->name && trace)
174*7d9195a7SDavid du Colombier 				itrace("%s\t[not yet done]", ci->name);
175*7d9195a7SDavid du Colombier 			else
176*7d9195a7SDavid du Colombier 				undef(reg.ir);
177*7d9195a7SDavid du Colombier 		}
178*7d9195a7SDavid du Colombier 		reg.pc += 4;
179*7d9195a7SDavid du Colombier 		if(bplist)
180*7d9195a7SDavid du Colombier 			brkchk(reg.pc, Instruction);
181*7d9195a7SDavid du Colombier 	}while(--count);
182*7d9195a7SDavid du Colombier }
183*7d9195a7SDavid du Colombier 
184*7d9195a7SDavid du Colombier void
ilock(int)185*7d9195a7SDavid du Colombier ilock(int)
186*7d9195a7SDavid du Colombier {
187*7d9195a7SDavid du Colombier }
188*7d9195a7SDavid du Colombier 
189*7d9195a7SDavid du Colombier void
undef(ulong ir)190*7d9195a7SDavid du Colombier undef(ulong ir)
191*7d9195a7SDavid du Colombier {
192*7d9195a7SDavid du Colombier /*	Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
193*7d9195a7SDavid du Colombier 	Bprint(bioout, "illegal_instruction IR #%.8lux (op=%ld/%ld, pc=#%.8lux)\n", ir, getop(ir), getxo(ir), reg.pc);
194*7d9195a7SDavid du Colombier 	if(ci && ci->name && ci->func==0)
195*7d9195a7SDavid du Colombier 		Bprint(bioout, "(%s not yet implemented)\n", ci->name);
196*7d9195a7SDavid du Colombier 	longjmp(errjmp, 0);
197*7d9195a7SDavid du Colombier }
198*7d9195a7SDavid du Colombier 
199*7d9195a7SDavid du Colombier void
unimp(ulong ir)200*7d9195a7SDavid du Colombier unimp(ulong ir)
201*7d9195a7SDavid du Colombier {
202*7d9195a7SDavid du Colombier /*	Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
203*7d9195a7SDavid du Colombier 	Bprint(bioout, "illegal_instruction IR #%.8lux (op=%ld/%ld, pc=#%.8lux) %s not in MPC601\n", ir, getop(ir), getxo(ir), reg.pc, ci->name?ci->name: "-");
204*7d9195a7SDavid du Colombier 	longjmp(errjmp, 0);
205*7d9195a7SDavid du Colombier }
206