xref: /plan9/sys/src/cmd/vi/special.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern extern
6 #include "mips.h"
7 
8 void	Snor(ulong);
9 void	Ssll(ulong);
10 void	Ssra(ulong);
11 void	Sslt(ulong);
12 void	Ssltu(ulong);
13 void	Sand(ulong);
14 void	Saddu(ulong);
15 void	Sadd(ulong);
16 void	Sjr(ulong);
17 void	Sor(ulong);
18 void	Ssubu(ulong);
19 void	Sjalr(ulong);
20 void	Sdivu(ulong);
21 void	Smfhi(ulong);
22 void	Smflo(ulong);
23 void	Sxor(ulong);
24 void	Smult(ulong);
25 void	Smultu(ulong);
26 void	Sdiv(ulong);
27 void	Ssrl(ulong);
28 void	Ssllv(ulong);
29 void	Ssrlv(ulong);
30 void	Ssrav(ulong);
31 
32 Inst ispec[] =
33 {
34 	{ Ssll,		"sll",	Iarith },
35 	{ undef,		"" },
36 	{ Ssrl,		"srl",	Iarith },
37 	{ Ssra,		"sra",	Iarith },
38 	{ Ssllv,	"sllv",	Iarith },
39 	{ undef,	"" },
40 	{ Ssrlv,	"srlv",	Iarith },
41 	{ Ssrav,	"srav",	Iarith },
42 	{ Sjr,		"jr",	Ibranch },
43 	{ Sjalr,	"jalr",	Ibranch },
44 	{ undef,	"" },
45 	{ undef,	"" },
46 	{ Ssyscall,	"sysc", Isyscall },
47 	{ undef,	"" },
48 	{ undef,	"" },
49 	{ undef,	"" },
50 	{ Smfhi,	"mfhi",	Ireg },
51 	{ undef,	"" },
52 	{ Smflo,	"mflo",	Ireg },
53 	{ undef,	"" },
54 	{ undef,	"" },
55 	{ undef,	"" },
56 	{ undef,	"" },
57 	{ undef,	"" },
58 	{ Smult,	"mult",	Iarith },
59 	{ Smultu,	"multu" },
60 	{ Sdiv,		"div",	Iarith },
61 	{ Sdivu,	"divu", Iarith },
62 	{ undef,	"" },
63 	{ undef,	"" },
64 	{ undef,	"" },
65 	{ undef,	"" },
66 	{ Sadd,		"add",	Iarith },
67 	{ Saddu,	"addu", Iarith },
68 	{ undef,	"" },
69 	{ Ssubu,	"subu", Iarith },
70 	{ Sand,		"and",	Iarith },
71 	{ Sor,		"or", 	Iarith },
72 	{ Sxor,		"xor",	Iarith },
73 	{ Snor,		"nor",	Iarith },
74 	{ undef,	"" },
75 	{ undef,	"" },
76 	{ Sslt,		"slt", 	Iarith },
77 	{ Ssltu,	"sltu",	Iarith },
78 	{ undef,	"" },
79 	{ undef,	"" },
80 	{ undef,	"" },
81 	{ undef,	"" },
82 	{ undef,	"" },
83 	{ undef,	"" },
84 	{ undef,	"" },
85 	{ undef,	"" },
86 	{ undef,	"" },
87 	{ undef,	"" },
88 	{ undef,	"" },
89 	{ undef,	"" },
90 	{ undef,	"" },
91 	{ undef,	"" },
92 	{ undef,	"" },
93 	{ undef,	"" },
94 	{ undef,	"" },
95 	{ undef,	"" },
96 	{ undef,	"" },
97 	{ undef,	"" },
98 	{ 0 }
99 };
100 
101 void
Ispecial(ulong inst)102 Ispecial(ulong inst)
103 {
104 	Inst *i;
105 
106 	i = &ispec[inst&0x3f];
107 	reg.ip = i;
108 	i->count++;
109 	(*i->func)(inst);
110 }
111 
112 void
Snor(ulong inst)113 Snor(ulong inst)
114 {
115 	int rs, rt, rd;
116 
117 	Get3(rs, rt, rd, inst);
118 	if(trace)
119 		itrace("nor\tr%d,r%d,r%d", rd, rs, rt);
120 
121 	if(inst == INOP)
122 		nopcount++;
123 	else
124 		reg.r[rd] = ~(reg.r[rt]|reg.r[rs]);
125 }
126 
127 void
Ssll(ulong inst)128 Ssll(ulong inst)
129 {
130 	int rd, rt, shamt;
131 
132 	SpecialGetrtrd(rt, rd, inst);
133 	shamt = (inst>>6)&0x1f;
134 	if(trace)
135 		itrace("sll\tr%d,r%d,%d", rd, rt, shamt);
136 
137 	reg.r[rd] = reg.r[rt]<<shamt;
138 }
139 
140 void
Ssllv(ulong inst)141 Ssllv(ulong inst)
142 {
143 	int rd, rt, rs;
144 
145 	Get3(rs, rt, rd, inst);
146 	if(trace)
147 		itrace("sllv\tr%d,r%d,r%d", rd, rt, rs);
148 
149 	reg.r[rd] = reg.r[rt]<<(reg.r[rs]&0x1f);
150 }
151 
152 void
Ssrlv(ulong inst)153 Ssrlv(ulong inst)
154 {
155 	int rd, rt, rs;
156 
157 	Get3(rs, rt, rd, inst);
158 	if(trace)
159 		itrace("srlv\tr%d,r%d,r%d", rd, rt, rs);
160 
161 	reg.r[rd] = (ulong)reg.r[rt] >> (reg.r[rs]&0x1f);
162 }
163 
164 void
Ssrav(ulong inst)165 Ssrav(ulong inst)
166 {
167 	int rd, rt, rs, shamt;
168 
169 	Get3(rs, rt, rd, inst);
170 	if(trace)
171 		itrace("srav\tr%d,r%d,r%d", rd, rt, rs);
172 
173 	shamt = reg.r[rs]&0x1f;
174 	if(shamt != 0 && (reg.r[rt] & SIGNBIT))
175 		reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1);
176 	else
177 		reg.r[rd] = reg.r[rt]>>shamt;
178 }
179 
180 void
Ssrl(ulong inst)181 Ssrl(ulong inst)
182 {
183 	int rd, rt, shamt;
184 
185 	SpecialGetrtrd(rt, rd, inst);
186 	shamt = (inst>>6)&0x1f;
187 	if(trace)
188 		itrace("srl\tr%d,r%d,%d", rd, rt, shamt);
189 
190 	reg.r[rd] = (ulong)reg.r[rt] >> shamt;
191 }
192 
193 void
Ssra(ulong inst)194 Ssra(ulong inst)
195 {
196 	int rd, rt, shamt;
197 
198 	SpecialGetrtrd(rt, rd, inst);
199 	shamt = (inst>>6)&0x1f;
200 	if(trace)
201 		itrace("sra\tr%d,r%d,%d", rd, rt, shamt);
202 
203 	if(shamt != 0 && (reg.r[rt] & SIGNBIT))
204 		reg.r[rd] = reg.r[rt]>>shamt | ~((1<<(32-shamt))-1);
205 	else
206 		reg.r[rd] = reg.r[rt]>>shamt;
207 }
208 
209 void
Sslt(ulong inst)210 Sslt(ulong inst)
211 {
212 	int rs, rt, rd;
213 
214 	Get3(rs, rt, rd, inst);
215 	if(trace)
216 		itrace("slt\tr%d,r%d,r%d", rd, rs, rt);
217 
218 	reg.r[rd] = reg.r[rs] < reg.r[rt] ? 1 : 0;
219 }
220 
221 void
Ssltu(ulong inst)222 Ssltu(ulong inst)
223 {
224 	int rs, rt, rd;
225 
226 	Get3(rs, rt, rd, inst);
227 	if(trace)
228 		itrace("sltu\tr%d,r%d,r%d", rd, rs, rt);
229 
230 	reg.r[rd] = (unsigned)reg.r[rs] < (unsigned)reg.r[rt] ? 1 : 0;
231 }
232 
233 void
Sand(ulong inst)234 Sand(ulong inst)
235 {
236 	int rs, rt, rd;
237 
238 	Get3(rs, rt, rd, inst);
239 	if(trace)
240 		itrace("and\tr%d,r%d,r%d", rd, rs, rt);
241 
242 	reg.r[rd] = reg.r[rs] & reg.r[rt];
243 }
244 
245 void
Saddu(ulong inst)246 Saddu(ulong inst)
247 {
248 	int rs, rt, rd;
249 
250 	Get3(rs, rt, rd, inst);
251 	if(trace)
252 		itrace("addu\tr%d,r%d,r%d", rd, rs, rt);
253 
254 	reg.r[rd] = reg.r[rs] + reg.r[rt];
255 }
256 
257 void
Sadd(ulong inst)258 Sadd(ulong inst)
259 {
260 	int rs, rt, rd;
261 
262 	Get3(rs, rt, rd, inst);
263 	if(trace)
264 		itrace("add\tr%d,r%d,r%d", rd, rs, rt);
265 
266 	reg.r[rd] = reg.r[rs] + reg.r[rt];
267 }
268 
269 void
Ssubu(ulong inst)270 Ssubu(ulong inst)
271 {
272 	int rs, rt, rd;
273 
274 	Get3(rs, rt, rd, inst);
275 	if(trace)
276 		itrace("subu\tr%d,r%d,r%d", rd, rs, rt);
277 
278 	reg.r[rd] = reg.r[rs] - reg.r[rt];
279 }
280 
281 void
Sor(ulong inst)282 Sor(ulong inst)
283 {
284 	int rs, rt, rd;
285 
286 	Get3(rs, rt, rd, inst);
287 	if(trace)
288 		itrace("or\tr%d,r%d,r%d", rd, rs, rt);
289 
290 	reg.r[rd] = reg.r[rs] | reg.r[rt];
291 }
292 
293 void
Sxor(ulong inst)294 Sxor(ulong inst)
295 {
296 	int rs, rt, rd;
297 
298 	Get3(rs, rt, rd, inst);
299 	if(trace)
300 		itrace("or\tr%d,r%d,r%d", rd, rs, rt);
301 
302 	reg.r[rd] = reg.r[rs] ^ reg.r[rt];
303 }
304 
305 void
Sjr(ulong inst)306 Sjr(ulong inst)
307 {
308 	ulong npc;
309 	int rs;
310 	Symbol s;
311 
312 	rs = (inst>>21)&0x1f;
313 	npc = reg.r[rs];
314 
315 	if(trace)
316 		itrace("jr\t0x%lux", npc);
317 
318 	/* Do the delay slot */
319 	reg.ir = ifetch(reg.pc+4);
320 	Statbra();
321 	Iexec(reg.ir);
322 	if(calltree) {
323 		if(rs == 31 || rs == 2) {
324 			findsym(npc, CTEXT, &s);
325 			Bprint(bioout, "%8lux return to %lux %s r1=%lux\n",
326 						reg.pc, npc, s.name, reg.r[1]);
327 		}
328 	}
329 	reg.pc = npc-4;
330 }
331 
332 void
Sjalr(ulong inst)333 Sjalr(ulong inst)
334 {
335 	ulong npc;
336 	int rs, rd;
337 	Symbol s;
338 
339 	rs = (inst>>21)&0x1f;
340 	rd = (inst>>11)&0x1f;
341 	npc = reg.r[rs];
342 
343 	if(trace)
344 		itrace("jalr\tr%d,r%d", rd, rs);
345 
346 	reg.r[rd] = reg.pc+8;
347 	/* Do the delay slot */
348 	reg.ir = ifetch(reg.pc+4);
349 	Statbra();
350 	Iexec(reg.ir);
351 
352 	if(calltree) {
353 		findsym(npc, CTEXT, &s);
354 		if(rs == 31)
355 			Bprint(bioout, "%8lux return to %8lux %s\n",
356 						reg.pc, npc, s.name);
357 		else {
358 			printparams(&s, reg.r[29]);
359 			Bputc(bioout, '\n');
360 		}
361 	}
362 
363 	reg.pc = npc-4;
364 }
365 
366 void
Sdivu(ulong inst)367 Sdivu(ulong inst)
368 {
369 	int rs, rt;
370 
371 	Getrsrt(rs,rt,inst);
372 	if(trace)
373 		itrace("divu\tr%d,r%d", rs, rt);
374 
375 	reg.mlo = (ulong)reg.r[rs]/(ulong)reg.r[rt];
376 	reg.mhi = (ulong)reg.r[rs]%(ulong)reg.r[rt];
377 }
378 
379 void
Sdiv(ulong inst)380 Sdiv(ulong inst)
381 {
382 	int rs, rt;
383 
384 	Getrsrt(rs,rt,inst);
385 	if(trace)
386 		itrace("div\tr%d,r%d", rs, rt);
387 
388 	reg.mlo = reg.r[rs]/reg.r[rt];
389 	reg.mhi = reg.r[rs]%reg.r[rt];
390 }
391 
392 void
Smfhi(ulong inst)393 Smfhi(ulong inst)
394 {
395 	int rd;
396 
397 	rd = (inst>>11)&0x1ff;
398 	if(trace)
399 		itrace("mfhi\tr%d", rd);
400 
401 	reg.r[rd] = reg.mhi;
402 }
403 
404 void
Smflo(ulong inst)405 Smflo(ulong inst)
406 {
407 	int rd;
408 
409 	rd = (inst>>11)&0x1ff;
410 	if(trace)
411 		itrace("mflo\tr%d", rd);
412 
413 	reg.r[rd] = reg.mlo;
414 }
415 
416 void
Smult(ulong inst)417 Smult(ulong inst)
418 {
419 	int rs, rt;
420 	Mul m;
421 
422 	Getrsrt(rs,rt,inst);
423 	if(trace)
424 		itrace("mult\tr%d,r%d", rs,rt);
425 
426 	m = mul(reg.r[rs], reg.r[rt]);
427 	reg.mlo = m.lo;
428 	reg.mhi = m.hi;
429 }
430 
431 void
Smultu(ulong inst)432 Smultu(ulong inst)
433 {
434 	int rs, rt;
435 	Mulu m;
436 
437 	Getrsrt(rs,rt,inst);
438 	if(trace)
439 		itrace("multu\tr%d,r%d", rs,rt);
440 
441 	m = mulu(reg.r[rs], reg.r[rt]);
442 	reg.mlo = m.lo;
443 	reg.mhi = m.hi;
444 }
445