Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
}