xref: /plan9/sys/src/cmd/vi/run.c (revision 0cc39a83e201996cab5ee319ea497ce6109e8d23)
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	Ibeql(ulong);
18 void	Iaddiu(ulong);
19 void	Ilb(ulong);
20 void	Iandi(ulong);
21 void	Ij(ulong);
22 void	Ibne(ulong);
23 void	Ibnel(ulong);
24 void	Isb(ulong);
25 void	Islti(ulong);
26 void	Ibcond(ulong);
27 void	Ibgtz(ulong);
28 void	Ibgtzl(ulong);
29 void	Ilbu(ulong);
30 void	Ilhu(ulong);
31 void	Ish(ulong);
32 void	Ilh(ulong);
33 void	Iblez(ulong);
34 void	Iblezl(ulong);
35 void	Isltiu(ulong);
36 void	Iswc1(ulong);
37 void	Ilwc1(ulong);
38 void	Icop1(ulong);
39 void	Ilwl(ulong);
40 void	Ilwr(ulong);
41 void	Ill(ulong);
42 void	Isc(ulong);
43 
44 Inst itab[] = {
45 	{ Ispecial,	0 },
46 	{ Ibcond,	"bcond",	Ibranch },
47 	{ Ij,		"j",		Ibranch },
48 	{ Ijal,		"jal",		Ibranch },
49 	{ Ibeq,		"beq",		Ibranch },
50 	{ Ibne,		"bne",		Ibranch },
51 	{ Iblez,	"blez",		Ibranch },
52 	{ Ibgtz,	"bgtz",		Ibranch },
53 	{ Iaddi,	"addi",		Iarith },	/* 8 */
54 	{ Iaddiu,	"addiu",	Iarith },
55 	{ Islti,	"slti",		Iarith },
56 	{ Isltiu,	"sltiu",	Iarith },
57 	{ Iandi,	"andi",		Iarith },
58 	{ Iori,		"ori",		Iarith },
59 	{ Ixori,	"xori",		Iarith },
60 	{ Ilui,		"lui",		Iload },	/* 15 */
61 	{ undef,	"" },
62 	{ Icop1,	"cop1",		Ifloat },
63 	{ undef,	"" },
64 	{ undef,	"" },
65 	{ Ibeql,	"beql" },
66 	{ Ibnel,	"bnel" },
67 	{ Iblezl,	"blezl" },
68 	{ Ibgtzl,	"bgtzl" },
69 	{ undef,	"" },
70 	{ undef,	"" },
71 	{ undef,	"" },
72 	{ undef,	"" },
73 	{ undef,	"" },
74 	{ undef,	"" },
75 	{ undef,	"" },
76 	{ undef,	"" },
77 	{ Ilb,		"lb",		Iload },
78 	{ Ilh,		"lh",		Iload },
79 	{ Ilwl,		"lwl", 		Iload },
80 	{ Ilw,		"lw",		Iload },
81 	{ Ilbu,		"lbu",		Iload },
82 	{ Ilhu,		"lhu",		Iload },
83 	{ Ilwr,		"lwr",		Iload },
84 	{ undef,	"" },
85 	{ Isb,		"sb",		Istore },
86 	{ Ish,		"sh",		Istore },
87 	{ undef,	"" },
88 	{ Isw,		"sw",		Istore },	/* 43 */
89 	{ undef,	"" },
90 	{ undef,	"" },
91 	{ undef,	"" },
92 	{ undef,	"" },
93 	{ Ill,			"ll",			Iload},
94 	{ Ilwc1,		"lwc1",		Ifloat },
95 	{ undef,	"" },
96 	{ undef,	"" },
97 	{ undef,	"" },
98 	{ undef,	"" },
99 	{ undef,	"" },
100 	{ undef,	"" },
101 	{ Isc,		"sc",		Istore },
102 	{ Iswc1,	"swc1",		Ifloat },
103 	{ undef,	"" },
104 	{ undef,	"" },
105 	{ undef,	"" },
106 	{ undef,	"" },
107 	{ undef,	"" },
108 	{ undef,	"" },
109 	{ 0 }
110 };
111 
112 void
dortrace(void)113 dortrace(void)
114 {
115 	int i;
116 
117 	for(i = 0; i < 32; i++)
118 		if(rtrace & (1<<i))
119 			Bprint(bioout, "R%.2d %.8lux\n", i, reg.r[i]);
120 }
121 
122 void
run(void)123 run(void)
124 {
125 	do {
126 		reg.r[0] = 0;
127 		reg.ir = ifetch(reg.pc);
128 		Iexec(reg.ir);
129 		reg.pc += 4;
130 		if(bplist)
131 			brkchk(reg.pc, Instruction);
132 		if(rtrace)
133 			dortrace();
134 Bflush(bioout);
135 	}while(--count);
136 }
137 
138 void
undef(ulong inst)139 undef(ulong inst)
140 {
141 
142 /*
143 	if((reg.ir>>26) == 0)
144 		Bprint(bioout, "special=%d,%d table=%d\n",
145 		(reg.ir>>3)&0x7, reg.ir&0x7, reg.ir&0x3f);
146 	else
147 		Bprint(bioout, "code=%d,%d table=%d\n",
148 		reg.ir>>29, (reg.ir>>26)&0x7, reg.ir>>26);
149 */
150 
151 	Bprint(bioout, "Undefined Instruction Trap IR %.8lux\n", inst);
152 	longjmp(errjmp, 0);
153 }
154 
155 void
Iaddi(ulong inst)156 Iaddi(ulong inst)
157 {
158 	int rs, rt;
159 	int imm;
160 
161 	Getrsrt(rs, rt, inst);
162 	imm = (short)(inst&0xffff);
163 
164 	if(trace)
165 		itrace("addi\tr%d,r%d,#0x%x", rt, rs, imm);
166 
167 	reg.r[rt] = reg.r[rs] + imm;
168 }
169 
170 void
Iandi(ulong inst)171 Iandi(ulong inst)
172 {
173 	int rs, rt;
174 	int imm;
175 
176 	Getrsrt(rs, rt, inst);
177 	imm = inst&0xffff;
178 
179 	if(trace)
180 		itrace("andi\tr%d,r%d,#0x%x", rt, rs, imm);
181 
182 	reg.r[rt] = reg.r[rs] & imm;
183 }
184 
185 void
Isw(ulong inst)186 Isw(ulong inst)
187 {
188 	int rt, rb;
189 	int off;
190 	ulong v;
191 
192 	Getrbrt(rb, rt, inst);
193 	off = (short)(inst&0xffff);
194 
195 	v = reg.r[rt];
196 	if(trace)
197 		itrace("sw\tr%d,0x%x(r%d) %lux=%lux",
198 				rt, off, rb, reg.r[rb]+off, v);
199 
200 	putmem_w(reg.r[rb]+off, v);
201 }
202 
203 void
Isb(ulong inst)204 Isb(ulong inst)
205 {
206 	int rt, rb;
207 	int off;
208 	uchar value;
209 
210 	Getrbrt(rb, rt, inst);
211 	off = (short)(inst&0xffff);
212 
213 	value = reg.r[rt];
214 	if(trace)
215 		itrace("sb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, reg.r[rb]+off, value);
216 
217 	putmem_b(reg.r[rb]+off, value);
218 }
219 
220 void
Ish(ulong inst)221 Ish(ulong inst)
222 {
223 	int rt, rb;
224 	int off;
225 	ushort value;
226 
227 	Getrbrt(rb, rt, inst);
228 	off = (short)(inst&0xffff);
229 
230 	value = reg.r[rt];
231 	if(trace)
232 		itrace("sh\tr%d,0x%x(r%d) %lux=%lux",
233 				rt, off, rb, reg.r[rb]+off, value&0xffff);
234 
235 	putmem_h(reg.r[rb]+off, value);
236 }
237 
238 void
Ilui(ulong inst)239 Ilui(ulong inst)
240 {
241 	int rs, rt;
242 	int imm;
243 
244 	Getrsrt(rs, rt, inst);
245 	USED(rs);
246 	imm = inst<<16;
247 
248 	if(trace)
249 		itrace("lui\tr%d,#0x%x", rt, imm);
250 
251 	reg.r[rt] = imm;
252 }
253 
254 void
Iori(ulong inst)255 Iori(ulong inst)
256 {
257 	int rs, rt;
258 	int imm;
259 
260 	Getrsrt(rs, rt, inst);
261 	imm = inst&0xffff;
262 
263 	if(trace)
264 		itrace("ori\tr%d,r%d,#0x%x", rt, rs, imm);
265 
266 	reg.r[rt] = reg.r[rs] | imm;
267 }
268 
269 void
Ixori(ulong inst)270 Ixori(ulong inst)
271 {
272 	int rs, rt;
273 	int imm;
274 
275 	Getrsrt(rs, rt, inst);
276 	imm = inst&0xffff;
277 
278 	if(trace)
279 		itrace("xori\tr%d,r%d,#0x%x", rt, rs, imm);
280 
281 	reg.r[rt] = reg.r[rs] ^ imm;
282 }
283 
284 void
Ilw(ulong inst)285 Ilw(ulong inst)
286 {
287 	int rt, rb;
288 	int off;
289 	ulong v, va;
290 
291 	Getrbrt(rb, rt, inst);
292 	off = (short)(inst&0xffff);
293 
294 	va = reg.r[rb]+off;
295 
296 	if(trace) {
297 		v = 0;
298 		if(!badvaddr(va, 4))
299 			v = getmem_w(va);
300 		itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
301 	}
302 
303 	reg.r[rt] = getmem_w(va);
304 }
305 
306 void
Ilwl(ulong inst)307 Ilwl(ulong inst)
308 {
309 	int rt, rb;
310 	int off;
311 	ulong v, va;
312 
313 	Getrbrt(rb, rt, inst);
314 	off = (short)(inst&0xffff);
315 
316 	va = reg.r[rb]+off;
317 
318 	if(trace) {
319 		v = 0;
320 		if(!badvaddr(va, 4))
321 			v = getmem_w(va & ~3) << ((va & 3) << 3);
322 		itrace("lwl\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
323 	}
324 
325 	v = getmem_w(va & ~3);
326 	switch(va & 3) {
327 	case 0:
328 		reg.r[rt] = v;
329 		break;
330 	case 1:
331 		reg.r[rt] = (v<<8) | (reg.r[rt] & 0xff);
332 		break;
333 	case 2:
334 		reg.r[rt] = (v<<16) | (reg.r[rt] & 0xffff);
335 		break;
336 	case 3:
337 		reg.r[rt] = (v<<24) | (reg.r[rt] & 0xffffff);
338 		break;
339 	}
340 }
341 
342 void
Ilwr(ulong inst)343 Ilwr(ulong inst)
344 {
345 	int rt, rb;
346 	int off;
347 	ulong v, va;
348 
349 	Getrbrt(rb, rt, inst);
350 	off = (short)(inst&0xffff);
351 
352 	va = reg.r[rb]+off;
353 
354 	if(trace) {
355 		v = 0;
356 		if(!badvaddr(va, 4))
357 			v = getmem_w(va & ~3) << ((va & 3) << 3);
358 		itrace("lwr\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
359 	}
360 
361 	v = getmem_w(va & ~3);
362 	switch(va & 3) {
363 	case 0:
364 		break;
365 	case 1:
366 		reg.r[rt] = (v>>24) | (reg.r[rt] & 0xffffff00);
367 		break;
368 	case 2:
369 		reg.r[rt] = (v>>16) | (reg.r[rt] & 0xffff0000);
370 		break;
371 	case 3:
372 		reg.r[rt] = (v>>8) | (reg.r[rt] & 0xff000000);
373 		break;
374 	}
375 }
376 
377 void
Ilh(ulong inst)378 Ilh(ulong inst)
379 {
380 	int rt, rb;
381 	int off;
382 	ulong v, va;
383 
384 	Getrbrt(rb, rt, inst);
385 	off = (short)(inst&0xffff);
386 
387 	va = reg.r[rb]+off;
388 
389 	if(trace) {
390 		v = 0;
391 		if(!badvaddr(va, 2))
392 			v = (short)getmem_h(va);
393 		itrace("lw\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
394 	}
395 
396 	reg.r[rt] = (short)getmem_h(va);
397 }
398 
399 void
Ilhu(ulong inst)400 Ilhu(ulong inst)
401 {
402 	int rt, rb;
403 	int off;
404 	ulong v, va;
405 
406 	Getrbrt(rb, rt, inst);
407 	off = (short)(inst&0xffff);
408 
409 	va = reg.r[rb]+off;
410 
411 	if(trace) {
412 		v = 0;
413 		if(!badvaddr(va, 2))
414 			v = getmem_h(va) & 0xffff;
415 		itrace("lhu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
416 	}
417 
418 	reg.r[rt] = getmem_h(va) & 0xffff;
419 }
420 
421 void
Ilb(ulong inst)422 Ilb(ulong inst)
423 {
424 	int rt, rb;
425 	int off;
426 	ulong v, va;
427 
428 	Getrbrt(rb, rt, inst);
429 	off = (short)(inst&0xffff);
430 
431 	va = reg.r[rb]+off;
432 
433 	if(trace) {
434 		v = 0;
435 		if(!badvaddr(va, 1))
436 			v = (schar)getmem_b(va);
437 		itrace("lb\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
438 	}
439 
440 	reg.r[rt] = (schar)getmem_b(va);
441 }
442 
443 void
Ilbu(ulong inst)444 Ilbu(ulong inst)
445 {
446 	int rt, rb;
447 	int off;
448 	ulong v, va;
449 
450 	Getrbrt(rb, rt, inst);
451 	off = (short)(inst&0xffff);
452 
453 	va = reg.r[rb]+off;
454 
455 	if(trace) {
456 		v = 0;
457 		if(!badvaddr(va, 1))
458 			v = getmem_b(va) & 0xff;
459 		itrace("lbu\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
460 	}
461 
462 	reg.r[rt] = getmem_b(va) & 0xff;
463 }
464 
465 void
Ijal(ulong inst)466 Ijal(ulong inst)
467 {
468 	ulong npc;
469 	Symbol s;
470 
471 	npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
472 	if(trace)
473 		itrace("jal\t0x%lux", npc);
474 
475 	reg.r[31] = reg.pc+8;
476 	/* Do the delay slot */
477 	reg.ir = ifetch(reg.pc+4);
478 	Statbra();
479 	Iexec(reg.ir);
480 
481 	if(calltree) {
482 		findsym(npc, CTEXT, &s);
483 		Bprint(bioout, "%8lux %s(", reg.pc, s.name);
484 		printparams(&s, reg.r[29]);
485 		Bprint(bioout, "from ");
486 		printsource(reg.pc);
487 		Bputc(bioout, '\n');
488 	}
489 
490 	reg.pc = npc-4;
491 }
492 
493 void
Ij(ulong inst)494 Ij(ulong inst)
495 {
496 	ulong npc;
497 
498 	npc = (reg.pc&0xF0000000)|((inst&0x3FFFFFF)<<2);
499 	if(trace)
500 		itrace("j\t0x%lux", npc);
501 
502 	/* Do the delay slot */
503 	reg.ir = ifetch(reg.pc+4);
504 	Statbra();
505 	Iexec(reg.ir);
506 	reg.pc = npc-4;
507 }
508 
509 void
Ibeq(ulong inst)510 Ibeq(ulong inst)
511 {
512 	int rt, rs;
513 	int off;
514 	ulong npc;
515 
516 	Getrsrt(rs, rt, inst);
517 	off = (short)(inst&0xffff);
518 
519 	npc = reg.pc + (off<<2) + 4;
520 	if(trace)
521 		itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
522 
523 	if(reg.r[rs] == reg.r[rt]) {
524 		/* Do the delay slot */
525 		reg.ir = ifetch(reg.pc+4);
526 		Statbra();
527 		Iexec(reg.ir);
528 		reg.pc = npc-4;
529 	}
530 }
531 
532 void
Ibeql(ulong inst)533 Ibeql(ulong inst)
534 {
535 	int rt, rs;
536 	int off;
537 	ulong npc;
538 
539 	Getrsrt(rs, rt, inst);
540 	off = (short)(inst&0xffff);
541 
542 	npc = reg.pc + (off<<2) + 4;
543 	if(trace)
544 		itrace("beq\tr%d,r%d,0x%lux", rs, rt, npc);
545 
546 	if(reg.r[rs] == reg.r[rt]) {
547 		/* Do the delay slot */
548 		reg.ir = ifetch(reg.pc+4);
549 		Statbra();
550 		Iexec(reg.ir);
551 		reg.pc = npc-4;
552 	} else
553 		reg.pc += 4;
554 }
555 
556 void
Ibgtz(ulong inst)557 Ibgtz(ulong inst)
558 {
559 	int rs;
560 	int off;
561 	ulong npc, r;
562 
563 	rs = (inst>>21)&0x1f;
564 	off = (short)(inst&0xffff);
565 
566 	npc = reg.pc + (off<<2) + 4;
567 	if(trace)
568 		itrace("bgtz\tr%d,0x%lux", rs, npc);
569 
570 	r = reg.r[rs];
571 	if(!(r&SIGNBIT) && r != 0) {
572 		/* Do the delay slot */
573 		reg.ir = ifetch(reg.pc+4);
574 		Iexec(reg.ir);
575 		reg.pc = npc-4;
576 	}
577 }
578 
579 void
Ibgtzl(ulong inst)580 Ibgtzl(ulong inst)
581 {
582 	int rs;
583 	int off;
584 	ulong npc, r;
585 
586 	rs = (inst>>21)&0x1f;
587 	off = (short)(inst&0xffff);
588 
589 	npc = reg.pc + (off<<2) + 4;
590 	if(trace)
591 		itrace("bgtz\tr%d,0x%lux", rs, npc);
592 
593 	r = reg.r[rs];
594 	if(!(r&SIGNBIT) && r != 0) {
595 		/* Do the delay slot */
596 		reg.ir = ifetch(reg.pc+4);
597 		Iexec(reg.ir);
598 		reg.pc = npc-4;
599 	} else
600 		reg.pc += 4;
601 }
602 
603 void
Iblez(ulong inst)604 Iblez(ulong inst)
605 {
606 	int rs;
607 	int off;
608 	ulong npc, r;
609 
610 	rs = (inst>>21)&0x1f;
611 	off = (short)(inst&0xffff);
612 
613 	npc = reg.pc + (off<<2) + 4;
614 	if(trace)
615 		itrace("blez\tr%d,0x%lux", rs, npc);
616 
617 	r = reg.r[rs];
618 	if((r&SIGNBIT) || r == 0) {
619 		/* Do the delay slot */
620 		reg.ir = ifetch(reg.pc+4);
621 		Statbra();
622 		Iexec(reg.ir);
623 		reg.pc = npc-4;
624 	}
625 }
626 
627 void
Iblezl(ulong inst)628 Iblezl(ulong inst)
629 {
630 	int rs;
631 	int off;
632 	ulong npc, r;
633 
634 	rs = (inst>>21)&0x1f;
635 	off = (short)(inst&0xffff);
636 
637 	npc = reg.pc + (off<<2) + 4;
638 	if(trace)
639 		itrace("blez\tr%d,0x%lux", rs, npc);
640 
641 	r = reg.r[rs];
642 	if((r&SIGNBIT) || r == 0) {
643 		/* Do the delay slot */
644 		reg.ir = ifetch(reg.pc+4);
645 		Statbra();
646 		Iexec(reg.ir);
647 		reg.pc = npc-4;
648 	} else
649 		reg.pc += 4;
650 }
651 
652 void
Ibne(ulong inst)653 Ibne(ulong inst)
654 {
655 	int rt, rs;
656 	int off;
657 	ulong npc;
658 
659 	Getrsrt(rs, rt, inst);
660 	off = (short)(inst&0xffff);
661 
662 	npc = reg.pc + (off<<2) + 4;
663 	if(trace)
664 		itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
665 
666 	if(reg.r[rs] != reg.r[rt]) {
667 		/* Do the delay slot */
668 		reg.ir = ifetch(reg.pc+4);
669 		Statbra();
670 		Iexec(reg.ir);
671 		reg.pc = npc-4;
672 	}
673 }
674 
675 void
Ibnel(ulong inst)676 Ibnel(ulong inst)
677 {
678 	int rt, rs;
679 	int off;
680 	ulong npc;
681 
682 	Getrsrt(rs, rt, inst);
683 	off = (short)(inst&0xffff);
684 
685 	npc = reg.pc + (off<<2) + 4;
686 	if(trace)
687 		itrace("bne\tr%d,r%d,0x%lux", rs, rt, npc);
688 
689 	if(reg.r[rs] != reg.r[rt]) {
690 		/* Do the delay slot */
691 		reg.ir = ifetch(reg.pc+4);
692 		Statbra();
693 		Iexec(reg.ir);
694 		reg.pc = npc-4;
695 	} else
696 		reg.pc += 4;
697 }
698 
699 void
Iaddiu(ulong inst)700 Iaddiu(ulong inst)
701 {
702 	int rs, rt;
703 	int imm;
704 
705 	Getrsrt(rs, rt, inst);
706 	imm = (short)(inst&0xffff);
707 
708 	if(trace)
709 		itrace("addiu\tr%d,r%d,#0x%x", rt, rs, imm);
710 
711 	reg.r[rt] = reg.r[rs]+imm;
712 }
713 
714 void
Islti(ulong inst)715 Islti(ulong inst)
716 {
717 	int rs, rt;
718 	int imm;
719 
720 	Getrsrt(rs, rt, inst);
721 	imm = (short)(inst&0xffff);
722 
723 	if(trace)
724 		itrace("slti\tr%d,r%d,#0x%x", rt, rs, imm);
725 
726 	reg.r[rt] = reg.r[rs] < imm ? 1 : 0;
727 }
728 
729 void
Isltiu(ulong inst)730 Isltiu(ulong inst)
731 {
732 	int rs, rt;
733 	int imm;
734 
735 	Getrsrt(rs, rt, inst);
736 	imm = (short)(inst&0xffff);
737 
738 	if(trace)
739 		itrace("sltiu\tr%d,r%d,#0x%x", rt, rs, imm);
740 
741 	reg.r[rt] = (ulong)reg.r[rs] < (ulong)imm ? 1 : 0;
742 }
743 
744 /* ll and sc are implemented as lw and sw, since we simulate a uniprocessor */
745 
746 void
Ill(ulong inst)747 Ill(ulong inst)
748 {
749 	int rt, rb;
750 	int off;
751 	ulong v, va;
752 
753 	Getrbrt(rb, rt, inst);
754 	off = (short)(inst&0xffff);
755 
756 	va = reg.r[rb]+off;
757 
758 	if(trace) {
759 		v = 0;
760 		if(!badvaddr(va, 4))
761 			v = getmem_w(va);
762 		itrace("ll\tr%d,0x%x(r%d) %lux=%lux", rt, off, rb, va, v);
763 	}
764 
765 	reg.r[rt] = getmem_w(va);
766 }
767 
768 void
Isc(ulong inst)769 Isc(ulong inst)
770 {
771 	int rt, rb;
772 	int off;
773 	ulong v;
774 
775 	Getrbrt(rb, rt, inst);
776 	off = (short)(inst&0xffff);
777 
778 	v = reg.r[rt];
779 	if(trace)
780 		itrace("sc\tr%d,0x%x(r%d) %lux=%lux",
781 				rt, off, rb, reg.r[rb]+off, v);
782 
783 	putmem_w(reg.r[rb]+off, v);
784 }
785 
786 enum
787 {
788 	Bltz	= 0,
789 	Bgez	= 1,
790 	Bltzal	= 0x10,
791 	Bgezal	= 0x11,
792 	Bltzl	= 2,
793 	Bgezl	= 3,
794 	Bltzall	= 0x12,
795 	Bgezall	= 0x13,
796 };
797 
798 static char *sbcond[] =
799 {
800 	[Bltz]		"ltz",
801 	[Bgez]		"gez",
802 	[Bltzal]	"ltzal",
803 	[Bgezal]	"gezal",
804 	[Bltzl]		"ltzl",
805 	[Bgezl]		"gezl",
806 	[Bltzall]	"ltzall",
807 	[Bgezall]	"gezall",
808 };
809 
810 void
Ibcond(ulong inst)811 Ibcond(ulong inst)
812 {
813 	int rs, bran;
814 	int off, doit, likely;
815 	ulong npc;
816 
817 	rs = (inst>>21)&0x1f;
818 	bran = (inst>>16)&0x1f;
819 	off = (short)(inst&0xffff);
820 	doit = 0;
821 	likely = 0;
822 
823 	npc = reg.pc + (off<<2) + 4;
824 	switch(bran) {
825 	default:
826 		Bprint(bioout, "bcond=%d\n", bran);
827 		undef(inst);
828 	case Bltzl:
829 		likely = 1;
830 	case Bltz:
831 		if(reg.r[rs]&SIGNBIT)
832 			doit = 1;
833 		break;
834 	case Bgezl:
835 		likely = 1;
836 	case Bgez:
837 		if(!(reg.r[rs]&SIGNBIT))
838 			doit = 1;
839 		break;
840 	case Bltzall:
841 		likely = 1;
842 	case Bltzal:
843 		reg.r[31] = reg.pc+8;
844 		if(reg.r[rs]&SIGNBIT)
845 			doit = 1;
846 		break;
847 	case Bgezall:
848 		likely = 1;
849 	case Bgezal:
850 		reg.r[31] = reg.pc+8;
851 		if(!(reg.r[rs]&SIGNBIT))
852 			doit = 1;
853 		break;
854 	}
855 
856 	if(trace)
857 		itrace("b%s\tr%d,0x%lux", sbcond[bran], rs, npc);
858 
859 	if(doit) {
860 		/* Do the delay slot */
861 		reg.ir = ifetch(reg.pc+4);
862 		Statbra();
863 		Iexec(reg.ir);
864 		reg.pc = npc-4;
865 	} else
866 	if(likely)
867 		reg.pc += 4;
868 
869 }
870