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