6 * Mips-specific debugger interface
9 static char *mipsexcep(Map*, Rgetter);
10 static int mipsfoll(Map*, uvlong, Rgetter, uvlong*);
11 static int mipsinst(Map*, uvlong, char, char*, int);
12 static int mipsdas(Map*, uvlong, char*, int);
13 static int mipsinstlen(Map*, uvlong);
20 {0, 0, 0, 0xD}, /* break point */
21 4, /* break point size */
23 beswab, /* short to local byte order */
24 beswal, /* long to local byte order */
25 beswav, /* vlong to local byte order */
26 risctrace, /* C traceback */
27 riscframe, /* Frame finder */
28 mipsexcep, /* print exception */
29 0, /* breakpoint fixup */
30 beieeesftos, /* single precision float printer */
31 beieeedftos, /* double precisioin float printer */
32 mipsfoll, /* following addresses */
33 mipsinst, /* print instruction */
34 mipsdas, /* dissembler */
35 mipsinstlen, /* instruction size */
40 {0xD, 0, 0, 0}, /* break point */
41 4, /* break point size */
43 leswab, /* short to local byte order */
44 leswal, /* long to local byte order */
45 leswav, /* vlong to local byte order */
46 risctrace, /* C traceback */
47 riscframe, /* Frame finder */
48 mipsexcep, /* print exception */
49 0, /* breakpoint fixup */
50 leieeesftos, /* single precision float printer */
51 leieeedftos, /* double precisioin float printer */
52 mipsfoll, /* following addresses */
53 mipsinst, /* print instruction */
54 mipsdas, /* dissembler */
55 mipsinstlen, /* instruction size */
59 * mips r4k little-endian
61 Machdata mipsmach2le =
63 {0xD, 0, 0, 0}, /* break point */
64 4, /* break point size */
66 leswab, /* short to local byte order */
67 leswal, /* long to local byte order */
68 leswav, /* vlong to local byte order */
69 risctrace, /* C traceback */
70 riscframe, /* Frame finder */
71 mipsexcep, /* print exception */
72 0, /* breakpoint fixup */
73 leieeesftos, /* single precision float printer */
74 leieeedftos, /* double precisioin float printer */
75 mipsfoll, /* following addresses */
76 mipsinst, /* print instruction */
77 mipsdas, /* dissembler */
78 mipsinstlen, /* instruction size */
84 Machdata mipsmach2be =
86 {0, 0, 0, 0xD}, /* break point */
87 4, /* break point size */
89 beswab, /* short to local byte order */
90 beswal, /* long to local byte order */
91 beswav, /* vlong to local byte order */
92 risctrace, /* C traceback */
93 riscframe, /* Frame finder */
94 mipsexcep, /* print exception */
95 0, /* breakpoint fixup */
96 beieeesftos, /* single precision float printer */
97 beieeedftos, /* double precisioin float printer */
98 mipsfoll, /* following addresses */
99 mipsinst, /* print instruction */
100 mipsdas, /* dissembler */
101 mipsinstlen, /* instruction size */
105 static char *excname[] =
107 "external interrupt",
109 "TLB miss (load or fetch)",
111 "address error (load or fetch)",
112 "address error (store)",
114 "bus error (data load or store)",
117 "reserved instruction",
118 "coprocessor unusable",
119 "arithmetic overflow",
123 /* the following is made up */
124 "floating point exception" /* FPEXC */
128 mipsexcep(Map *map, Rgetter rget)
133 c = (*rget)(map, "CAUSE");
134 if(c & 0x00002000) /* INTR3 */
135 e = 16; /* Floating point exception */
141 /* mips disassembler and related functions */
143 static char FRAMENAME[] = ".frame";
147 uchar op; /* bits 31-26 */
148 uchar rs; /* bits 25-21 */
149 uchar rt; /* bits 20-16 */
150 uchar rd; /* bits 15-11 */
151 uchar sa; /* bits 10-6 */
152 uchar function; /* bits 5-0 */
153 long immediate; /* bits 15-0 */
154 ulong cofun; /* bits 24-0 */
155 ulong target; /* bits 25-0 */
158 int size; /* instruction size */
159 char *curr; /* fill point in buffer */
160 char *end; /* end of buffer */
161 char *err; /* error message */
167 decode(uvlong pc, Instr *i)
171 if (get4(mymap, pc, &w) < 0) {
172 werrstr("can't read instruction: %r");
178 i->op = (w >> 26) & 0x3F;
179 i->rs = (w >> 21) & 0x1F;
180 i->rt = (w >> 16) & 0x1F;
181 i->rd = (w >> 11) & 0x1F;
182 i->sa = (w >> 6) & 0x1F;
183 i->function = w & 0x3F;
184 i->immediate = w & 0x0000FFFF;
185 if (i->immediate & 0x8000)
186 i->immediate |= ~0x0000FFFF;
187 i->cofun = w & 0x01FFFFFF;
188 i->target = w & 0x03FFFFFF;
194 mkinstr(uvlong pc, Instr *i)
198 if (decode(pc, i) < 0)
201 * if it's a LUI followed by an ORI,
202 * it's an immediate load of a large constant.
203 * fix the LUI immediate in any case.
206 if (decode(pc+4, &x) < 0)
209 if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
210 i->immediate |= (x.immediate & 0xFFFF);
217 * if it's a LWC1 followed by another LWC1
218 * into an adjacent register, it's a load of
219 * a floating point double.
221 else if (i->op == 0x31 && (i->rt & 0x01)) {
222 if (decode(pc+4, &x) < 0)
224 if (x.op == 0x31 && x.rt == (i->rt - 1) && x.rs == i->rs) {
232 * similarly for double stores
234 else if (i->op == 0x39 && (i->rt & 0x01)) {
235 if (decode(pc+4, &x) < 0)
237 if (x.op == 0x39 && x.rt == (i->rt - 1) && x.rs == i->rs) {
246 #pragma varargck argpos bprint 2
249 bprint(Instr *i, char *fmt, ...)
254 i->curr = vseprint(i->curr, i->end, fmt, arg);
258 typedef struct Opcode Opcode;
262 void (*f)(Opcode *, Instr *);
266 static void format(char *, Instr *, char *);
269 branch(Opcode *o, Instr *i)
271 if (i->rs == 0 && i->rt == 0)
272 format("JMP", i, "%b");
274 format(o->mnemonic, i, "R%t,%b");
276 format(o->mnemonic, i, "R%s,%b");
278 format(o->mnemonic, i, "R%s,R%t,%b");
282 addi(Opcode *o, Instr *i)
285 format(o->mnemonic, i, "%i,R%t");
287 format("MOVW", i, "%i,R%t");
288 else if (i->rs == 30) {
289 bprint(i, "MOVW\t$");
290 i->curr += symoff(i->curr, i->end-i->curr,
291 i->immediate+mach->sb, CANY);
292 bprint(i, "(SB),R%d", i->rt);
295 format(o->mnemonic, i, o->ken);
299 andi(Opcode *o, Instr *i)
302 format(o->mnemonic, i, "%i,R%t");
304 format(o->mnemonic, i, o->ken);
308 plocal(Instr *i, char *m, char r, int store)
314 if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
316 if (s.value > i->immediate) {
317 if(!getauto(&s, s.value-i->immediate, CAUTO, &s))
320 offset = i->immediate;
322 offset = i->immediate-s.value;
323 if (!getauto(&s, offset-4, CPARAM, &s))
328 bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->rt, s.name, offset, reg);
330 bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->rt);
335 lw(Opcode *o, Instr *i, char r)
347 if (i->rs == 29 && plocal(i, m, r, 0))
350 if (i->rs == 30 && mach->sb) {
351 bprint(i, "%s\t", m);
352 i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY);
353 bprint(i, "(SB),%c%d", r, i->rt);
357 format(m, i, "%l,F%t");
359 format(m, i, o->ken);
363 load(Opcode *o, Instr *i)
369 lwc1(Opcode *o, Instr *i)
375 sw(Opcode *o, Instr *i, char r)
387 if (i->rs == 29 && plocal(i, m, r, 1))
390 if (i->rs == 30 && mach->sb) {
391 bprint(i, "%s\t%c%d,", m, r, i->rt);
392 i->curr += symoff(i->curr, i->end-i->curr, i->immediate+mach->sb, CANY);
397 format(m, i, "F%t,%l");
399 format(m, i, o->ken);
403 store(Opcode *o, Instr *i)
409 swc1(Opcode *o, Instr *i)
415 sll(Opcode *o, Instr *i)
418 bprint(i, "NOOP"); /* unofficial nop */
419 else if (i->w0 == 0xc0) /* 0xc0: SLL $3,R0 */
421 else if (i->rd == i->rt)
422 format(o->mnemonic, i, "$%a,R%d");
424 format(o->mnemonic, i, o->ken);
428 sl32(Opcode *o, Instr *i)
432 format(o->mnemonic, i, "$%a,R%d");
434 format(o->mnemonic, i, o->ken);
438 sllv(Opcode *o, Instr *i)
441 format(o->mnemonic, i, "R%s,R%d");
443 format(o->mnemonic, i, o->ken);
447 jal(Opcode *o, Instr *i)
450 format("JAL", i, "(R%s)");
452 format(o->mnemonic, i, o->ken);
456 add(Opcode *o, Instr *i)
459 format(o->mnemonic, i, "R%t,R%d");
460 else if (i->rd == i->rt)
461 format(o->mnemonic, i, "R%s,R%d");
463 format(o->mnemonic, i, o->ken);
467 sub(Opcode *o, Instr *i)
470 format(o->mnemonic, i, "R%t,R%d");
472 format(o->mnemonic, i, o->ken);
476 or(Opcode *o, Instr *i)
478 if (i->rs == 0 && i->rt == 0)
479 format("MOVW", i, "$0,R%d");
481 format("MOVW", i, "R%t,R%d");
483 format("MOVW", i, "R%s,R%d");
489 nor(Opcode *o, Instr *i)
491 if (i->rs == 0 && i->rt == 0 && i->rd == 0)
497 static char mipscoload[] = "r%t,%l";
498 static char mipsload[] = "%l,R%t";
499 static char mipsstore[] = "R%t,%l";
500 static char mipsalui[] = "%i,R%s,R%t";
501 static char mipsalu3op[] = "R%t,R%s,R%d";
502 static char mipsrtrs[] = "R%t,R%s";
503 static char mipscorsrt[] = "r%s,r%t";
504 static char mipscorsi[] = "r%s,%i";
505 static char mipscoxxx[] = "%w";
506 static char mipscofp3[] = "f%a,f%d,f%t"; /* fd,fs,ft */
507 static char mipsfp3[] = "F%t,F%d,F%a";
508 static char mipscofp2[] = "f%a,f%d"; /* fd,fs */
509 static char mipsfp2[] = "F%d,F%a";
510 static char mipscofpc[] = "f%d,f%t"; /* fs,ft */
511 static char mipsfpc[] = "F%t,F%d";
513 static Opcode opcodes[64] = {
522 "ADD", addi, mipsalui,
523 "ADDU", addi, mipsalui,
526 "AND", andi, mipsalui,
527 "OR", andi, mipsalui,
528 "XOR", andi, mipsalui,
529 "MOVW", 0, "$%u,R%t",
538 "instr18", 0, mipscoxxx,
539 "instr19", 0, mipscoxxx,
540 "MOVVL", load, mipsload,
541 "MOVVR", load, mipsload,
542 "instr1C", 0, mipscoxxx,
543 "instr1D", 0, mipscoxxx,
544 "instr1E", 0, mipscoxxx,
545 "instr1F", 0, mipscoxxx,
546 "MOVB", load, mipsload,
547 "MOVH", load, mipsload,
548 "lwl", 0, mipscoload,
549 "MOVW", load, mipsload,
550 "MOVBU", load, mipsload,
551 "MOVHU", load, mipsload,
552 "lwr", 0, mipscoload,
553 "instr27", 0, mipscoxxx,
554 "MOVB", store, mipsstore,
555 "MOVH", store, mipsstore,
556 "swl", 0, mipscoload,
557 "MOVW", store, mipsstore,
558 "MOVVL", store, mipsstore,
559 "MOVVR", store, mipsstore,
560 "swr", 0, mipscoload,
563 "MOVW", lwc1, mipscoload,
564 "lwc2", 0, mipscoload,
565 "lwc3", 0, mipscoload,
566 "instr34", 0, mipscoxxx,
567 "ldc1", 0, mipscoload,
568 "ldc2", 0, mipscoload,
569 "MOVV", load, mipsload,
571 "swc1", swc1, mipscoload,
572 "swc2", 0, mipscoload,
573 "swc3", 0, mipscoload,
574 "instr3C", 0, mipscoxxx,
575 "sdc1", 0, mipscoload,
576 "sdc2", 0, mipscoload,
577 "MOVV", store, mipsstore,
580 static Opcode sopcodes[64] = {
581 "SLL", sll, "$%a,R%t,R%d",
582 "special01", 0, mipscoxxx,
583 "SRL", sll, "$%a,R%t,R%d",
584 "SRA", sll, "$%a,R%t,R%d",
585 "SLL", sllv, "R%s,R%t,R%d",
586 "special05", 0, mipscoxxx,
587 "SRL", sllv, "R%s,R%t,R%d",
588 "SRA", sllv, "R%s,R%t,R%d",
590 "jal", jal, "r%d,r%s",
591 "special0A", 0, mipscoxxx,
592 "special0B", 0, mipscoxxx,
595 "special0E", 0, mipscoxxx,
601 "SLLV", sllv, "R%s,R%t,R%d",
602 "special15", 0, mipscoxxx,
603 "SRLV", sllv, "R%s,R%t,R%d",
604 "SRAV", sllv, "R%s,R%t,R%d",
609 "special1C", 0, mipscoxxx,
610 "special1D", 0, mipscoxxx,
611 "DDIV", 0, "R%s,R%t",
612 "special1F", 0, mipscoxxx,
613 "ADD", add, mipsalu3op,
614 "ADDU", add, mipsalu3op,
615 "SUB", sub, mipsalu3op,
616 "SUBU", sub, mipsalu3op,
617 "AND", add, mipsalu3op,
618 "OR", or, mipsalu3op,
619 "XOR", add, mipsalu3op,
620 "NOR", nor, mipsalu3op,
621 "special28", 0, mipscoxxx,
622 "special29", 0, mipscoxxx,
623 "SGT", 0, mipsalu3op,
624 "SGTU", 0, mipsalu3op,
625 "special2C", 0, mipscoxxx,
626 "special2D", 0, mipscoxxx,
627 "special2E", 0, mipscoxxx,
628 "DSUBU", 0, "R%s,R%t,R%d",
629 "tge", 0, mipscorsrt,
630 "tgeu", 0, mipscorsrt,
631 "tlt", 0, mipscorsrt,
632 "tltu", 0, mipscorsrt,
633 "teq", 0, mipscorsrt,
634 "special35", 0, mipscoxxx,
635 "tne", 0, mipscorsrt,
636 "special37", 0, mipscoxxx,
637 "SLLV", sll, "$%a,R%t,R%d",
638 "special39", 0, mipscoxxx,
639 "SRLV", sll, "$%a,R%t,R%d",
640 "SRAV", sll, "$%a,R%t,R%d",
641 "SLLV", sl32, "$%a,R%t,R%d",
642 "special3D", 0, mipscoxxx,
643 "SRLV", sl32, "$%a,R%t,R%d",
644 "SRAV", sl32, "$%a,R%t,R%d",
647 static Opcode ropcodes[32] = {
652 "regimm04", 0, mipscoxxx,
653 "regimm05", 0, mipscoxxx,
654 "regimm06", 0, mipscoxxx,
655 "regimm07", 0, mipscoxxx,
656 "tgei", 0, mipscorsi,
657 "tgeiu", 0, mipscorsi,
658 "tlti", 0, mipscorsi,
659 "tltiu", 0, mipscorsi,
660 "teqi", 0, mipscorsi,
661 "regimm0D", 0, mipscoxxx,
662 "tnei", 0, mipscorsi,
663 "regimm0F", 0, mipscoxxx,
666 "BLTZALL", branch, 0,
667 "BGEZALL", branch, 0,
668 "regimm14", 0, mipscoxxx,
669 "regimm15", 0, mipscoxxx,
670 "regimm16", 0, mipscoxxx,
671 "regimm17", 0, mipscoxxx,
672 "regimm18", 0, mipscoxxx,
673 "regimm19", 0, mipscoxxx,
674 "regimm1A", 0, mipscoxxx,
675 "regimm1B", 0, mipscoxxx,
676 "regimm1C", 0, mipscoxxx,
677 "regimm1D", 0, mipscoxxx,
678 "regimm1E", 0, mipscoxxx,
679 "regimm1F", 0, mipscoxxx,
682 static Opcode fopcodes[64] = {
687 "sqrt.%f", 0, mipscofp2,
691 "finstr08", 0, mipscoxxx,
692 "finstr09", 0, mipscoxxx,
693 "finstr0A", 0, mipscoxxx,
694 "finstr0B", 0, mipscoxxx,
695 "round.w.%f", 0, mipscofp2,
696 "trunc.w%f", 0, mipscofp2,
697 "ceil.w%f", 0, mipscofp2,
698 "floor.w%f", 0, mipscofp2,
699 "finstr10", 0, mipscoxxx,
700 "finstr11", 0, mipscoxxx,
701 "finstr12", 0, mipscoxxx,
702 "finstr13", 0, mipscoxxx,
703 "finstr14", 0, mipscoxxx,
704 "finstr15", 0, mipscoxxx,
705 "finstr16", 0, mipscoxxx,
706 "finstr17", 0, mipscoxxx,
707 "finstr18", 0, mipscoxxx,
708 "finstr19", 0, mipscoxxx,
709 "finstr1A", 0, mipscoxxx,
710 "finstr1B", 0, mipscoxxx,
711 "finstr1C", 0, mipscoxxx,
712 "finstr1D", 0, mipscoxxx,
713 "finstr1E", 0, mipscoxxx,
714 "finstr1F", 0, mipscoxxx,
715 "cvt.s.%f", 0, mipscofp2,
716 "cvt.d.%f", 0, mipscofp2,
717 "cvt.e.%f", 0, mipscofp2,
718 "cvt.q.%f", 0, mipscofp2,
719 "cvt.w.%f", 0, mipscofp2,
720 "finstr25", 0, mipscoxxx,
721 "finstr26", 0, mipscoxxx,
722 "finstr27", 0, mipscoxxx,
723 "finstr28", 0, mipscoxxx,
724 "finstr29", 0, mipscoxxx,
725 "finstr2A", 0, mipscoxxx,
726 "finstr2B", 0, mipscoxxx,
727 "finstr2C", 0, mipscoxxx,
728 "finstr2D", 0, mipscoxxx,
729 "finstr2E", 0, mipscoxxx,
730 "finstr2F", 0, mipscoxxx,
731 "c.f.%f", 0, mipscofpc,
732 "c.un.%f", 0, mipscofpc,
733 "CMPEQ%f", 0, mipsfpc,
734 "c.ueq.%f", 0, mipscofpc,
735 "c.olt.%f", 0, mipscofpc,
736 "c.ult.%f", 0, mipscofpc,
737 "c.ole.%f", 0, mipscofpc,
738 "c.ule.%f", 0, mipscofpc,
739 "c.sf.%f", 0, mipscofpc,
740 "c.ngle.%f", 0, mipscofpc,
741 "c.seq.%f", 0, mipscofpc,
742 "c.ngl.%f", 0, mipscofpc,
743 "CMPGT%f", 0, mipsfpc,
744 "c.nge.%f", 0, mipscofpc,
745 "CMPGE%f", 0, mipsfpc,
746 "c.ngt.%f", 0, mipscofpc,
749 static char *cop0regs[32] = {
750 "INDEX", "RANDOM", "TLBPHYS", "EntryLo0",
751 "CONTEXT", "PageMask", "Wired", "Error",
752 "BADVADDR", "Count", "TLBVIRT", "Compare",
753 "STATUS", "CAUSE", "EPC", "PRID",
754 "Config", "LLadr", "WatchLo", "WatchHi",
755 "20", "21", "22", "23",
756 "24", "25", "26", "CacheErr",
757 "TagLo", "TagHi", "ErrorEPC", "31"
760 static char fsub[16] = {
761 'F', 'D', 'e', 'q', 'W', '?', '?', '?',
762 '?', '?', '?', '?', '?', '?', '?', '?'
765 static char *cacheps[] = {
769 static char *cacheop[] = {
770 "IWBI", "ILT", "IST", "CDE", "HI", "HWBI", "HWB", "HSV"
774 format(char *mnemonic, Instr *i, char *f)
777 format(0, i, mnemonic);
781 if (i->curr < i->end)
783 for ( ; *f && i->curr < i->end; f++) {
791 bprint(i, "%d", i->rs);
795 bprint(i, "%d", i->rt);
799 bprint(i, "%d", i->rd);
803 bprint(i, "%d", i->sa);
807 bprint(i, "%lx(R%d)",i->immediate, i->rs);
811 bprint(i, "$%lx", i->immediate);
815 i->curr += symoff(i->curr, i->end-i->curr, i->immediate, CANY);
820 i->curr += symoff(i->curr, i->end-i->curr,
821 (i->target<<2)|(i->addr & 0xF0000000), CANY);
826 i->curr += symoff(i->curr, i->end-i->curr,
827 (i->immediate<<2)+i->addr+4, CANY);
831 bprint(i, "$%lx", i->cofun);
835 bprint(i, "[%lux]", i->w0);
839 bprint(i, "M(%s)", cop0regs[i->rd]);
843 *i->curr++ = fsub[i->rs & 0x0F];
847 bprint(i, "%s%s", cacheps[i->rt & 3], cacheop[(i->rt>>2) & 7]);
855 bprint(i, "%%%c", *f);
863 copz(int cop, Instr *i)
865 char *f, *m, buf[16];
872 sprint(buf, "mfc%d", cop);
876 sprint(buf, "cfc%d", cop);
880 sprint(buf, "mtc%d", cop);
884 sprint(buf, "ctc%d", cop);
892 sprint(buf, "bc%df", cop);
896 sprint(buf, "bc%dt", cop);
900 sprint(buf, "bc%dfl", cop);
904 sprint(buf, "bc%dtl", cop);
908 sprint(buf, "cop%d", cop);
915 sprint(buf, "cop%d", cop);
935 format("MOVW", i, "%m,R%t");
940 format("MOVW", i, "R%t,%m");
944 else if (i->rs >= 0x10) {
991 format(m, i, "F%d,R%t");
995 format(m, i, "FCR%d,R%t");
999 format(m, i, "R%t,F%d");
1003 format(m, i, "R%t,FCR%d");
1010 format("BFPF", i, "%b");
1014 format("BFPT", i, "%b");
1023 printins(Map *map, uvlong pc, char *buf, int n)
1032 if (mkinstr(pc, &i) < 0)
1036 case 0x00: /* SPECIAL */
1041 case 0x01: /* REGIMM */
1046 case 0x10: /* COP0 */
1050 case 0x11: /* COP1 */
1059 case 0x12: /* COP2 */
1060 case 0x13: /* COP3 */
1061 copz(i.op-0x10, &i);
1070 (*o[op].f)(&o[op], &i);
1072 format(o[op].mnemonic, &i, o[op].ken);
1076 extern int _mipscoinst(Map *, uvlong, char*, int);
1078 /* modifier 'I' toggles the default disassembler type */
1080 mipsinst(Map *map, uvlong pc, char modifier, char *buf, int n)
1082 if ((asstype == AMIPSCO && modifier == 'i')
1083 || (asstype == AMIPS && modifier == 'I'))
1084 return _mipscoinst(map, pc, buf, n);
1086 return printins(map, pc, buf, n);
1090 mipsdas(Map *map, uvlong pc, char *buf, int n)
1097 if (mkinstr(pc, &i) < 0)
1099 if (i.end-i.curr > 8)
1100 i.curr = _hexify(buf, i.w0, 7);
1101 if (i.size == 2 && i.end-i.curr > 9) {
1103 i.curr = _hexify(i.curr, i.w1, 7);
1110 mipsinstlen(Map *map, uvlong pc)
1115 if (mkinstr(pc, &i) < 0)
1121 mipsfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
1128 if (mkinstr(pc, &i) < 0)
1131 if((w&0xF3600000) == 0x41000000){ /* branch on coprocessor */
1134 l = ((w&0xFFFF)<<2);
1141 l = (w&0xFC000000)>>26;
1143 case 0: /* SPECIAL */
1144 if((w&0x3E) == 0x08){ /* JR, JALR */
1145 sprint(buf, "R%ld", (w>>21)&0x1F);
1146 foll[0] = (*rget)(map, buf);
1149 foll[0] = pc+i.size*4;
1151 case 0x30: /* Load-Linked followed by NOP, STC */
1160 case 22: /* BLEZL */
1162 case 23: /* BGTZL */
1166 foll[0] = (pc&0xF0000000) | ((w&0x03FFFFFF)<<2);
1170 foll[0] = pc+i.size*4;