]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ki/run.c
libtags, zuke: add *.mod support (thanks kemal)
[plan9front.git] / sys / src / cmd / ki / run.c
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }