xref: /plan9-contrib/sys/src/cmd/vi/run.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	Iaddi(ulong);
9 void	Isw(ulong);
10 void	Ilui(ulong);
11 void	Iori(ulong);
12 void	Ixori(ulong);
13 void	Ilw(ulong);
14 void	Ijal(ulong);
15 void	Ispecial(ulong);
16 void	Ibeq(ulong);
17 void	Iaddiu(ulong);
18 void	Ilb(ulong);
19 void	Iandi(ulong);
20 void	Ij(ulong);
21 void	Ibne(ulong);
22 void	Isb(ulong);
23 void	Islti(ulong);
24 void	Ibcond(ulong);
25 void	Ibgtz(ulong);
26 void	Ilbu(ulong);
27 void	Ilhu(ulong);
28 void	Ish(ulong);
29 void	Ilh(ulong);
30 void	Iblez(ulong);
31 void	Isltiu(ulong);
32 void	Iswc1(ulong);
33 void	Ilwc1(ulong);
34 void	Icop1(ulong);
35 
36 Inst itab[] = {
37 	{ Ispecial,	0 },
38 	{ Ibcond,	"bcond",	Ibranch },
39 	{ Ij,		"j",		Ibranch },
40 	{ Ijal,		"jal",		Ibranch },
41 	{ Ibeq,		"beq",		Ibranch },
42 	{ Ibne,		"bne",		Ibranch },
43 	{ Iblez,	"blez",		Ibranch },
44 	{ Ibgtz,	"bgtz",		Ibranch },
45 	{ Iaddi,	"addi",		Iarith },	/* 8 */
46 	{ Iaddiu,	"addiu",	Iarith },
47 	{ Islti,	"slti",		Iarith },
48 	{ Isltiu,	"sltiu",	Iarith },
49 	{ Iandi,	"andi",		Iarith },
50 	{ Iori,		"ori",		Iarith },
51 	{ Ixori,	"xori",		Iarith },
52 	{ Ilui,		"lui",		Iload },	/* 15 */
53 	{ undef,	"" },
54 	{ Icop1,	"cop1",		Ifloat },
55 	{ undef,	"" },
56 	{ undef,	"" },
57 	{ undef,	"" },
58 	{ undef,	"" },
59 	{ undef,	"" },
60 	{ undef,	"" },
61 	{ undef,	"" },
62 	{ undef,	"" },
63 	{ undef,	"" },
64 	{ undef,	"" },
65 	{ undef,	"" },
66 	{ undef,	"" },
67 	{ undef,	"" },
68 	{ undef,	"" },
69 	{ Ilb,		"lb",		Iload },
70 	{ Ilh,		"lh",		Iload },
71 	{ undef,	"" },
72 	{ Ilw,		"lw",		Iload },
73 	{ Ilbu,		"lbu",		Iload },
74 	{ Ilhu,		"lhu",		Iload },
75 	{ undef,	"" },
76 	{ undef,	"" },
77 	{ Isb,		"sb",		Istore },
78 	{ Ish,		"sh",		Istore },
79 	{ undef,	"" },
80 	{ Isw,		"sw",		Istore },	/* 43 */
81 	{ undef,	"" },
82 	{ undef,	"" },
83 	{ undef,	"" },
84 	{ undef,	"" },
85 	{ undef,	"" },
86 	{ Ilwc1,		"lwc1",		Ifloat },
87 	{ undef,	"" },
88 	{ undef,	"" },
89 	{ undef,	"" },
90 	{ undef,	"" },
91 	{ undef,	"" },
92 	{ undef,	"" },
93 	{ undef,	"" },
94 	{ Iswc1,	"swc1",		Ifloat },
95 	{ undef,	"" },
96 	{ undef,	"" },
97 	{ undef,	"" },
98 	{ undef,	"" },
99 	{ undef,	"" },
100 	{ undef,	"" },
101 	{ 0 }
102 };
103 
104 void
105 run(void)
106 {
107 	do {
108 		reg.r[0] = 0;
109 		reg.ir = ifetch(reg.pc);
110 		Iexec(reg.ir);
111 		reg.pc += 4;
112 		if(bplist)
113 			brkchk(reg.pc, Instruction);
114 	}while(--count);
115 }
116 
117 void
118 undef(ulong inst)
119 {
120 /*
121 	if((reg.ir>>26) == 0)
122 		Bprint(bioout, "special=%d,%d table=%d\n",
123 		(reg.ir>>3)&0x7, reg.ir&0x7, reg.ir&0x3f);
124 	else
125 		Bprint(bioout, "code=%d,%d table=%d\n",
126 		reg.ir>>29, (reg.ir>>26)&0x7, reg.ir>>26);
127 */
128 	Bprint(bioout, "Undefined Instruction Trap IR %.8lux\n", inst);
129 	longjmp(errjmp, 0);
130 }
131 
132 void
133 Iaddi(ulong inst)
134 {
135 	int rs, rt;
136 	int imm;
137 
138 	Getrsrt(rs, rt, inst);
139 	imm = (short)(inst&0xffff);
140 
141 	if(trace)
142 		itrace("addi\tr%d,r%d,#0x%x", rt, rs, imm);
143 
144 	reg.r[rt] = reg.r[rs] + imm;
145 }
146 
147 void
148 Iandi(ulong inst)
149 {
150 	int rs, rt;
151 	int imm;
152 
153 	Getrsrt(rs, rt, inst);
154 	imm = inst&0xffff;
155 
156 	if(trace)
157 		itrace("andi\tr%d,r%d,#0x%x", rt, rs, imm);
158 
159 	reg.r[rt] = reg.r[rs] & imm;
160 }
161 
162 void
163 Isw(ulong inst)
164 {
165 	int rt, rb;
166 	int off;
167 	ulong value;
168 
169 	Getrbrt(rb, rt, inst);
170 	off = (short)(inst&0xffff);
171 
172 	value = reg.r[rt];
173 	if(trace)
174 		itrace("sw\tr%d,0x%x(r%d) %lux=%lux",
175 				rt, off, rb, reg.r[rb]+off, value);
176 
177 	putmem_w(reg.r[rb]+off, value);
178 }
179 
180 void
181 Isb(ulong inst)
182 {
183 	int rt, rb;
184 	int off;
185 	uchar value;
186 
187 	Getrbrt(rb, rt, inst);
188 	off = (short)(inst&0xffff);
189 
190 	value = reg.r[rt];
191 	if(trace)
192 		itrace("sb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, reg.r[rb]+off, value);
193 
194 	putmem_b(reg.r[rb]+off, value);
195 }
196 
197 void
198 Ish(ulong inst)
199 {
200 	int rt, rb;
201 	int off;
202 	ushort value;
203 
204 	Getrbrt(rb, rt, inst);
205 	off = (short)(inst&0xffff);
206 
207 	value = reg.r[rt];
208 	if(trace)
209 		itrace("sh\tr%d,0x%x(r%d) %lux=%lux",
210 				rt, off, rb, reg.r[rb]+off, value&0xffff);
211 
212 	putmem_h(reg.r[rb]+off, value);
213 }
214 
215 void
216 Ilui(ulong inst)
217 {
218 	int rs, rt;
219 	int imm;
220 
221 	Getrsrt(rs, rt, inst);
222 	USED(rs);
223 	imm = inst<<16;
224 
225 	if(trace)
226 		itrace("lui\tr%d,#0x%x", rt, imm);
227 
228 	reg.r[rt] = imm;
229 }
230 
231 void
232 Iori(ulong inst)
233 {
234 	int rs, rt;
235 	int imm;
236 
237 	Getrsrt(rs, rt, inst);
238 	imm = inst&0xffff;
239 
240 	if(trace)
241 		itrace("ori\tr%d,r%d,#0x%x", rt, rs, imm);
242 
243 	reg.r[rt] = reg.r[rs] | imm;
244 }
245 
246 void
247 Ixori(ulong inst)
248 {
249 	int rs, rt;
250 	int imm;
251 
252 	Getrsrt(rs, rt, inst);
253 	imm = inst&0xffff;
254 
255 	if(trace)
256 		itrace("xori\tr%d,r%d,#0x%x", rt, rs, imm);
257 
258 	reg.r[rt] = reg.r[rs] ^ imm;
259 }
260 
261 void
262 Ilw(ulong inst)
263 {
264 	int rt, rb;
265 	int off;
266 
267 	Getrbrt(rb, rt, inst);
268 	off = (short)(inst&0xffff);
269 
270 	if(trace)
271 		itrace("lw\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
272 
273 	reg.r[rt] = getmem_w(reg.r[rb]+off);
274 }
275 
276 void
277 Ilh(ulong inst)
278 {
279 	int rt, rb;
280 	int off;
281 
282 	Getrbrt(rb, rt, inst);
283 	off = (short)(inst&0xffff);
284 
285 	if(trace)
286 		itrace("lh\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
287 
288 	reg.r[rt] = (short)getmem_h(reg.r[rb]+off);
289 }
290 
291 void
292 Ijal(ulong inst)
293 {
294 	ulong npc;
295 	Symbol s;
296 
297 	npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
298 	if(trace)
299 		itrace("jal\t0x%lux", npc);
300 
301 	reg.r[31] = reg.pc+8;
302 	/* Do the delay slot */
303 	reg.ir = ifetch(reg.pc+4);
304 	Statbra();
305 	Iexec(reg.ir);
306 
307 	if(calltree) {
308 		findsym(npc, CTEXT, &s);
309 		Bprint(bioout, "%8lux %s(", reg.pc, s.name);
310 		printparams(&s, reg.r[29]);
311 		Bprint(bioout, "from ");
312 		printsource(reg.pc);
313 		Bputc(bioout, '\n');
314 	}
315 
316 	reg.pc = npc-4;
317 }
318 
319 void
320 Ij(ulong inst)
321 {
322 	ulong npc;
323 
324 	npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
325 	if(trace)
326 		itrace("j\t0x%lux", npc);
327 
328 	/* Do the delay slot */
329 	reg.ir = ifetch(reg.pc+4);
330 	Statbra();
331 	Iexec(reg.ir);
332 	reg.pc = npc-4;
333 }
334 
335 void
336 Ibeq(ulong inst)
337 {
338 	int rt, rs;
339 	int off;
340 	ulong npc;
341 
342 	Getrsrt(rs, rt, inst);
343 	off = (short)(inst&0xffff);
344 
345 	npc = reg.pc + (off<<2) + 4;
346 	if(trace)
347 		itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
348 
349 	if(reg.r[rs] == reg.r[rt]) {
350 		/* Do the delay slot */
351 		reg.ir = ifetch(reg.pc+4);
352 		Statbra();
353 		Iexec(reg.ir);
354 		reg.pc = npc-4;
355 	}
356 }
357 
358 void
359 Ibgtz(ulong inst)
360 {
361 	int rs;
362 	int off;
363 	ulong npc, r;
364 
365 	rs = (inst>>21)&0x1f;
366 	off = (short)(inst&0xffff);
367 
368 	npc = reg.pc + (off<<2) + 4;
369 	if(trace)
370 		itrace("bgtz\tr%d,0x%lux", rs, npc);
371 
372 	r = reg.r[rs];
373 	if(!(r&SIGNBIT) && r != 0) {
374 		/* Do the delay slot */
375 		reg.ir = ifetch(reg.pc+4);
376 		Iexec(reg.ir);
377 		reg.pc = npc-4;
378 	}
379 }
380 
381 void
382 Iblez(ulong inst)
383 {
384 	int rs;
385 	int off;
386 	ulong npc, r;
387 
388 	rs = (inst>>21)&0x1f;
389 	off = (short)(inst&0xffff);
390 
391 	npc = reg.pc + (off<<2) + 4;
392 	if(trace)
393 		itrace("blez\tr%d,0x%lux", rs, npc);
394 
395 	r = reg.r[rs];
396 	if((r&SIGNBIT) || r == 0) {
397 		/* Do the delay slot */
398 		reg.ir = ifetch(reg.pc+4);
399 		Statbra();
400 		Iexec(reg.ir);
401 		reg.pc = npc-4;
402 	}
403 }
404 
405 void
406 Ibne(ulong inst)
407 {
408 	int rt, rs;
409 	int off;
410 	ulong npc;
411 
412 	Getrsrt(rs, rt, inst);
413 	off = (short)(inst&0xffff);
414 
415 	npc = reg.pc + (off<<2) + 4;
416 	if(trace)
417 		itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
418 
419 	if(reg.r[rs] != reg.r[rt]) {
420 		/* Do the delay slot */
421 		reg.ir = ifetch(reg.pc+4);
422 		Statbra();
423 		Iexec(reg.ir);
424 		reg.pc = npc-4;
425 	}
426 }
427 
428 void
429 Iaddiu(ulong inst)
430 {
431 	int rs, rt;
432 	int imm;
433 
434 	Getrsrt(rs, rt, inst);
435 	imm = (short)(inst&0xffff);
436 
437 	if(trace)
438 		itrace("addiu\tr%d,r%d,#0x%x", rt, rs, imm);
439 
440 	reg.r[rt] = reg.r[rs]+imm;
441 }
442 
443 void
444 Islti(ulong inst)
445 {
446 	int rs, rt;
447 	int imm;
448 
449 	Getrsrt(rs, rt, inst);
450 	imm = (short)(inst&0xffff);
451 
452 	if(trace)
453 		itrace("slti\tr%d,r%d,#0x%x", rt, rs, imm);
454 
455 	reg.r[rt] = reg.r[rs] < imm ? 1 : 0;
456 }
457 
458 void
459 Isltiu(ulong inst)
460 {
461 	int rs, rt;
462 	int imm;
463 
464 	Getrsrt(rs, rt, inst);
465 	imm = (short)(inst&0xffff);
466 
467 	if(trace)
468 		itrace("sltiu\tr%d,r%d,#0x%x", rt, rs, imm);
469 
470 	reg.r[rt] = (ulong)reg.r[rs] < (ulong)imm ? 1 : 0;
471 }
472 
473 void
474 Ilb(ulong inst)
475 {
476 	int rt, rb;
477 	int off;
478 
479 	Getrbrt(rb, rt, inst);
480 	off = (short)(inst&0xffff);
481 
482 	if(trace)
483 		itrace("lb\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
484 
485 	reg.r[rt] = (schar)getmem_b(reg.r[rb]+off);
486 }
487 
488 void
489 Ilbu(ulong inst)
490 {
491 	int rt, rb;
492 	int off;
493 
494 	Getrbrt(rb, rt, inst);
495 	off = (short)(inst&0xffff);
496 
497 	if(trace)
498 		itrace("lbu\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
499 
500 	reg.r[rt] = getmem_b(reg.r[rb]+off) & 0xff;
501 }
502 
503 void
504 Ilhu(ulong inst)
505 {
506 	int rt, rb;
507 	int off;
508 
509 	Getrbrt(rb, rt, inst);
510 	off = (short)(inst&0xffff);
511 
512 	if(trace)
513 		itrace("lhu\tr%d,0x%x(r%d) ea=%lux", rt, off, rb, reg.r[rb]+off);
514 
515 	reg.r[rt] = getmem_h(reg.r[rb]+off) & 0xffff;
516 }
517 
518 enum
519 {
520 	Bltz	= 0,
521 	Bgez	= 1,
522 	Bltzal	= 0x10,
523 	Bgezal	= 0x11,
524 };
525 
526 static char *sbcond[] =
527 {
528 	[Bltz]		"ltz",
529 	[Bgez]		"gez",
530 	[Bltzal]	"ltzal",
531 	[Bgezal]	"gezal",
532 };
533 
534 void
535 Ibcond(ulong inst)
536 {
537 	int rs, bran;
538 	int off, doit;
539 	ulong npc;
540 
541 	rs = (inst>>21)&0x1f;
542 	bran = (inst>>16)&0x1f;
543 	off = (short)(inst&0xffff);
544 	doit = 0;
545 
546 	npc = reg.pc + (off<<2) + 4;
547 	switch(bran) {
548 	default:
549 		Bprint(bioout, "bcond=%d\n", bran);
550 		undef(inst);
551 	case Bltz:
552 		if(reg.r[rs]&SIGNBIT)
553 			doit = 1;
554 		break;
555 	case Bgez:
556 		if(!(reg.r[rs]&SIGNBIT))
557 			doit = 1;
558 		break;
559 	case Bltzal:
560 		if(reg.r[rs]&SIGNBIT) {
561 			doit = 1;
562 			reg.r[31] = reg.pc+8;
563 		}
564 		break;
565 	case Bgezal:
566 		if(reg.r[rs] >= 0) {
567 			doit = 1;
568 			reg.r[31] = reg.pc+8;
569 		}
570 		break;
571 	}
572 
573 	if(trace)
574 		itrace("b%s\tr%d,0x%lux", sbcond[bran], rs, npc);
575 
576 	if(doit) {
577 		/* Do the delay slot */
578 		reg.ir = ifetch(reg.pc+4);
579 		Statbra();
580 		Iexec(reg.ir);
581 		reg.pc = npc-4;
582 	}
583 
584 }
585