alphadb.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include <u.h>
  10. #include <libc.h>
  11. #include <bio.h>
  12. #include <mach.h>
  13. /*
  14. * Alpha-specific debugger interface
  15. */
  16. static char *alphaexcep(Map*, Rgetter);
  17. static int alphafoll(Map*, uint64_t, Rgetter, uint64_t*);
  18. static int alphainst(Map*, uint64_t, char, char*, int);
  19. static int alphadas(Map*, uint64_t, char*, int);
  20. static int alphainstlen(Map*, uint64_t);
  21. /*
  22. * Debugger interface
  23. */
  24. Machdata alphamach =
  25. {
  26. {0x80, 0, 0, 0}, /* break point */
  27. 4, /* break point size */
  28. leswab, /* short to local byte order */
  29. leswal, /* long to local byte order */
  30. leswav, /* vlong to local byte order */
  31. risctrace, /* C traceback */
  32. riscframe, /* Frame finder */
  33. alphaexcep, /* print exception */
  34. 0, /* breakpoint fixup */
  35. leieeesftos, /* single precision float printer */
  36. leieeedftos, /* double precisioin float printer */
  37. alphafoll, /* following addresses */
  38. alphainst, /* print instruction */
  39. alphadas, /* dissembler */
  40. alphainstlen, /* instruction size */
  41. };
  42. static char *illegaltype[] = {
  43. "breakpoint",
  44. "bugchk",
  45. "gentrap",
  46. "fen",
  47. "illegal instruction",
  48. };
  49. static char *
  50. alphaexcep(Map *map, Rgetter rget)
  51. {
  52. uint32_t type, a0, a1;
  53. static char buf[256];
  54. type = (*rget)(map, "TYPE");
  55. a0 = (*rget)(map, "A0");
  56. a1 = (*rget)(map, "A1");
  57. /* a2 = (*rget)(map, "A2"); */
  58. switch (type) {
  59. case 1: /* arith */
  60. sprint(buf, "trap: arithmetic trap 0x%lux", a0);
  61. break;
  62. case 2: /* bad instr or FEN */
  63. if (a0 <= 4)
  64. return illegaltype[a0];
  65. else
  66. sprint(buf, "illegal instr trap, unknown type %lud", a0);
  67. break;
  68. case 3: /* intr */
  69. sprint(buf, "interrupt type %lud", a0);
  70. break;
  71. case 4: /* memory fault */
  72. sprint(buf, "fault %s addr=0x%lux", (a1&1)?"write":"read", a0);
  73. break;
  74. case 5: /* syscall() */
  75. return "system call";
  76. case 6: /* alignment fault */
  77. sprint(buf, "unaligned op 0x%lux addr 0x%lux", a1, a0);
  78. break;
  79. default: /* cannot happen */
  80. sprint(buf, "unknown exception type %lud", type);
  81. break;
  82. }
  83. return buf;
  84. }
  85. /* alpha disassembler and related functions */
  86. static char FRAMENAME[] = ".frame";
  87. typedef struct {
  88. uint64_t addr;
  89. uint8_t op; /* bits 31-26 */
  90. uint8_t ra; /* bits 25-21 */
  91. uint8_t rb; /* bits 20-16 */
  92. uint8_t rc; /* bits 4-0 */
  93. int32_t mem; /* bits 15-0 */
  94. int32_t branch; /* bits 20-0 */
  95. uint8_t function; /* bits 11-5 */
  96. uint8_t literal; /* bits 20-13 */
  97. uint8_t islit; /* bit 12 */
  98. uint8_t fpfn; /* bits 10-5 */
  99. uint8_t fpmode; /* bits 15-11 */
  100. int32_t w0;
  101. int32_t w1;
  102. int size; /* instruction size */
  103. char *curr; /* fill point in buffer */
  104. char *end; /* end of buffer */
  105. char *err; /* error message */
  106. } Instr;
  107. static Map *mymap;
  108. static int
  109. decode(uint64_t pc, Instr *i)
  110. {
  111. uint32_t w;
  112. if (get4(mymap, pc, &w) < 0) {
  113. werrstr("can't read instruction: %r");
  114. return -1;
  115. }
  116. i->addr = pc;
  117. i->size = 1;
  118. i->op = (w >> 26) & 0x3F;
  119. i->ra = (w >> 21) & 0x1F;
  120. i->rb = (w >> 16) & 0x1F;
  121. i->rc = w & 0x1F;
  122. i->function = (w >> 5) & 0x7F;
  123. i->mem = w & 0xFFFF;
  124. if (i->mem & 0x8000)
  125. i->mem -= 0x10000;
  126. i->branch = w & 0x1FFFFF;
  127. if (i->branch & 0x100000)
  128. i->branch -= 0x200000;
  129. i->function = (w >> 5) & 0x7F;
  130. i->literal = (w >> 13) & 0xFF;
  131. i->islit = (w >> 12) & 0x01;
  132. i->fpfn = (w >> 5) & 0x3F;
  133. i->fpmode = (w >> 11) & 0x1F;
  134. i->w0 = w;
  135. return 1;
  136. }
  137. static int
  138. mkinstr(uint64_t pc, Instr *i)
  139. {
  140. /* Instr x; */
  141. if (decode(pc, i) < 0)
  142. return -1;
  143. #ifdef frommips
  144. /* we probably want to do something like this for alpha... */
  145. /*
  146. * if it's a LUI followed by an ORI,
  147. * it's an immediate load of a large constant.
  148. * fix the LUI immediate in any case.
  149. */
  150. if (i->op == 0x0F) {
  151. if (decode(pc+4, &x) < 0)
  152. return 0;
  153. i->immediate <<= 16;
  154. if (x.op == 0x0D && x.rs == x.rt && x.rt == i->rt) {
  155. i->immediate |= (x.immediate & 0xFFFF);
  156. i->w1 = x.w0;
  157. i->size++;
  158. return 1;
  159. }
  160. }
  161. #endif
  162. return 1;
  163. }
  164. #pragma varargck argpos bprint 2
  165. static void
  166. bprint(Instr *i, char *fmt, ...)
  167. {
  168. va_list arg;
  169. va_start(arg, fmt);
  170. i->curr = vseprint(i->curr, i->end, fmt, arg);
  171. va_end(arg);
  172. }
  173. typedef struct Opcode Opcode;
  174. struct Opcode {
  175. char *mnemonic;
  176. void (*f)(Opcode *, Instr *);
  177. char *ken;
  178. };
  179. static void format(char *, Instr *, char *);
  180. static int
  181. plocal(Instr *i, char *m, char r, int store)
  182. {
  183. int offset;
  184. char *reg;
  185. Symbol s;
  186. if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
  187. return 0;
  188. if (s.value > i->mem) {
  189. if(!getauto(&s, s.value-i->mem, CAUTO, &s))
  190. return 0;
  191. reg = "(SP)";
  192. offset = i->mem;
  193. } else {
  194. offset = i->mem-s.value-8;
  195. if (!getauto(&s, offset, CPARAM, &s))
  196. return 0;
  197. reg = "(FP)";
  198. }
  199. if (store)
  200. bprint(i, "%s\t%c%d,%s+%d%s", m, r, i->ra, s.name, offset, reg);
  201. else
  202. bprint(i, "%s\t%s+%d%s,%c%d", m, s.name, offset, reg, r, i->ra);
  203. return 1;
  204. }
  205. static void
  206. _load(Opcode *o, Instr *i, char r)
  207. {
  208. char *m;
  209. m = o->mnemonic;
  210. if (i->rb == 30 && plocal(i, m, r, 0))
  211. return;
  212. if (i->rb == 29 && mach->sb) {
  213. bprint(i, "%s\t", m);
  214. i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
  215. bprint(i, "(SB),%c%d", r, i->ra);
  216. return;
  217. }
  218. format(m, i, o->ken);
  219. }
  220. static void
  221. load(Opcode *o, Instr *i)
  222. {
  223. _load(o, i, 'R');
  224. }
  225. static void
  226. loadf(Opcode *o, Instr *i)
  227. {
  228. _load(o, i, 'F');
  229. }
  230. static void
  231. _store(Opcode *o, Instr *i, char r)
  232. {
  233. char *m;
  234. m = o->mnemonic;
  235. if (i->rb == 30 && plocal(i, m, r, 1))
  236. return;
  237. if (i->rb == 29 && mach->sb) {
  238. bprint(i, "%s\t%c%d,", m, r, i->ra);
  239. i->curr += symoff(i->curr, i->end-i->curr, i->mem+mach->sb, CANY);
  240. bprint(i, "(SB)");
  241. return;
  242. }
  243. format(o->mnemonic, i, o->ken);
  244. }
  245. static void
  246. store(Opcode *o, Instr *i)
  247. {
  248. _store(o, i, 'R');
  249. }
  250. static void
  251. storef(Opcode *o, Instr *i)
  252. {
  253. _store(o, i, 'F');
  254. }
  255. static void
  256. misc(Opcode *o, Instr *i)
  257. {
  258. char *f;
  259. USED(o);
  260. switch (i->mem&0xFFFF) {
  261. case 0x0000:
  262. f = "TRAPB";
  263. break;
  264. case 0x4000:
  265. f = "MB";
  266. break;
  267. case 0x8000:
  268. f = "FETCH\t0(R%b)";
  269. break;
  270. case 0xA000:
  271. f = "FETCH_M\t0(R%b)";
  272. break;
  273. case 0xC000:
  274. f = "RPCC\tR%a";
  275. break;
  276. case 0xE000:
  277. f = "RC\tR%a";
  278. break;
  279. case 0xF000:
  280. f = "RS\tR%a";
  281. break;
  282. default:
  283. f = "%w";
  284. }
  285. format(0, i, f);
  286. }
  287. static char *jmpcode[4] = { "JMP", "JSR", "RET", "JSR_COROUTINE" };
  288. static void
  289. jmp(Opcode *o, Instr *i)
  290. {
  291. int hint;
  292. char *m;
  293. USED(o);
  294. hint = (i->mem >> 14) & 3;
  295. m = jmpcode[hint];
  296. if (i->ra == 31) {
  297. if (hint == 2 && i->rb == 29)
  298. bprint(i, m);
  299. else
  300. format(m, i, "(R%b)");
  301. }
  302. else
  303. format(m, i, "R%a,(R%b)");
  304. }
  305. static void
  306. br(Opcode *o, Instr *i)
  307. {
  308. if (i->ra == 31)
  309. format(o->mnemonic, i, "%B");
  310. else
  311. format(o->mnemonic, i, o->ken);
  312. }
  313. static void
  314. bsr(Opcode *o, Instr *i)
  315. {
  316. if (i->ra == 26)
  317. format(o->mnemonic, i, "%B");
  318. else
  319. format(o->mnemonic, i, o->ken);
  320. }
  321. static void
  322. mult(Opcode *o, Instr *i)
  323. {
  324. char *m;
  325. switch (i->function) {
  326. case 0x00:
  327. m = "MULL";
  328. break;
  329. case 0x20:
  330. m = "MULQ";
  331. break;
  332. case 0x40:
  333. m = "MULL/V";
  334. break;
  335. case 0x60:
  336. m = "MULQ/V";
  337. break;
  338. case 0x30:
  339. m = "UMULH";
  340. break;
  341. default:
  342. format("???", i, "%w");
  343. return;
  344. }
  345. format(m, i, o->ken);
  346. }
  347. static char alphaload[] = "%l,R%a";
  348. static char alphafload[] = "%l,F%a";
  349. static char alphastore[] = "R%a,%l";
  350. static char alphafstore[] = "F%a,%l";
  351. static char alphabranch[] = "R%a,%B";
  352. static char alphafbranch[] = "F%a,%B";
  353. static char alphaint[] = "%v,R%a,R%c";
  354. static char alphafp[] = "F%b,F%a,F%c";
  355. static char alphafp2[] = "F%b,F%c";
  356. static char alphaxxx[] = "%w";
  357. static Opcode opcodes[64] = {
  358. "PAL", 0, alphaxxx,
  359. "OPC01", 0, alphaxxx,
  360. "OPC02", 0, alphaxxx,
  361. "OPC03", 0, alphaxxx,
  362. "OPC04", 0, alphaxxx,
  363. "OPC05", 0, alphaxxx,
  364. "OPC06", 0, alphaxxx,
  365. "OPC07", 0, alphaxxx,
  366. "MOVQA", load, alphaload,
  367. "MOVQAH", load, alphaload,
  368. "MOVBU", load, alphaload, /* v 3 */
  369. "MOVQU", load, alphaload,
  370. "MOVWU", load, alphaload, /* v 3 */
  371. "MOVWU", store, alphastore, /* v 3 */
  372. "MOVBU", store, alphastore, /* v 3 */
  373. "MOVQU", store, alphastore,
  374. 0, 0, 0, /* int arith */
  375. 0, 0, 0, /* logical */
  376. 0, 0, 0, /* shift */
  377. 0, mult, alphaint,
  378. "OPC14", 0, alphaxxx,
  379. "vax", 0, alphafp, /* vax */
  380. 0, 0, 0, /* ieee */
  381. 0, 0, 0, /* fp */
  382. 0, misc, alphaxxx,
  383. "PAL19 [HW_MFPR]",0, alphaxxx,
  384. "JSR", jmp, 0,
  385. "PAL1B [HW_LD]",0, alphaxxx,
  386. "OPC1C", 0, alphaxxx,
  387. "PAL1D [HW_MTPR]",0, alphaxxx,
  388. "PAL1E [HW_REI]",0, alphaxxx,
  389. "PAL1F [HW_ST]",0, alphaxxx,
  390. "MOVF", loadf, alphafload,
  391. "MOVG", loadf, alphafload,
  392. "MOVS", loadf, alphafload,
  393. "MOVT", loadf, alphafload,
  394. "MOVF", storef, alphafstore,
  395. "MOVG", storef, alphafstore,
  396. "MOVS", storef, alphafstore,
  397. "MOVT", storef, alphafstore,
  398. "MOVL", load, alphaload,
  399. "MOVQ", load, alphaload,
  400. "MOVLL", load, alphaload,
  401. "MOVQL", load, alphaload,
  402. "MOVL", store, alphastore,
  403. "MOVQ", store, alphastore,
  404. "MOVLC", store, alphastore,
  405. "MOVQC", store, alphastore,
  406. "JMP", br, alphabranch,
  407. "FBEQ", 0, alphafbranch,
  408. "FBLT", 0, alphafbranch,
  409. "FBLE", 0, alphafbranch,
  410. "JSR", bsr, alphabranch,
  411. "FBNE", 0, alphafbranch,
  412. "FBGE", 0, alphafbranch,
  413. "FBGT", 0, alphafbranch,
  414. "BLBC", 0, alphafbranch,
  415. "BEQ", 0, alphabranch,
  416. "BLT", 0, alphabranch,
  417. "BLE", 0, alphabranch,
  418. "BLBS", 0, alphabranch,
  419. "BNE", 0, alphabranch,
  420. "BGE", 0, alphabranch,
  421. "BGT", 0, alphabranch,
  422. };
  423. static Opcode fpopcodes[64] = {
  424. "???", 0, alphaxxx,
  425. "???", 0, alphaxxx,
  426. "???", 0, alphaxxx,
  427. "???", 0, alphaxxx,
  428. "???", 0, alphaxxx,
  429. "???", 0, alphaxxx,
  430. "???", 0, alphaxxx,
  431. "???", 0, alphaxxx,
  432. "???", 0, alphaxxx,
  433. "???", 0, alphaxxx,
  434. "???", 0, alphaxxx,
  435. "???", 0, alphaxxx,
  436. "???", 0, alphaxxx,
  437. "???", 0, alphaxxx,
  438. "???", 0, alphaxxx,
  439. "???", 0, alphaxxx,
  440. "CVTLQ", 0, alphafp2,
  441. "???", 0, alphaxxx,
  442. "???", 0, alphaxxx,
  443. "???", 0, alphaxxx,
  444. "???", 0, alphaxxx,
  445. "???", 0, alphaxxx,
  446. "???", 0, alphaxxx,
  447. "???", 0, alphaxxx,
  448. "???", 0, alphaxxx,
  449. "???", 0, alphaxxx,
  450. "???", 0, alphaxxx,
  451. "???", 0, alphaxxx,
  452. "???", 0, alphaxxx,
  453. "???", 0, alphaxxx,
  454. "???", 0, alphaxxx,
  455. "???", 0, alphaxxx,
  456. "CPYS", 0, alphafp,
  457. "CPYSN", 0, alphafp,
  458. "CPYSE", 0, alphafp,
  459. "???", 0, alphaxxx,
  460. "MOVT", 0, "FPCR,F%a",
  461. "MOVT", 0, "F%a,FPCR",
  462. "???", 0, alphaxxx,
  463. "???", 0, alphaxxx,
  464. "???", 0, alphaxxx,
  465. "???", 0, alphaxxx,
  466. "FCMOVEQ", 0, alphafp,
  467. "FCMOVNE", 0, alphafp,
  468. "FCMOVLT", 0, alphafp,
  469. "FCMOVGE", 0, alphafp,
  470. "FCMOVLE", 0, alphafp,
  471. "FCMOVGT", 0, alphafp,
  472. "CVTQL", 0, alphafp2,
  473. "???", 0, alphaxxx,
  474. "???", 0, alphaxxx,
  475. "???", 0, alphaxxx,
  476. "???", 0, alphaxxx,
  477. "???", 0, alphaxxx,
  478. "???", 0, alphaxxx,
  479. "???", 0, alphaxxx,
  480. "???", 0, alphaxxx,
  481. "???", 0, alphaxxx,
  482. "???", 0, alphaxxx,
  483. "???", 0, alphaxxx,
  484. "???", 0, alphaxxx,
  485. "???", 0, alphaxxx,
  486. "???", 0, alphaxxx,
  487. "???", 0, alphaxxx,
  488. };
  489. static Opcode ieeeopcodes[64] = {
  490. "ADDS", 0, alphafp,
  491. "SUBS", 0, alphafp,
  492. "MULS", 0, alphafp,
  493. "DIVS", 0, alphafp,
  494. "???", 0, alphaxxx,
  495. "???", 0, alphaxxx,
  496. "???", 0, alphaxxx,
  497. "???", 0, alphaxxx,
  498. "???", 0, alphaxxx,
  499. "???", 0, alphaxxx,
  500. "???", 0, alphaxxx,
  501. "???", 0, alphaxxx,
  502. "???", 0, alphaxxx,
  503. "???", 0, alphaxxx,
  504. "???", 0, alphaxxx,
  505. "???", 0, alphaxxx,
  506. "???", 0, alphaxxx,
  507. "???", 0, alphaxxx,
  508. "???", 0, alphaxxx,
  509. "???", 0, alphaxxx,
  510. "???", 0, alphaxxx,
  511. "???", 0, alphaxxx,
  512. "???", 0, alphaxxx,
  513. "???", 0, alphaxxx,
  514. "???", 0, alphaxxx,
  515. "???", 0, alphaxxx,
  516. "???", 0, alphaxxx,
  517. "???", 0, alphaxxx,
  518. "???", 0, alphaxxx,
  519. "???", 0, alphaxxx,
  520. "???", 0, alphaxxx,
  521. "???", 0, alphaxxx,
  522. "ADDT", 0, alphafp,
  523. "SUBT", 0, alphafp,
  524. "MULT", 0, alphafp,
  525. "DIVT", 0, alphafp,
  526. "CMPTUN", 0, alphafp,
  527. "CMPTEQ", 0, alphafp,
  528. "CMPTLT", 0, alphafp,
  529. "CMPTLE", 0, alphafp,
  530. "???", 0, alphaxxx,
  531. "???", 0, alphaxxx,
  532. "???", 0, alphaxxx,
  533. "???", 0, alphaxxx,
  534. "CVTTS", 0, alphafp2,
  535. "???", 0, alphaxxx,
  536. "???", 0, alphaxxx,
  537. "CVTTQ", 0, alphafp2,
  538. "???", 0, alphaxxx,
  539. "???", 0, alphaxxx,
  540. "???", 0, alphaxxx,
  541. "???", 0, alphaxxx,
  542. "???", 0, alphaxxx,
  543. "???", 0, alphaxxx,
  544. "???", 0, alphaxxx,
  545. "???", 0, alphaxxx,
  546. "???", 0, alphaxxx,
  547. "???", 0, alphaxxx,
  548. "???", 0, alphaxxx,
  549. "???", 0, alphaxxx,
  550. "CVTQS", 0, alphafp2,
  551. "???", 0, alphaxxx,
  552. "CVTQT", 0, alphafp2,
  553. "???", 0, alphaxxx,
  554. };
  555. static unsigned char amap[128] = {
  556. [0x00] 1,
  557. [0x40] 2,
  558. [0x20] 3,
  559. [0x60] 4,
  560. [0x09] 5,
  561. [0x49] 6,
  562. [0x29] 7,
  563. [0x69] 8,
  564. [0x2D] 9,
  565. [0x4D] 10,
  566. [0x6D] 11,
  567. [0x1D] 12,
  568. [0x3D] 13,
  569. [0x0F] 14,
  570. [0x02] 15,
  571. [0x0B] 16,
  572. [0x12] 17,
  573. [0x1B] 18,
  574. [0x22] 19,
  575. [0x2B] 20,
  576. [0x32] 21,
  577. [0x3B] 22,
  578. };
  579. static Opcode arithopcodes[64] = {
  580. "???", 0, alphaxxx,
  581. "ADDL", 0, alphaint,
  582. "ADDL/V", 0, alphaint,
  583. "ADDQ", 0, alphaint,
  584. "ADDQ/V", 0, alphaint,
  585. "SUBL", 0, alphaint,
  586. "SUBL/V", 0, alphaint,
  587. "SUBQ", 0, alphaint,
  588. "SUBQ/V", 0, alphaint,
  589. "CMPEQ", 0, alphaint,
  590. "CMPLT", 0, alphaint,
  591. "CMPLE", 0, alphaint,
  592. "CMPULT", 0, alphaint,
  593. "CMPULE", 0, alphaint,
  594. "CMPBGE", 0, alphaint,
  595. "S4ADDL", 0, alphaint,
  596. "S4SUBL", 0, alphaint,
  597. "S8ADDL", 0, alphaint,
  598. "S8SUBL", 0, alphaint,
  599. "S4ADDQ", 0, alphaint,
  600. "S4SUBQ", 0, alphaint,
  601. "S8ADDQ", 0, alphaint,
  602. "S8SUBQ", 0, alphaint,
  603. };
  604. static unsigned char lmap[128] = {
  605. [0x00] 1,
  606. [0x20] 2,
  607. [0x40] 3,
  608. [0x08] 4,
  609. [0x28] 5,
  610. [0x48] 6,
  611. [0x24] 7,
  612. [0x44] 8,
  613. [0x64] 9,
  614. [0x26] 7,
  615. [0x46] 8,
  616. [0x66] 9,
  617. [0x14] 10,
  618. [0x16] 11,
  619. };
  620. static Opcode logicalopcodes[64] = {
  621. "???", 0, alphaxxx,
  622. "AND", 0, alphaint,
  623. "OR", 0, alphaint,
  624. "XOR", 0, alphaint,
  625. "ANDNOT", 0, alphaint,
  626. "ORNOT", 0, alphaint,
  627. "XORNOT", 0, alphaint,
  628. "CMOVEQ", 0, alphaint,
  629. "CMOVLT", 0, alphaint,
  630. "CMOVLE", 0, alphaint,
  631. "CMOVNE", 0, alphaint,
  632. "CMOVGE", 0, alphaint,
  633. "CMOVGT", 0, alphaint,
  634. "CMOVLBS", 0, alphaint,
  635. "CMOVLBC", 0, alphaint,
  636. };
  637. static unsigned char smap[128] = {
  638. [0x39] 1,
  639. [0x3C] 2,
  640. [0x34] 3,
  641. [0x06] 4,
  642. [0x16] 5,
  643. [0x26] 6,
  644. [0x36] 7,
  645. [0x5A] 8,
  646. [0x6A] 9,
  647. [0x7A] 10,
  648. [0x0B] 11,
  649. [0x1B] 12,
  650. [0x2B] 13,
  651. [0x3B] 14,
  652. [0x57] 15,
  653. [0x67] 16,
  654. [0x77] 17,
  655. [0x02] 18,
  656. [0x12] 19,
  657. [0x22] 20,
  658. [0x32] 21,
  659. [0x52] 22,
  660. [0x62] 23,
  661. [0x72] 24,
  662. [0x30] 25,
  663. [0x31] 26,
  664. };
  665. static Opcode shiftopcodes[64] = {
  666. "???", 0, alphaxxx,
  667. "SLLQ", 0, alphaint,
  668. "SRAQ", 0, alphaint,
  669. "SRLQ", 0, alphaint,
  670. "EXTBL", 0, alphaint,
  671. "EXTWL", 0, alphaint,
  672. "EXTLL", 0, alphaint,
  673. "EXTQL", 0, alphaint,
  674. "EXTWH", 0, alphaint,
  675. "EXTLH", 0, alphaint,
  676. "EXTQH", 0, alphaint,
  677. "INSBL", 0, alphaint,
  678. "INSWL", 0, alphaint,
  679. "INSLL", 0, alphaint,
  680. "INSQL", 0, alphaint,
  681. "INSWH", 0, alphaint,
  682. "INSLH", 0, alphaint,
  683. "INSQH", 0, alphaint,
  684. "MSKBL", 0, alphaint,
  685. "MSKWL", 0, alphaint,
  686. "MSKLL", 0, alphaint,
  687. "MSKQL", 0, alphaint,
  688. "MSKWH", 0, alphaint,
  689. "MSKLH", 0, alphaint,
  690. "MSKQH", 0, alphaint,
  691. "ZAP", 0, alphaint,
  692. "ZAPNOT", 0, alphaint,
  693. };
  694. static void
  695. format(char *mnemonic, Instr *i, char *f)
  696. {
  697. if (mnemonic)
  698. format(0, i, mnemonic);
  699. if (f == 0)
  700. return;
  701. if (mnemonic)
  702. if (i->curr < i->end)
  703. *i->curr++ = '\t';
  704. for ( ; *f && i->curr < i->end; f++) {
  705. if (*f != '%') {
  706. *i->curr++ = *f;
  707. continue;
  708. }
  709. switch (*++f) {
  710. case 'a':
  711. bprint(i, "%d", i->ra);
  712. break;
  713. case 'b':
  714. bprint(i, "%d", i->rb);
  715. break;
  716. case 'c':
  717. bprint(i, "%d", i->rc);
  718. break;
  719. case 'v':
  720. if (i->islit)
  721. bprint(i, "$%ux", i->literal);
  722. else
  723. bprint(i, "R%d", i->rb);
  724. break;
  725. case 'l':
  726. bprint(i, "%lx(R%d)", i->mem, i->rb);
  727. break;
  728. case 'i':
  729. bprint(i, "$%lx", i->mem);
  730. break;
  731. case 'B':
  732. i->curr += symoff(i->curr, i->end-i->curr,
  733. (i->branch<<2)+i->addr+4, CANY);
  734. break;
  735. case 'w':
  736. bprint(i, "[%lux]", i->w0);
  737. break;
  738. case '\0':
  739. *i->curr++ = '%';
  740. return;
  741. default:
  742. bprint(i, "%%%c", *f);
  743. break;
  744. }
  745. }
  746. *i->curr = 0;
  747. }
  748. static int
  749. printins(Map *map, uint64_t pc, char *buf, int n)
  750. {
  751. Instr i;
  752. Opcode *o;
  753. uint8_t op;
  754. i.curr = buf;
  755. i.end = buf+n-1;
  756. mymap = map;
  757. if (mkinstr(pc, &i) < 0)
  758. return -1;
  759. switch (i.op) {
  760. case 0x10: /* INTA */
  761. o = arithopcodes;
  762. op = amap[i.function];
  763. break;
  764. case 0x11: /* INTL */
  765. o = logicalopcodes;
  766. op = lmap[i.function];
  767. break;
  768. case 0x12: /* INTS */
  769. o = shiftopcodes;
  770. op = smap[i.function];
  771. break;
  772. case 0x16: /* FLTI */
  773. o = ieeeopcodes;
  774. op = i.fpfn;
  775. break;
  776. case 0x17: /* FLTL */
  777. o = fpopcodes;
  778. op = i.fpfn;
  779. break;
  780. default:
  781. o = opcodes;
  782. op = i.op;
  783. break;
  784. }
  785. if (o[op].f)
  786. (*o[op].f)(&o[op], &i);
  787. else
  788. format(o[op].mnemonic, &i, o[op].ken);
  789. return i.size*4;
  790. }
  791. static int
  792. alphainst(Map *map, uint64_t pc, char modifier, char *buf, int n)
  793. {
  794. USED(modifier);
  795. return printins(map, pc, buf, n);
  796. }
  797. static int
  798. alphadas(Map *map, uint64_t pc, char *buf, int n)
  799. {
  800. Instr i;
  801. i.curr = buf;
  802. i.end = buf+n;
  803. mymap = map;
  804. if (mkinstr(pc, &i) < 0)
  805. return -1;
  806. if (i.end-i.curr > 8)
  807. i.curr = _hexify(buf, i.w0, 7);
  808. if (i.size == 2 && i.end-i.curr > 9) {
  809. *i.curr++ = ' ';
  810. i.curr = _hexify(i.curr, i.w1, 7);
  811. }
  812. *i.curr = 0;
  813. return i.size*4;
  814. }
  815. static int
  816. alphainstlen(Map *map, uint64_t pc)
  817. {
  818. Instr i;
  819. mymap = map;
  820. if (mkinstr(pc, &i) < 0)
  821. return -1;
  822. return i.size*4;
  823. }
  824. static int
  825. alphafoll(Map *map, uint64_t pc, Rgetter rget, uint64_t *foll)
  826. {
  827. char buf[8];
  828. Instr i;
  829. mymap = map;
  830. if (mkinstr(pc, &i) < 0)
  831. return -1;
  832. switch(i.op) {
  833. case 0x1A: /* JMP/JSR/RET */
  834. sprint(buf, "R%d", i.rb);
  835. foll[0] = (*rget)(map, buf);
  836. return 1;
  837. case 0x30: /* BR */
  838. case 0x34: /* BSR */
  839. foll[0] = pc+4 + (i.branch<<2);
  840. return 1;
  841. default:
  842. if (i.op > 0x30) { /* cond */
  843. foll[0] = pc+4;
  844. foll[1] = pc+4 + (i.branch<<2);
  845. return 2;
  846. }
  847. foll[0] = pc+i.size*4;
  848. return 1;
  849. }
  850. }