6 * Alpha-specific debugger interface
9 static char *alphaexcep(Map*, Rgetter);
10 static int alphafoll(Map*, uvlong, Rgetter, uvlong*);
11 static int alphainst(Map*, uvlong, char, char*, int);
12 static int alphadas(Map*, uvlong, char*, int);
13 static int alphainstlen(Map*, uvlong);
19 {0x80, 0, 0, 0}, /* break point */
20 4, /* break point size */
22 leswab, /* short to local byte order */
23 leswal, /* long to local byte order */
24 leswav, /* vlong to local byte order */
25 risctrace, /* C traceback */
26 riscframe, /* Frame finder */
27 alphaexcep, /* print exception */
28 0, /* breakpoint fixup */
29 leieeesftos, /* single precision float printer */
30 leieeedftos, /* double precisioin float printer */
31 alphafoll, /* following addresses */
32 alphainst, /* print instruction */
33 alphadas, /* dissembler */
34 alphainstlen, /* instruction size */
37 static char *illegaltype[] = {
42 "illegal instruction",
46 alphaexcep(Map *map, Rgetter rget)
51 type = (*rget)(map, "TYPE");
52 a0 = (*rget)(map, "A0");
53 a1 = (*rget)(map, "A1");
54 /* a2 = (*rget)(map, "A2"); */
58 sprint(buf, "trap: arithmetic trap 0x%lux", a0);
60 case 2: /* bad instr or FEN */
62 return illegaltype[a0];
64 sprint(buf, "illegal instr trap, unknown type %lud", a0);
67 sprint(buf, "interrupt type %lud", a0);
69 case 4: /* memory fault */
70 sprint(buf, "fault %s addr=0x%lux", (a1&1)?"write":"read", a0);
72 case 5: /* syscall() */
74 case 6: /* alignment fault */
75 sprint(buf, "unaligned op 0x%lux addr 0x%lux", a1, a0);
77 default: /* cannot happen */
78 sprint(buf, "unknown exception type %lud", type);
84 /* alpha disassembler and related functions */
86 static char FRAMENAME[] = ".frame";
90 uchar op; /* bits 31-26 */
91 uchar ra; /* bits 25-21 */
92 uchar rb; /* bits 20-16 */
93 uchar rc; /* bits 4-0 */
94 long mem; /* bits 15-0 */
95 long branch; /* bits 20-0 */
96 uchar function; /* bits 11-5 */
97 uchar literal; /* bits 20-13 */
98 uchar islit; /* bit 12 */
99 uchar fpfn; /* bits 10-5 */
100 uchar fpmode; /* bits 15-11 */
103 int size; /* instruction size */
104 char *curr; /* fill point in buffer */
105 char *end; /* end of buffer */
106 char *err; /* error message */
112 decode(uvlong pc, Instr *i)
116 if (get4(mymap, pc, &w) < 0) {
117 werrstr("can't read instruction: %r");
122 i->op = (w >> 26) & 0x3F;
123 i->ra = (w >> 21) & 0x1F;
124 i->rb = (w >> 16) & 0x1F;
126 i->function = (w >> 5) & 0x7F;
130 i->branch = w & 0x1FFFFF;
131 if (i->branch & 0x100000)
132 i->branch -= 0x200000;
133 i->function = (w >> 5) & 0x7F;
134 i->literal = (w >> 13) & 0xFF;
135 i->islit = (w >> 12) & 0x01;
136 i->fpfn = (w >> 5) & 0x3F;
137 i->fpmode = (w >> 11) & 0x1F;
143 mkinstr(uvlong pc, Instr *i)
147 if (decode(pc, i) < 0)
151 /* we probably want to do something like this for alpha... */
153 * if it's a LUI followed by an ORI,
154 * it's an immediate load of a large constant.
155 * fix the LUI immediate in any case.
158 if (decode(pc+4, &x) < 0)
161 if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
162 i->immediate |= (x.immediate & 0xFFFF);
172 #pragma varargck argpos bprint 2
175 bprint(Instr *i, char *fmt, ...)
180 i->curr = vseprint(i->curr, i->end, fmt, arg);
184 typedef struct Opcode Opcode;
188 void (*f)(Opcode *, Instr *);
192 static void format(char *, Instr *, char *);
195 plocal(Instr *i, char *m, char r, int store)
201 if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
203 if (s.value > i->mem) {
204 if(!getauto(&s, s.value-i->mem, CAUTO, &s))
209 offset = i->mem-s.value-8;
210 if (!getauto(&s, offset, CPARAM, &s))
215 bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->ra, s.name, offset, reg);
217 bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->ra);
222 _load(Opcode *o, Instr *i, char r)
227 if (i->rb == 30 && plocal(i, m, r, 0))
229 if (i->rb == 29 && mach->sb) {
230 bprint(i, "%s\t", m);
231 i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
232 bprint(i, "(SB),%c%d", r, i->ra);
235 format(m, i, o->ken);
239 load(Opcode *o, Instr *i)
245 loadf(Opcode *o, Instr *i)
251 _store(Opcode *o, Instr *i, char r)
256 if (i->rb == 30 && plocal(i, m, r, 1))
258 if (i->rb == 29 && mach->sb) {
259 bprint(i, "%s\t%c%d,", m, r, i->ra);
260 i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
264 format(o->mnemonic, i, o->ken);
268 store(Opcode *o, Instr *i)
274 storef(Opcode *o, Instr *i)
280 misc(Opcode *o, Instr *i)
285 switch (i->mem&0xFFFF) {
296 f = "FETCH_M\t0(R%b)";
313 static char *jmpcode[4] = { "JMP", "JSR", "RET", "JSR_COROUTINE" };
316 jmp(Opcode *o, Instr *i)
322 hint = (i->mem >> 14) & 3;
325 if (hint == 2 && i->rb == 29)
328 format(m, i, "(R%b)");
331 format(m, i, "R%a,(R%b)");
335 br(Opcode *o, Instr *i)
338 format(o->mnemonic, i, "%B");
340 format(o->mnemonic, i, o->ken);
344 bsr(Opcode *o, Instr *i)
347 format(o->mnemonic, i, "%B");
349 format(o->mnemonic, i, o->ken);
353 mult(Opcode *o, Instr *i)
357 switch (i->function) {
374 format("???", i, "%w");
377 format(m, i, o->ken);
380 static char alphaload[] = "%l,R%a";
381 static char alphafload[] = "%l,F%a";
382 static char alphastore[] = "R%a,%l";
383 static char alphafstore[] = "F%a,%l";
384 static char alphabranch[] = "R%a,%B";
385 static char alphafbranch[] = "F%a,%B";
386 static char alphaint[] = "%v,R%a,R%c";
387 static char alphafp[] = "F%b,F%a,F%c";
388 static char alphafp2[] = "F%b,F%c";
389 static char alphaxxx[] = "%w";
391 static Opcode opcodes[64] = {
393 "OPC01", 0, alphaxxx,
394 "OPC02", 0, alphaxxx,
395 "OPC03", 0, alphaxxx,
396 "OPC04", 0, alphaxxx,
397 "OPC05", 0, alphaxxx,
398 "OPC06", 0, alphaxxx,
399 "OPC07", 0, alphaxxx,
400 "MOVQA", load, alphaload,
401 "MOVQAH", load, alphaload,
402 "MOVBU", load, alphaload, /* v 3 */
403 "MOVQU", load, alphaload,
404 "MOVWU", load, alphaload, /* v 3 */
405 "MOVWU", store, alphastore, /* v 3 */
406 "MOVBU", store, alphastore, /* v 3 */
407 "MOVQU", store, alphastore,
408 0, 0, 0, /* int arith */
409 0, 0, 0, /* logical */
412 "OPC14", 0, alphaxxx,
413 "vax", 0, alphafp, /* vax */
417 "PAL19 [HW_MFPR]",0, alphaxxx,
419 "PAL1B [HW_LD]",0, alphaxxx,
420 "OPC1C", 0, alphaxxx,
421 "PAL1D [HW_MTPR]",0, alphaxxx,
422 "PAL1E [HW_REI]",0, alphaxxx,
423 "PAL1F [HW_ST]",0, alphaxxx,
424 "MOVF", loadf, alphafload,
425 "MOVG", loadf, alphafload,
426 "MOVS", loadf, alphafload,
427 "MOVT", loadf, alphafload,
428 "MOVF", storef, alphafstore,
429 "MOVG", storef, alphafstore,
430 "MOVS", storef, alphafstore,
431 "MOVT", storef, alphafstore,
432 "MOVL", load, alphaload,
433 "MOVQ", load, alphaload,
434 "MOVLL", load, alphaload,
435 "MOVQL", load, alphaload,
436 "MOVL", store, alphastore,
437 "MOVQ", store, alphastore,
438 "MOVLC", store, alphastore,
439 "MOVQC", store, alphastore,
440 "JMP", br, alphabranch,
441 "FBEQ", 0, alphafbranch,
442 "FBLT", 0, alphafbranch,
443 "FBLE", 0, alphafbranch,
444 "JSR", bsr, alphabranch,
445 "FBNE", 0, alphafbranch,
446 "FBGE", 0, alphafbranch,
447 "FBGT", 0, alphafbranch,
448 "BLBC", 0, alphafbranch,
449 "BEQ", 0, alphabranch,
450 "BLT", 0, alphabranch,
451 "BLE", 0, alphabranch,
452 "BLBS", 0, alphabranch,
453 "BNE", 0, alphabranch,
454 "BGE", 0, alphabranch,
455 "BGT", 0, alphabranch,
458 static Opcode fpopcodes[64] = {
476 "CVTLQ", 0, alphafp2,
497 "MOVT", 0, "FPCR,F%a",
498 "MOVT", 0, "F%a,FPCR",
503 "FCMOVEQ", 0, alphafp,
504 "FCMOVNE", 0, alphafp,
505 "FCMOVLT", 0, alphafp,
506 "FCMOVGE", 0, alphafp,
507 "FCMOVLE", 0, alphafp,
508 "FCMOVGT", 0, alphafp,
510 "CVTQL", 0, alphafp2,
528 static Opcode ieeeopcodes[64] = {
567 "CMPTUN", 0, alphafp,
568 "CMPTEQ", 0, alphafp,
569 "CMPTLT", 0, alphafp,
570 "CMPTLE", 0, alphafp,
575 "CVTTS", 0, alphafp2,
578 "CVTTQ", 0, alphafp2,
592 "CVTQS", 0, alphafp2,
594 "CVTQT", 0, alphafp2,
598 static uchar amap[128] = {
623 static Opcode arithopcodes[64] = {
626 "ADDL/V", 0, alphaint,
628 "ADDQ/V", 0, alphaint,
630 "SUBL/V", 0, alphaint,
632 "SUBQ/V", 0, alphaint,
633 "CMPEQ", 0, alphaint,
634 "CMPLT", 0, alphaint,
635 "CMPLE", 0, alphaint,
636 "CMPULT", 0, alphaint,
637 "CMPULE", 0, alphaint,
638 "CMPBGE", 0, alphaint,
639 "S4ADDL", 0, alphaint,
640 "S4SUBL", 0, alphaint,
641 "S8ADDL", 0, alphaint,
642 "S8SUBL", 0, alphaint,
643 "S4ADDQ", 0, alphaint,
644 "S4SUBQ", 0, alphaint,
645 "S8ADDQ", 0, alphaint,
646 "S8SUBQ", 0, alphaint,
649 static uchar lmap[128] = {
666 static Opcode logicalopcodes[64] = {
671 "ANDNOT", 0, alphaint,
672 "ORNOT", 0, alphaint,
673 "XORNOT", 0, alphaint,
674 "CMOVEQ", 0, alphaint,
675 "CMOVLT", 0, alphaint,
676 "CMOVLE", 0, alphaint,
677 "CMOVNE", 0, alphaint,
678 "CMOVGE", 0, alphaint,
679 "CMOVGT", 0, alphaint,
680 "CMOVLBS", 0, alphaint,
681 "CMOVLBC", 0, alphaint,
684 static uchar smap[128] = {
713 static Opcode shiftopcodes[64] = {
718 "EXTBL", 0, alphaint,
719 "EXTWL", 0, alphaint,
720 "EXTLL", 0, alphaint,
721 "EXTQL", 0, alphaint,
722 "EXTWH", 0, alphaint,
723 "EXTLH", 0, alphaint,
724 "EXTQH", 0, alphaint,
725 "INSBL", 0, alphaint,
726 "INSWL", 0, alphaint,
727 "INSLL", 0, alphaint,
728 "INSQL", 0, alphaint,
729 "INSWH", 0, alphaint,
730 "INSLH", 0, alphaint,
731 "INSQH", 0, alphaint,
732 "MSKBL", 0, alphaint,
733 "MSKWL", 0, alphaint,
734 "MSKLL", 0, alphaint,
735 "MSKQL", 0, alphaint,
736 "MSKWH", 0, alphaint,
737 "MSKLH", 0, alphaint,
738 "MSKQH", 0, alphaint,
740 "ZAPNOT", 0, alphaint,
744 format(char *mnemonic, Instr *i, char *f)
747 format(0, i, mnemonic);
751 if (i->curr < i->end)
753 for ( ; *f && i->curr < i->end; f++) {
761 bprint(i, "%d", i->ra);
765 bprint(i, "%d", i->rb);
769 bprint(i, "%d", i->rc);
774 bprint(i, "$%ux", i->literal);
776 bprint(i, "R%d", i->rb);
780 bprint(i, "%lx(R%d)", i->mem, i->rb);
784 bprint(i, "$%lx", i->mem);
788 i->curr += symoff(i->curr, i->end-i->curr,
789 (i->branch<<2)+i->addr+4, CANY);
793 bprint(i, "[%lux]", i->w0);
801 bprint(i, "%%%c", *f);
809 printins(Map *map, uvlong pc, char *buf, int n)
818 if (mkinstr(pc, &i) < 0)
822 case 0x10: /* INTA */
824 op = amap[i.function];
827 case 0x11: /* INTL */
829 op = lmap[i.function];
832 case 0x12: /* INTS */
834 op = smap[i.function];
837 case 0x16: /* FLTI */
842 case 0x17: /* FLTL */
853 (*o[op].f)(&o[op], &i);
855 format(o[op].mnemonic, &i, o[op].ken);
860 alphainst(Map *map, uvlong pc, char modifier, char *buf, int n)
863 return printins(map, pc, buf, n);
867 alphadas(Map *map, uvlong pc, char *buf, int n)
874 if (mkinstr(pc, &i) < 0)
876 if (i.end-i.curr > 8)
877 i.curr = _hexify(buf, i.w0, 7);
878 if (i.size == 2 && i.end-i.curr > 9) {
880 i.curr = _hexify(i.curr, i.w1, 7);
887 alphainstlen(Map *map, uvlong pc)
892 if (mkinstr(pc, &i) < 0)
898 alphafoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
904 if (mkinstr(pc, &i) < 0)
908 case 0x1A: /* JMP/JSR/RET */
909 sprint(buf, "R%d", i.rb);
910 foll[0] = (*rget)(map, buf);
914 foll[0] = pc+4 + (i.branch<<2);
917 if (i.op > 0x30) { /* cond */
919 foll[1] = pc+4 + (i.branch<<2);
922 foll[0] = pc+i.size*4;