xref: /plan9/sys/src/cmd/ki/run.c (revision bd389b369d90320ffee8121f40c4c30619f88097)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <mach.h>
5 #define Extern extern
6 #include "sparc.h"
7 
8 void add(ulong);
9 void and(ulong);
10 void or(ulong);
11 void xor(ulong);
12 void sub(ulong);
13 void andn(ulong);
14 void xnor(ulong);
15 void subcc(ulong);
16 void sll(ulong);
17 void srl(ulong);
18 void sra(ulong);
19 void jmpl(ulong);
20 void andcc(ulong);
21 void xorcc(ulong);
22 void andncc(ulong);
23 void wry(ulong);
24 void rdy(ulong);
25 void mulscc(ulong);
26 void fcmp(ulong);
27 void farith(ulong);
28 void addcc(ulong);
29 void addx(ulong);
30 void addxcc(ulong);
31 void orcc(ulong);
32 void orncc(ulong);
33 void xnorcc(ulong);
34 void orn(ulong);
35 
36 Inst op2[] = {
37 	{ add,		"add",	Iarith },
38 	{ and,		"and",	Iarith },
39 	{ or,		"or",	Iarith },
40 	{ xor,		"xor",	Iarith },
41 	{ sub,		"sub",	Iarith },
42 	{ andn,		"andn", Iarith },
43 	{ orn,		"orn",	Inop },
44 	{ xnor,		"xnor", Iarith },
45 	{ addx,		"addx", Iarith },
46 	{ undef,	"" },
47 	{ undef,	"" },
48 	{ undef,	"" },
49 	{ undef,	"" },
50 	{ undef,	"" },
51 	{ undef,	"" },
52 	{ undef,	"" },
53 	{ addcc, 	"addcc", Iarith },
54 	{ andcc, 	"andcc", Iarith },
55 	{ orcc,	 	"orcc",  Iarith },
56 	{ xorcc, 	"xorcc", Iarith },
57 	{ subcc, 	"subcc", Iarith },
58 	{ andncc,	"andncc",Iarith },
59 	{ orncc, 	"orncc", Iarith },
60 	{ xnorcc,	"xnorcc",Iarith },
61 	{ addxcc,	"addxcc",Iarith },
62 	{ undef,	"" },
63 	{ undef,	"" },
64 	{ undef,	"" },
65 	{ undef,	"" },
66 	{ undef,	"" },
67 	{ undef,	"" },
68 	{ undef,	"" },
69 	{ undef,	"" },
70 	{ undef,	"" },
71 	{ undef,	"" },
72 	{ undef,	"" },
73 	{ mulscc,	"mulscc", Iarith },
74 	{ sll,		"sll",	Iarith },
75 	{ srl,		"srl",	Iarith },
76 	{ sra,		"sra",	Iarith },
77 	{ rdy,		"rdy",	Ireg },
78 	{ undef,	"" },
79 	{ undef,	"" },
80 	{ undef,	"" },
81 	{ undef,	"" },
82 	{ undef,	"" },
83 	{ undef,	"" },
84 	{ undef,	"" },
85 	{ wry,		"wry",	Ireg },
86 	{ undef,	"" },
87 	{ undef,	"" },
88 	{ undef,	"" },
89 	{ farith,	"farith", Ifloat },
90 	{ fcmp,		"fcmp", Ifloat },
91 	{ undef,	"" },
92 	{ undef,	"" },
93 	{ jmpl,		"jmpl", Ibranch },
94 	{ undef,	"" },
95 	{ ta,		"ta",	Isyscall },
96 	{ undef,	"" },
97 	{ undef,	"" },
98 	{ undef,	"" },
99 	{ undef,	"" },
100 	{ undef,	"" },
101 	{ 0 }
102 };
103 
104 void st(ulong);
105 void stb(ulong);
106 void sth(ulong);
107 void ld(ulong);
108 void ldub(ulong);
109 void ldsb(ulong);
110 void lduh(ulong);
111 void stf(ulong);
112 void ldf(ulong);
113 void ldsh(ulong);
114 void std(ulong);
115 void ldd(ulong);
116 void ldstub(ulong);
117 void swap(ulong);
118 void lddf(ulong);
119 void stdf(ulong);
120 
121 Inst op3[] = {
122 	{ ld,		"ld",	Iload },
123 	{ ldub,		"ldub",	Iload },
124 	{ lduh,		"lduh",	Iload },
125 	{ ldd,		"ldd",	Iload },
126 	{ st,		"st",	Istore },
127 	{ stb,		"stb",	Istore },
128 	{ sth,		"sth",	Istore },
129 	{ std,		"std",	Istore },
130 	{ undef,	"" },
131 	{ ldsb,		"ldsb",	Iload },
132 	{ ldsh,		"ldsh", Iload },
133 	{ undef,	"" },
134 	{ undef,	"" },
135 	{ ldstub,	"ldstub", Iload },
136 	{ undef,	"" },
137 	{ swap,		"swap",	Iload },
138 	{ undef,	"" },
139 	{ undef,	"" },
140 	{ undef,	"" },
141 	{ undef,	"" },
142 	{ undef,	"" },
143 	{ undef,	"" },
144 	{ undef,	"" },
145 	{ undef,	"" },
146 	{ undef,	"" },
147 	{ undef,	"" },
148 	{ undef,	"" },
149 	{ undef,	"" },
150 	{ undef,	"" },
151 	{ undef,	"" },
152 	{ undef,	"" },
153 	{ undef,	"" },
154 	{ ldf,		"ldf",	Ifloat },
155 	{ undef,	"" },
156 	{ undef,	"" },
157 	{ lddf,		"lddf", Ifloat },
158 	{ stf,		"stf",	Ifloat },
159 	{ undef,	"" },
160 	{ undef,	"" },
161 	{ stdf,		"stdf",	Ifloat },
162 	{ undef,	"" },
163 	{ undef,	"" },
164 	{ undef,	"" },
165 	{ undef,	"" },
166 	{ undef,	"" },
167 	{ undef,	"" },
168 	{ undef,	"" },
169 	{ undef,	"" },
170 	{ undef,	"" },
171 	{ undef,	"" },
172 	{ undef,	"" },
173 	{ undef,	"" },
174 	{ undef,	"" },
175 	{ undef,	"" },
176 	{ undef,	"" },
177 	{ undef,	"" },
178 	{ undef,	"" },
179 	{ undef,	"" },
180 	{ undef,	"" },
181 	{ undef,	"" },
182 	{ undef,	"" },
183 	{ undef,	"" },
184 	{ undef,	"" },
185 	{ undef,	"" },
186 	{ 0 }
187 };
188 
189 void sethi(ulong);
190 void bicc(ulong);
191 void fbcc(ulong);
192 void call(ulong);
193 
194 Inst op0[] = {
195 	{ undef,	"" },
196 	{ undef,	"" },
197 	{ bicc,		"bicc",	Ibranch },
198 	{ undef,	"" },
199 	{ sethi,	"sethi",Iarith },
200 	{ undef,	"" },
201 	{ fbcc,		"fbcc",	Ibranch },
202 	{ undef,	"" },
203 	/* This is a fake and connot be reached by op0 decode */
204 	{ call,		"call", Ibranch },
205 	{ 0 }
206 };
207 
208 void call(ulong);
209 
210 void
run(void)211 run(void)
212 {
213 	do {
214 		reg.r[0] = 0;
215 		reg.ir = ifetch(reg.pc);
216 		switch(reg.ir>>30) {
217 		case 0:
218 			ci = &op0[(reg.ir>>22)&0x07];
219 			ci->count++;
220 			(*ci->func)(reg.ir);
221 			break;
222 		case 1:
223 			ci = &op0[8];
224 			ci->count++;
225 			call(reg.ir);
226 			break;
227 		case 2:
228 			ci = &op2[(reg.ir>>19)&0x3f];
229 			ci->count++;
230 			(*ci->func)(reg.ir);
231 			break;
232 		case 3:
233 			ci = &op3[(reg.ir>>19)&0x3f];
234 			ci->count++;
235 			(*ci->func)(reg.ir);
236 			break;
237 		}
238 		reg.pc += 4;
239 		if(bplist)
240 			brkchk(reg.pc, Instruction);
241 	}while(--count);
242 }
243 
244 void
ilock(int rd)245 ilock(int rd)
246 {
247 	ulong ir;
248 
249 	ir = getmem_4(reg.pc+4);
250 	switch(ir>>30) {
251 	case 0:
252 	case 1:
253 		break;
254 	case 2:
255 		if(((ir>>20)&0x1f) == 0x1a)		/* floating point */
256 			break;
257 	case 3:
258 		if(rd == ((ir>>14)&0x1f)) {
259 			loadlock++;
260 			break;
261 		}
262 		if(ir&IMMBIT)
263 			break;
264 		if(rd == (ir&0x1f))
265 			loadlock++;
266 		break;
267 	}
268 }
269 
270 void
delay(ulong npc)271 delay(ulong npc)
272 {
273 	ulong opc;
274 
275 	reg.r[0] = 0;
276 	if(reg.ir != NOP)
277 		ci->useddelay++;
278 	switch(reg.ir>>30) {
279 	case 0:
280 		ci = &op0[(reg.ir>>22)&0x07];
281 		ci->count++;
282 		(*ci->func)(reg.ir);
283 		break;
284 	case 1:
285 		ci = &op0[8];
286 		ci->count++;
287 		call(reg.ir);
288 		break;
289 	case 2:
290 		ci = &op2[(reg.ir>>19)&0x3f];
291 		ci->count++;
292 		opc = reg.pc;
293 		reg.pc = npc-4;
294 		(*ci->func)(reg.ir);
295 		reg.pc = opc;
296 		break;
297 	case 3:
298 		ci = &op3[(reg.ir>>19)&0x3f];
299 		ci->count++;
300 		opc = reg.pc;
301 		reg.pc = npc-4;
302 		(*ci->func)(reg.ir);
303 		reg.pc = opc;
304 		break;
305 	}
306 }
307 
308 void
undef(ulong ir)309 undef(ulong ir)
310 {
311 /*	Bprint(bioout, "op=%d op2=%d op3=%d\n", ir>>30, (ir>>21)&0x7, (ir>>19)&0x3f); */
312 	Bprint(bioout, "illegal_instruction IR #%.8lux\n", ir);
313 	longjmp(errjmp, 0);
314 }
315 
316 void
sub(ulong ir)317 sub(ulong ir)
318 {
319 	long v;
320 	int rd, rs1, rs2;
321 
322 	getrop23(ir);
323 	if(ir&IMMBIT) {
324 		ximm(v, ir);
325 		if(trace)
326 			itrace("sub\tr%d,#0x%x,r%d", rs1, v, rd);
327 	}
328 	else {
329 		v = reg.r[rs2];
330 		if(trace)
331 			itrace("sub\tr%d,r%d,r%d", rs1, rs2, rd);
332 	}
333 	reg.r[rd] = reg.r[rs1] - v;
334 }
335 
336 void
sll(ulong ir)337 sll(ulong ir)
338 {
339 	long v;
340 	int rd, rs1, rs2;
341 
342 	getrop23(ir);
343 	if(ir&IMMBIT) {
344 		ximm(v, ir);
345 		if(trace)
346 			itrace("sll\tr%d,#0x%x,r%d", rs1, v, rd);
347 	}
348 	else {
349 		v = reg.r[rs2]&0x1F;
350 		if(trace)
351 			itrace("sll\tr%d,r%d,r%d", rs1, rs2, rd);
352 	}
353 	reg.r[rd] = reg.r[rs1] << v;
354 }
355 
356 void
srl(ulong ir)357 srl(ulong ir)
358 {
359 	long v;
360 	int rd, rs1, rs2;
361 
362 	getrop23(ir);
363 	if(ir&IMMBIT) {
364 		ximm(v, ir);
365 		if(trace)
366 			itrace("srl\tr%d,#0x%x,r%d", rs1, v, rd);
367 	}
368 	else {
369 		v = reg.r[rs2];
370 		if(trace)
371 			itrace("srl\tr%d,r%d,r%d", rs1, rs2, rd);
372 	}
373 	reg.r[rd] = (ulong)reg.r[rs1] >> v;
374 }
375 
376 void
sra(ulong ir)377 sra(ulong ir)
378 {
379 	long v;
380 	int rd, rs1, rs2;
381 
382 	getrop23(ir);
383 	if(ir&IMMBIT) {
384 		ximm(v, ir);
385 		if(trace)
386 			itrace("sra\tr%d,#0x%x,r%d", rs1, v, rd);
387 	}
388 	else {
389 		v = reg.r[rs2];
390 		if(trace)
391 			itrace("sra\tr%d,r%d,r%d", rs1, rs2, rd);
392 	}
393 	if(reg.r[rs1]&SIGNBIT)
394 		reg.r[rd] = reg.r[rs1]>>v | ~((1<<(32-v))-1);
395 	else
396 		reg.r[rd] = reg.r[rs1]>>v;
397 }
398 
399 void
subcc(ulong ir)400 subcc(ulong ir)
401 {
402 	long v;
403 	int b31rs1, b31op2, b31res, r, rd, rs1, rs2;
404 
405 	getrop23(ir);
406 	if(ir&IMMBIT) {
407 		ximm(v, ir);
408 		if(trace)
409 			itrace("subcc\tr%d,#0x%x,r%d", rs1, v, rd);
410 	}
411 	else {
412 		v = reg.r[rs2];
413 		if(trace)
414 			itrace("subcc\tr%d,r%d,r%d", rs1, rs2, rd);
415 	}
416 	r = reg.r[rs1] - v;
417 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
418 	if(r == 0)
419 		reg.psr |= PSR_z;
420 	if(r < 0)
421 		reg.psr |= PSR_n;
422 
423 	b31rs1 = reg.r[rs1]>>31;
424 	b31op2 = v>>31;
425 	b31res = r>>31;
426 
427 	if((b31rs1 & ~b31op2 & ~b31res)|(~b31rs1 & b31op2 & b31res))
428 		reg.psr |= PSR_v;
429 
430 	if((~b31rs1 & b31op2)|(b31res & (~b31rs1|b31op2)))
431 		reg.psr |= PSR_c;
432 
433 	reg.r[rd] = r;
434 
435 }
436 
437 void
add(ulong ir)438 add(ulong ir)
439 {
440 	long v;
441 	int rd, rs1, rs2;
442 
443 	getrop23(ir);
444 	if(ir&IMMBIT) {
445 		ximm(v, ir);
446 		if(trace)
447 			itrace("add\tr%d,#0x%x,r%d", rs1, v, rd);
448 	}
449 	else {
450 		v = reg.r[rs2];
451 		if(trace)
452 			itrace("add\tr%d,r%d,r%d", rs1, rs2, rd);
453 	}
454 	reg.r[rd] = reg.r[rs1] + v;
455 }
456 
457 void
addcc(ulong ir)458 addcc(ulong ir)
459 {
460 	long v, r;
461 	int rd, rs1, rs2, b31rs1, b31op2, b31r;
462 
463 	getrop23(ir);
464 	if(ir&IMMBIT) {
465 		ximm(v, ir);
466 		if(trace)
467 			itrace("addcc\tr%d,#0x%x,r%d", rs1, v, rd);
468 	}
469 	else {
470 		v = reg.r[rs2];
471 		if(trace)
472 			itrace("addcc\tr%d,r%d,r%d", rs1, rs2, rd);
473 	}
474 	r = reg.r[rs1] + v;
475 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
476 	if(r == 0)
477 		reg.psr |= PSR_z;
478 	if(r < 0)
479 		reg.psr |= PSR_n;
480 
481 	b31rs1 = reg.r[rs1]>>31;
482 	b31op2 = v>>31;
483 	b31r = r>>31;
484 	if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r))
485 		reg.psr |= PSR_v;
486 	if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2)))
487 		reg.psr |= PSR_c;
488 
489 	reg.r[rd] = r;
490 }
491 
492 void
addx(ulong ir)493 addx(ulong ir)
494 {
495 	long v;
496 	int rd, rs1, rs2;
497 
498 	getrop23(ir);
499 	if(ir&IMMBIT) {
500 		ximm(v, ir);
501 		if(trace)
502 			itrace("addx\tr%d,#0x%x,r%d", rs1, v, rd);
503 	}
504 	else {
505 		v = reg.r[rs2];
506 		if(trace)
507 			itrace("addx\tr%d,r%d,r%d", rs1, rs2, rd);
508 	}
509 	if(reg.psr&PSR_c)
510 		v++;
511 	reg.r[rd] = reg.r[rs1] + v;
512 }
513 
514 void
addxcc(ulong ir)515 addxcc(ulong ir)
516 {
517 	long r, v;
518 	int rd, rs1, rs2, b31rs1, b31op2, b31r;
519 
520 	getrop23(ir);
521 	if(ir&IMMBIT) {
522 		ximm(v, ir);
523 		if(trace)
524 			itrace("addxcc\tr%d,#0x%x,r%d", rs1, v, rd);
525 	}
526 	else {
527 		v = reg.r[rs2];
528 		if(trace)
529 			itrace("addxcc\tr%d,r%d,r%d", rs1, rs2, rd);
530 	}
531 	if(reg.psr&PSR_c)
532 		v++;
533 
534 	r = reg.r[rs1] + v;
535 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
536 	if(r == 0)
537 		reg.psr |= PSR_z;
538 	if(r < 0)
539 		reg.psr |= PSR_n;
540 
541 	b31rs1 = reg.r[rs1]>>31;
542 	b31op2 = v>>31;
543 	b31r = r>>31;
544 	if((b31rs1 & b31op2 & ~b31r)|(~b31rs1 & ~b31op2 & b31r))
545 		reg.psr |= PSR_v;
546 	if((b31rs1 & b31op2) | (~b31r & (b31rs1 | b31op2)))
547 		reg.psr |= PSR_c;
548 
549 	reg.r[rd] = r;
550 }
551 
552 void
wry(ulong ir)553 wry(ulong ir)
554 {
555 	long v;
556 	int rd, rs1, rs2;
557 
558 	getrop23(ir);
559 	if(rd != 0)
560 		undef(ir);
561 	if(ir&IMMBIT) {
562 		ximm(v, ir);
563 		if(trace)
564 			itrace("wry\tr%d,#0x%x,Y", rs1, v);
565 	}
566 	else {
567 		v = reg.r[rs2];
568 		if(trace)
569 			itrace("wry\tr%d,r%d,Y", rs1, rs2);
570 	}
571 	reg.Y = reg.r[rs1] + v;
572 }
573 
574 void
rdy(ulong ir)575 rdy(ulong ir)
576 {
577 	int rd, rs1, rs2;
578 
579 	getrop23(ir);
580 	USED(rs2);
581 	if(rs1 != 0)
582 		undef(ir);
583 
584 	if(trace)
585 		itrace("rdy\tY,r%d", rd);
586 
587 	reg.r[rd] = reg.Y;
588 }
589 
590 void
and(ulong ir)591 and(ulong ir)
592 {
593 	long v;
594 	int rd, rs1, rs2;
595 
596 	getrop23(ir);
597 	if(ir&IMMBIT) {
598 		ximm(v, ir);
599 		if(trace)
600 			itrace("and\tr%d,#0x%x,r%d", rs1, v, rd);
601 	}
602 	else {
603 		v = reg.r[rs2];
604 		if(trace)
605 			itrace("and\tr%d,r%d,r%d", rs1, rs2, rd);
606 	}
607 	reg.r[rd] = reg.r[rs1] & v;
608 }
609 
610 void
andcc(ulong ir)611 andcc(ulong ir)
612 {
613 	long v, r;
614 	int rd, rs1, rs2;
615 
616 	getrop23(ir);
617 	if(ir&IMMBIT) {
618 		ximm(v, ir);
619 		if(trace)
620 			itrace("andcc\tr%d,#0x%x,r%d", rs1, v, rd);
621 	}
622 	else {
623 		v = reg.r[rs2];
624 		if(trace)
625 			itrace("andcc\tr%d,r%d,r%d", rs1, rs2, rd);
626 	}
627 	r = reg.r[rs1] & v;
628 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
629 	if(r == 0)
630 		reg.psr |= PSR_z;
631 	if(r < 0)
632 		reg.psr |= PSR_n;
633 
634 	reg.r[rd] = r;
635 }
636 
637 void
orcc(ulong ir)638 orcc(ulong ir)
639 {
640 	long v, r;
641 	int rd, rs1, rs2;
642 
643 	getrop23(ir);
644 	if(ir&IMMBIT) {
645 		ximm(v, ir);
646 		if(trace)
647 			itrace("orcc\tr%d,#0x%x,r%d", rs1, v, rd);
648 	}
649 	else {
650 		v = reg.r[rs2];
651 		if(trace)
652 			itrace("orcc\tr%d,r%d,r%d", rs1, rs2, rd);
653 	}
654 	r = reg.r[rs1] | v;
655 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
656 	if(r == 0)
657 		reg.psr |= PSR_z;
658 	if(r < 0)
659 		reg.psr |= PSR_n;
660 
661 	reg.r[rd] = r;
662 }
663 
664 void
mulscc(ulong ir)665 mulscc(ulong ir)
666 {
667 	int b, n, v, rd, rs1, rs2;
668 	long o1, o2, r, b31o1, b31o2, b31r;
669 
670 	getrop23(ir);
671 	if(ir&IMMBIT) {
672 		ximm(o2, ir);
673 		if(trace)
674 			itrace("mulscc\tr%d,#0x%x,r%d", rs1, o2, rd);
675 	}
676 	else {
677 		o2 = reg.r[rs2];
678 		if(trace)
679 			itrace("mulscc\tr%d,r%d,r%d", rs1, rs2, rd);
680 	}
681 	o1 = reg.r[rs1]>>1;
682 	n = reg.psr&PSR_n ? 1 : 0;
683 	v = reg.psr&PSR_v ? 1 : 0;
684 
685 	o1 |= (n ^ v)<<31;
686 	if((reg.Y&1) == 0)
687 		o2 = 0;
688 
689 	r = o1 + o2;
690 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
691 	if(r == 0)
692 		reg.psr |= PSR_z;
693 	if(r < 0)
694 		reg.psr |= PSR_n;
695 
696 	b31o1 = o1>>31;
697 	b31o2 = o2>>31;
698 	b31r = r>>31;
699 	if((b31o1 & b31o2 & ~b31r) | (~b31o1 & ~b31o2 & b31r))
700 		reg.psr |= PSR_v;
701 	if((b31o1 & b31o2) | (~b31r & (b31o1 | b31o2)))
702 		reg.psr |= PSR_c;
703 
704 	b = reg.r[rs1]&1;
705 	reg.Y = (reg.Y>>1)|(b<<31);
706 	reg.r[rd] = r;
707 }
708 
709 void
or(ulong ir)710 or(ulong ir)
711 {
712 	long v;
713 	int rd, rs1, rs2;
714 
715 	getrop23(ir);
716 	if(ir&IMMBIT) {
717 		ximm(v, ir);
718 		if(trace)
719 			itrace("or\tr%d,#0x%x,r%d", rs1, v, rd);
720 	}
721 	else {
722 		v = reg.r[rs2];
723 		if(trace)
724 			itrace("or\tr%d,r%d,r%d", rs1, rs2, rd);
725 	}
726 	reg.r[rd] = reg.r[rs1] | v;
727 }
728 
729 void
xor(ulong ir)730 xor(ulong ir)
731 {
732 	long v;
733 	int rd, rs1, rs2;
734 
735 	getrop23(ir);
736 	if(ir&IMMBIT) {
737 		ximm(v, ir);
738 		if(trace)
739 			itrace("xor\tr%d,#0x%x,r%d", rs1, v, rd);
740 	}
741 	else {
742 		v = reg.r[rs2];
743 		if(trace)
744 			itrace("xor\tr%d,r%d,r%d", rs1, rs2, rd);
745 	}
746 	reg.r[rd] = reg.r[rs1] ^ v;
747 }
748 
749 void
xorcc(ulong ir)750 xorcc(ulong ir)
751 {
752 	long v, r;
753 	int rd, rs1, rs2;
754 
755 	getrop23(ir);
756 	if(ir&IMMBIT) {
757 		ximm(v, ir);
758 		if(trace)
759 			itrace("xorcc\tr%d,#0x%x,r%d", rs1, v, rd);
760 	}
761 	else {
762 		v = reg.r[rs2];
763 		if(trace)
764 			itrace("xorcc\tr%d,r%d,r%d", rs1, rs2, rd);
765 	}
766 	r = reg.r[rs1] ^ v;
767 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
768 	if(r == 0)
769 		reg.psr |= PSR_z;
770 	if(r < 0)
771 		reg.psr |= PSR_n;
772 
773 	reg.r[rd] = r;
774 }
775 
776 void
andn(ulong ir)777 andn(ulong ir)
778 {
779 	long v;
780 	int rd, rs1, rs2;
781 
782 	getrop23(ir);
783 	if(ir&IMMBIT) {
784 		ximm(v, ir);
785 		if(trace)
786 			itrace("andn\tr%d,#0x%x,r%d", rs1, v, rd);
787 	}
788 	else {
789 		v = reg.r[rs2];
790 		if(trace)
791 			itrace("andn\tr%d,r%d,r%d", rs1, rs2, rd);
792 	}
793 	reg.r[rd] = reg.r[rs1] & ~v;
794 }
795 
796 void
andncc(ulong ir)797 andncc(ulong ir)
798 {
799 	long v, r;
800 	int rd, rs1, rs2;
801 
802 	getrop23(ir);
803 	if(ir&IMMBIT) {
804 		ximm(v, ir);
805 		if(trace)
806 			itrace("andncc\tr%d,#0x%x,r%d", rs1, v, rd);
807 	}
808 	else {
809 		v = reg.r[rs2];
810 		if(trace)
811 			itrace("andncc\tr%d,r%d,r%d", rs1, rs2, rd);
812 	}
813 	r = reg.r[rs1] & ~v;
814 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
815 	if(r == 0)
816 		reg.psr |= PSR_z;
817 	if(r < 0)
818 		reg.psr |= PSR_n;
819 
820 	reg.r[rd] = r;
821 }
822 
823 void
orn(ulong ir)824 orn(ulong ir)
825 {
826 	long v;
827 	int rd, rs1, rs2;
828 
829 	getrop23(ir);
830 	if(rd == 0 && rs1 == 0)	/* ken used orn r0,r0,r0 as nop */
831 		nopcount++;
832 
833 	if(ir&IMMBIT) {
834 		ximm(v, ir);
835 		if(trace)
836 			itrace("orn\tr%d,#0x%x,r%d", rs1, v, rd);
837 	}
838 	else {
839 		v = reg.r[rs2];
840 		if(trace)
841 			itrace("orn\tr%d,r%d,r%d", rs1, rs2, rd);
842 	}
843 	reg.r[rd] = reg.r[rs1] | ~v;
844 }
845 
846 void
orncc(ulong ir)847 orncc(ulong ir)
848 {
849 	long r, v;
850 	int rd, rs1, rs2;
851 
852 	getrop23(ir);
853 	if(ir&IMMBIT) {
854 		ximm(v, ir);
855 		if(trace)
856 			itrace("orncc\tr%d,#0x%x,r%d", rs1, v, rd);
857 	}
858 	else {
859 		v = reg.r[rs2];
860 		if(trace)
861 			itrace("orncc\tr%d,r%d,r%d", rs1, rs2, rd);
862 	}
863 	r = reg.r[rs1] | ~v;
864 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
865 	if(r == 0)
866 		reg.psr |= PSR_z;
867 	if(r < 0)
868 		reg.psr |= PSR_n;
869 
870 	reg.r[rd] = r;
871 }
872 
873 void
xnor(ulong ir)874 xnor(ulong ir)
875 {
876 	long v;
877 	int rd, rs1, rs2;
878 
879 	getrop23(ir);
880 	if(ir&IMMBIT) {
881 		ximm(v, ir);
882 		if(trace)
883 			itrace("xnor\tr%d,#0x%x,r%d", rs1, v, rd);
884 	}
885 	else {
886 		v = reg.r[rs2];
887 		if(trace)
888 			itrace("xnor\tr%d,r%d,r%d", rs1, rs2, rd);
889 	}
890 	reg.r[rd] = reg.r[rs1] ^ ~v;
891 }
892 
893 void
xnorcc(ulong ir)894 xnorcc(ulong ir)
895 {
896 	long v, r;
897 	int rd, rs1, rs2;
898 
899 	getrop23(ir);
900 	if(ir&IMMBIT) {
901 		ximm(v, ir);
902 		if(trace)
903 			itrace("xnorcc\tr%d,#0x%x,r%d", rs1, v, rd);
904 	}
905 	else {
906 		v = reg.r[rs2];
907 		if(trace)
908 			itrace("xnorcc\tr%d,r%d,r%d", rs1, rs2, rd);
909 	}
910 	r = reg.r[rs1] ^ ~v;
911 	reg.psr &= ~(PSR_z|PSR_n|PSR_c|PSR_v);
912 	if(r == 0)
913 		reg.psr |= PSR_z;
914 	if(r < 0)
915 		reg.psr |= PSR_n;
916 
917 	reg.r[rd] = r;
918 }
919 
920 void
st(ulong ir)921 st(ulong ir)
922 {
923 	ulong ea;
924 	int rd, rs1, rs2;
925 
926 	getrop23(ir);
927 	if(ir&IMMBIT) {
928 		ximm(ea, ir);
929 		if(trace)
930 			itrace("st\tr%d,0x%lux(r%d) %lux=%lux",
931 					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]);
932 		ea += reg.r[rs1];
933 	}
934 	else {
935 		ea = reg.r[rs1] + reg.r[rs2];
936 		if(trace)
937 			itrace("st\tr%d,[r%d+r%d] %lux=%lux",
938 					rd, rs1, rs2, ea, reg.r[rd]);
939 	}
940 
941 	putmem_w(ea, reg.r[rd]);
942 }
943 
944 void
std(ulong ir)945 std(ulong ir)
946 {
947 	ulong ea;
948 	int rd, rs1, rs2;
949 
950 	getrop23(ir);
951 	if(ir&IMMBIT) {
952 		ximm(ea, ir);
953 		if(trace)
954 			itrace("std\tr%d,0x%lux(r%d) %lux=%lux",
955 					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]);
956 		ea += reg.r[rs1];
957 	}
958 	else {
959 		ea = reg.r[rs1] + reg.r[rs2];
960 		if(trace)
961 			itrace("std\tr%d,[r%d+r%d] %lux=%lux",
962 					rd, rs1, rs2, ea, reg.r[rd]);
963 	}
964 
965 	putmem_w(ea, reg.r[rd]);
966 	putmem_w(ea+4, reg.r[rd+1]);
967 }
968 
969 void
stb(ulong ir)970 stb(ulong ir)
971 {
972 	ulong ea;
973 	int rd, rs1, rs2;
974 
975 	getrop23(ir);
976 	if(ir&IMMBIT) {
977 		ximm(ea, ir);
978 		if(trace)
979 			itrace("stb\tr%d,0x%lux(r%d) %lux=%lux",
980 					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xff);
981 		ea += reg.r[rs1];
982 	}
983 	else {
984 		ea = reg.r[rs1] + reg.r[rs2];
985 		if(trace)
986 			itrace("stb\tr%d,[r%d+r%d] %lux=%lux",
987 					rd, rs1, rs2, ea, reg.r[rd]&0xff);
988 	}
989 
990 	putmem_b(ea, reg.r[rd]);
991 }
992 
993 void
sth(ulong ir)994 sth(ulong ir)
995 {
996 	ulong ea;
997 	int rd, rs1, rs2;
998 
999 	getrop23(ir);
1000 	if(ir&IMMBIT) {
1001 		ximm(ea, ir);
1002 		if(trace)
1003 			itrace("sth\tr%d,0x%lux(r%d) %lux=%lux",
1004 					rd, ea, rs1, ea+reg.r[rs1], reg.r[rd]&0xffff);
1005 		ea += reg.r[rs1];
1006 	}
1007 	else {
1008 		ea = reg.r[rs1] + reg.r[rs2];
1009 		if(trace)
1010 			itrace("sth\tr%d,[r%d+r%d] %lux=%lux",
1011 					rd, rs1, rs2, ea, reg.r[rd]&0xffff);
1012 	}
1013 
1014 	putmem_h(ea, reg.r[rd]);
1015 }
1016 
1017 void
ld(ulong ir)1018 ld(ulong ir)
1019 {
1020 	ulong ea;
1021 	int rd, rs1, rs2;
1022 
1023 	getrop23(ir);
1024 	if(ir&IMMBIT) {
1025 		ximm(ea, ir);
1026 		if(trace)
1027 			itrace("ld\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
1028 		ea += reg.r[rs1];
1029 	}
1030 	else {
1031 		ea = reg.r[rs1] + reg.r[rs2];
1032 		if(trace)
1033 			itrace("ld\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1034 	}
1035 
1036 	reg.r[rd] = getmem_w(ea);
1037 	ilock(rd);
1038 }
1039 
1040 void
swap(ulong ir)1041 swap(ulong ir)
1042 {
1043 	ulong t, ea;
1044 	int rd, rs1, rs2;
1045 
1046 	getrop23(ir);
1047 	if(ir&IMMBIT) {
1048 		ximm(ea, ir);
1049 		if(trace)
1050 			itrace("swap\tr%d,0x%lux(r%d) ea=%lux",
1051 						rd, ea, rs1, ea+reg.r[rs1]);
1052 		ea += reg.r[rs1];
1053 	}
1054 	else {
1055 		ea = reg.r[rs1] + reg.r[rs2];
1056 		if(trace)
1057 			itrace("swap\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1058 	}
1059 
1060 	t = reg.r[rd];
1061 	reg.r[rd] = getmem_w(ea);
1062 	putmem_w(ea, t);
1063 }
1064 
1065 void
ldd(ulong ir)1066 ldd(ulong ir)
1067 {
1068 	ulong ea;
1069 	int rd, rs1, rs2;
1070 
1071 	getrop23(ir);
1072 	if(ir&IMMBIT) {
1073 		ximm(ea, ir);
1074 		if(trace)
1075 			itrace("ldd\tr%d,0x%lux(r%d) ea=%lux",rd, ea, rs1, ea+reg.r[rs1]);
1076 		ea += reg.r[rs1];
1077 	}
1078 	else {
1079 		ea = reg.r[rs1] + reg.r[rs2];
1080 		if(trace)
1081 			itrace("ldd\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1082 	}
1083 
1084 	reg.r[rd] = getmem_w(ea);
1085 	reg.r[rd+1] = getmem_w(ea+4);
1086 }
1087 
1088 void
ldub(ulong ir)1089 ldub(ulong ir)
1090 {
1091 	ulong ea;
1092 	int rd, rs1, rs2;
1093 
1094 	getrop23(ir);
1095 	if(ir&IMMBIT) {
1096 		ximm(ea, ir);
1097 		if(trace)
1098 			itrace("ldub\tr%d,0x%lux(r%d) ea=%lux",
1099 						rd, ea, rs1, ea+reg.r[rs1]);
1100 		ea += reg.r[rs1];
1101 	}
1102 	else {
1103 		ea = reg.r[rs1] + reg.r[rs2];
1104 		if(trace)
1105 			itrace("ldub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1106 	}
1107 
1108 	reg.r[rd] = getmem_b(ea) & 0xff;
1109 	ilock(rd);
1110 }
1111 
1112 void
ldstub(ulong ir)1113 ldstub(ulong ir)
1114 {
1115 	ulong ea;
1116 	int rd, rs1, rs2;
1117 
1118 	getrop23(ir);
1119 	if(ir&IMMBIT) {
1120 		ximm(ea, ir);
1121 		if(trace)
1122 			itrace("ldstub\tr%d,0x%lux(r%d) ea=%lux",
1123 						rd, ea, rs1, ea+reg.r[rs1]);
1124 		ea += reg.r[rs1];
1125 	}
1126 	else {
1127 		ea = reg.r[rs1] + reg.r[rs2];
1128 		if(trace)
1129 			itrace("ldstub\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1130 	}
1131 
1132 	reg.r[rd] = getmem_b(ea) & 0xff;
1133 	putmem_b(ea, 0xff);
1134 }
1135 
1136 void
ldsb(ulong ir)1137 ldsb(ulong ir)
1138 {
1139 	ulong ea;
1140 	int rd, rs1, rs2;
1141 
1142 	getrop23(ir);
1143 	if(ir&IMMBIT) {
1144 		ximm(ea, ir);
1145 		if(trace)
1146 			itrace("ldsb\tr%d,0x%lux(r%d) ea=%lux",
1147 						rd, ea, rs1, ea+reg.r[rs1]);
1148 		ea += reg.r[rs1];
1149 	}
1150 	else {
1151 		ea = reg.r[rs1] + reg.r[rs2];
1152 		if(trace)
1153 			itrace("ldsb\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1154 	}
1155 
1156 	reg.r[rd] = (schar)getmem_b(ea);
1157 	ilock(rd);
1158 }
1159 
1160 void
lduh(ulong ir)1161 lduh(ulong ir)
1162 {
1163 	ulong ea;
1164 	int rd, rs1, rs2;
1165 
1166 	getrop23(ir);
1167 	if(ir&IMMBIT) {
1168 		ximm(ea, ir);
1169 		if(trace)
1170 			itrace("lduh\tr%d,0x%lux(r%d) ea=%lux",
1171 						rd, ea, rs1, ea+reg.r[rs1]);
1172 		ea += reg.r[rs1];
1173 	}
1174 	else {
1175 		ea = reg.r[rs1] + reg.r[rs2];
1176 		if(trace)
1177 			itrace("lduh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1178 	}
1179 
1180 	reg.r[rd] = getmem_h(ea) & 0xffff;
1181 	ilock(rd);
1182 }
1183 
1184 void
ldsh(ulong ir)1185 ldsh(ulong ir)
1186 {
1187 	ulong ea;
1188 	int rd, rs1, rs2;
1189 
1190 	getrop23(ir);
1191 	if(ir&IMMBIT) {
1192 		ximm(ea, ir);
1193 		if(trace)
1194 			itrace("ldsh\tr%d,0x%lux(r%d) ea=%lux",
1195 						rd, ea, rs1, ea+reg.r[rs1]);
1196 		ea += reg.r[rs1];
1197 	}
1198 	else {
1199 		ea = reg.r[rs1] + reg.r[rs2];
1200 		if(trace)
1201 			itrace("ldsh\tr%d,[r%d+r%d] ea=%lux", rd, rs1, rs2, ea);
1202 	}
1203 
1204 	reg.r[rd] = (short)getmem_h(ea);
1205 	ilock(rd);
1206 }
1207 
1208 void
sethi(ulong ir)1209 sethi(ulong ir)
1210 {
1211 	int rd;
1212 	ulong v;
1213 
1214 	rd = (ir>>25)&0x1f;
1215 	v = (ir&0x3FFFFF)<<10;
1216 
1217 	if(rd == 0)
1218 		nopcount++;
1219 
1220 	if(trace)
1221 		itrace("sethi\t0x%lux,r%d", v, rd);
1222 
1223 	reg.r[rd] = v;
1224 }
1225 
1226 void
call(ulong ir)1227 call(ulong ir)
1228 {
1229 	Symbol s;
1230 	ulong npc;
1231 
1232 	npc = (ir<<2) + reg.pc;
1233 	if(trace)
1234 		itrace("call\t%lux", npc);
1235 
1236 	ci->taken++;
1237 	reg.r[15] = reg.pc;
1238 	reg.ir = ifetch(reg.pc+4);
1239 	delay(npc);
1240 
1241 	if(calltree) {
1242 		findsym(npc, CTEXT, &s);
1243 		Bprint(bioout, "%8lux %s(", reg.pc, s.name);
1244 		printparams(&s, reg.r[1]);
1245 		Bprint(bioout, "from ");
1246 		printsource(reg.pc);
1247 		Bputc(bioout, '\n');
1248 	}
1249 	npc -= 4;
1250 	reg.pc = npc;
1251 }
1252 
1253 void
jmpl(ulong ir)1254 jmpl(ulong ir)
1255 {
1256 	ulong ea, o;
1257 	Symbol s;
1258 	int rd, rs1, rs2;
1259 
1260 	getrop23(ir);
1261 	if(ir&IMMBIT) {
1262 		ximm(ea, ir);
1263 		o = ea;
1264 		if(trace)
1265 			itrace("jmpl\t0x%lux(r%d),r%d", ea, rs1, rd);
1266 
1267 		ea += reg.r[rs1];
1268 		if(calltree && rd == 0 && o == 8) {
1269 			findsym(ea-4, CTEXT, &s);
1270 			Bprint(bioout, "%8lux return to %lux %s r7=%lux\n",
1271 						reg.pc, ea-4, s.name, reg.r[7]);
1272 		}
1273 	}
1274 	else {
1275 		ea = reg.r[rs1] + reg.r[rs2];
1276 		if(trace)
1277 			itrace("jmpl\t[r%d+r%d],r%d", rs1, rs2, rd);
1278 	}
1279 
1280 	ci->taken++;
1281 	reg.r[rd] = reg.pc;
1282 	reg.ir = ifetch(reg.pc+4);
1283 	delay(ea);
1284 	reg.pc = ea-4;
1285 }
1286 
1287 void
bicc(ulong ir)1288 bicc(ulong ir)
1289 {
1290 	char *op;
1291 	ulong npc, anul, ba;
1292 	int takeit, z, v, n, c;
1293 
1294 	SET(op, takeit);
1295 	ba = 0;
1296 	switch((ir>>25)&0x0F) {
1297 	case 0:
1298 		op = "bn";
1299 		takeit = 0;
1300 		break;
1301 	case 1:
1302 		op = "be";
1303 		takeit = reg.psr&PSR_z;
1304 		break;
1305 	case 2:
1306 		op = "ble";
1307 		z = reg.psr&PSR_z ? 1 : 0;
1308 		v = reg.psr&PSR_v ? 1 : 0;
1309 		n = reg.psr&PSR_n ? 1 : 0;
1310 		takeit = z | (n ^ v);
1311 		break;
1312 	case 3:
1313 		op = "bl";
1314 		v = reg.psr&PSR_v ? 1 : 0;
1315 		n = reg.psr&PSR_n ? 1 : 0;
1316 		takeit = n ^ v;
1317 		break;
1318 	case 4:
1319 		op = "bleu";
1320 		z = reg.psr&PSR_z ? 1 : 0;
1321 		c = reg.psr&PSR_c ? 1 : 0;
1322 		takeit = c | z;
1323 		break;
1324 	case 5:
1325 		op = "bcs";
1326 		takeit = reg.psr&PSR_c;
1327 		break;
1328 	case 6:
1329 		op = "bneg";
1330 		takeit = reg.psr&PSR_n;
1331 		break;
1332 	case 7:
1333 		op = "bvs";
1334 		takeit = reg.psr&PSR_v;
1335 		break;
1336 	case 8:
1337 		op = "ba";
1338 		ba = 1;
1339 		takeit = 1;
1340 		break;
1341 	case 9:
1342 		op = "bne";
1343 		takeit = !(reg.psr&PSR_z);
1344 		break;
1345 	case 10:
1346 		op = "bg";
1347 		z = reg.psr&PSR_z ? 1 : 0;
1348 		v = reg.psr&PSR_v ? 1 : 0;
1349 		n = reg.psr&PSR_n ? 1 : 0;
1350 		takeit = !(z | (n ^ v));
1351 		break;
1352 	case 11:
1353 		op = "bge";
1354 		v = reg.psr&PSR_v ? 1 : 0;
1355 		n = reg.psr&PSR_n ? 1 : 0;
1356 		takeit = !(n ^ v);
1357 		break;
1358 	case 12:
1359 		op = "bgu";
1360 		z = reg.psr&PSR_z ? 1 : 0;
1361 		c = reg.psr&PSR_c ? 1 : 0;
1362 		takeit = !(c | z);
1363 		break;
1364 	case 13:
1365 		op = "bcc";
1366 		takeit = !(reg.psr&PSR_c);
1367 		break;
1368 	case 14:
1369 		op = "bpos";
1370 		takeit = !(reg.psr&PSR_n);
1371 		break;
1372 	case 15:
1373 		op = "bvc";
1374 		takeit = !(reg.psr&PSR_v);
1375 		break;
1376 	}
1377 
1378 	npc = ir & 0x3FFFFF;
1379 	if(npc & (1<<21))
1380 		npc |= ~((1<<22)-1);
1381 	npc = (npc<<2) + reg.pc;
1382 
1383 	anul = ir&ANUL;
1384 	if(trace) {
1385 		if(anul)
1386 			itrace("%s,a\t%lux", op, npc);
1387 		else
1388 			itrace("%s\t%lux", op, npc);
1389 	}
1390 
1391 	if(takeit == 0) {
1392 		reg.pc += 4;
1393 		if(anul == 0) {
1394 			reg.ir = ifetch(reg.pc);
1395 			delay(reg.pc+4);
1396 		}
1397 		else
1398 			anulled++;
1399 		return;
1400 	}
1401 
1402 	ci->taken++;
1403 	if(ba && anul) {
1404 		anulled++;
1405 		reg.pc = npc-4;
1406 		return;
1407 	}
1408 	reg.ir = ifetch(reg.pc+4);
1409 	delay(npc);
1410 	reg.pc = npc-4;
1411 }
1412