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