9db.c 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <mach.h>
  5. /*
  6. * amd29k-specific debugger interface
  7. */
  8. static int a29000inst(Map*, ulong, char, char*, int);
  9. static int a29000das(Map*, ulong, char*, int);
  10. static int a29000instlen(Map*, ulong);
  11. /*
  12. * Debugger interface
  13. */
  14. Machdata a29000mach =
  15. {
  16. {0, 0, 0, 0}, /* break point */
  17. 4, /* break point size */
  18. beswab, /* short to local byte order */
  19. beswal, /* long to local byte order */
  20. beswav, /* vlong to local byte order */
  21. risctrace, /* C traceback */
  22. riscframe, /* Frame finder */
  23. 0, /* print exception */
  24. 0, /* breakpoint fixup */
  25. beieeesftos, /* single precision float printer */
  26. beieeedftos, /* double precisioin float printer */
  27. 0, /* following addresses */
  28. a29000inst, /* print instruction */
  29. a29000das, /* dissembler */
  30. a29000instlen, /* instruction size */
  31. };
  32. /* mips disassembler and related functions */
  33. static char FRAMENAME[] = ".frame";
  34. /* amd 29k native disassembler */
  35. typedef struct {
  36. long addr; /* pc of instr */
  37. uchar op; /* bits 31-24 */
  38. uchar rc; /* bits 23-16 */
  39. uchar ra; /* bits 15-8 */
  40. uchar rb; /* bits 0-7 */
  41. ushort imm; /* bits 23-16 and bits 0-7 */
  42. long w0;
  43. char *curr; /* current fill point */
  44. char *end; /* end of buffer */
  45. char *err;
  46. } Instr;
  47. typedef struct {
  48. char *mnemonic;
  49. char *fmt;
  50. } Opcode;
  51. static char amdunk[] = "%w";
  52. static char amdalu2op[] = "r%c,r%a";
  53. static char amdaluasop[] = "$%c,r%a,r%b";
  54. static char amdaluasopi[] = "$%c,r%a,%s";
  55. static char amdalu3op[] = "r%c,r%a,r%b";
  56. static char amdalu3opi[] = "r%c,r%a,%s";
  57. static char amdjs[] = "r%a,%j";
  58. static char amdju[] = "r%a,%J";
  59. static char amdji[] = "r%a,r%b";
  60. static char amdmem[] = "%m,r%a,r%b";
  61. static char amdmemi[] = "%m,r%a,%s";
  62. static char *memacc[8] = { "L", "B", "H", "HW" };
  63. static Opcode opcodes[256] = {
  64. 0, 0,
  65. "constn", "r%a,%i",
  66. "consth", "r%a,%I0000",
  67. "const", "r%a,%I",
  68. "mtsrim", "s%a,%I",
  69. 0, 0,
  70. "loadl", amdmem,
  71. "loadl", amdmemi,
  72. "clz", amdunk,
  73. "clz", amdunk,
  74. "exbyte", amdalu3op,
  75. "exbyte", amdalu3opi,
  76. "inbyte", amdalu3op,
  77. "inbyte", amdalu3opi,
  78. "storel", amdmem,
  79. "storel", amdmemi,
  80. "adds", amdalu3op,
  81. "adds", amdalu3opi,
  82. "addu", amdalu3op,
  83. "addu", amdalu3opi,
  84. "add", amdalu3op,
  85. "add", amdalu3opi,
  86. "load", amdmem,
  87. "load", amdmemi,
  88. "addcs", amdalu3op,
  89. "addcs", amdalu3opi,
  90. "addcu", amdalu3op,
  91. "addcu", amdalu3opi,
  92. "addc", amdalu3op,
  93. "addc", amdalu3opi,
  94. "store", amdmem,
  95. "store", amdmemi,
  96. "subs", amdalu3op,
  97. "subs", amdalu3opi,
  98. "subu", amdalu3op,
  99. "subu", amdalu3opi,
  100. "sub", amdalu3op,
  101. "sub", amdalu3opi,
  102. "loadset", amdmem,
  103. "loadset", amdmemi,
  104. "subcs", amdalu3op,
  105. "subcs", amdalu3opi,
  106. "subcu", amdalu3op,
  107. "subcu", amdalu3opi,
  108. "subc", amdalu3op,
  109. "subc", amdalu3opi,
  110. "cpbyte", amdalu3op,
  111. "cpbyte", amdalu3opi,
  112. "subrs", amdalu3op,
  113. "subrs", amdalu3opi,
  114. "subru", amdalu3op,
  115. "subru", amdalu3opi,
  116. "subr", amdalu3op,
  117. "subr", amdalu3opi,
  118. "loadm", amdmem,
  119. "loadm", amdmemi,
  120. "subrcs", amdalu3op,
  121. "subrcs", amdalu3opi,
  122. "subrcu", amdalu3op,
  123. "subrcu", amdalu3opi,
  124. "subrc", amdalu3op,
  125. "subrc", amdalu3opi,
  126. "storem", amdmem,
  127. "storem", amdmemi,
  128. "cplt", amdalu3op,
  129. "cplt", amdalu3opi,
  130. "cpltu", amdalu3op,
  131. "cpltu", amdalu3opi,
  132. "cple", amdalu3op,
  133. "cple", amdalu3opi,
  134. "cpleu", amdalu3op,
  135. "cpleu", amdalu3opi,
  136. "cpgt", amdalu3op,
  137. "cpgt", amdalu3opi,
  138. "cpgtu", amdalu3op,
  139. "cpgtu", amdalu3opi,
  140. "cpge", amdalu3op,
  141. "cpge", amdalu3opi,
  142. "cpgeu", amdalu3op,
  143. "cpgeu", amdalu3opi,
  144. "aslt", amdaluasop,
  145. "aslt", amdaluasopi,
  146. "asltu", amdaluasop,
  147. "asltu", amdaluasopi,
  148. "asle", amdaluasop,
  149. "asle", amdaluasopi,
  150. "asleu", amdaluasop,
  151. "asleu", amdaluasopi,
  152. "asgt", amdaluasop,
  153. "asgt", amdaluasopi,
  154. "asgtu", amdaluasop,
  155. "asgtu", amdaluasopi,
  156. "asge", amdaluasop,
  157. "asge", amdaluasopi,
  158. "asgeu", amdaluasop,
  159. "asgeu", amdaluasopi,
  160. "cpeq", amdalu3op,
  161. "cpeq", amdalu3opi,
  162. "cpneq", amdalu3op,
  163. "cpneq", amdalu3opi,
  164. "mul", amdalu3op,
  165. "mul", amdalu3opi,
  166. "mull", amdalu3op,
  167. "mull", amdalu3opi,
  168. "div0", amdalu3op,
  169. "div0", amdalu3opi,
  170. "div", amdalu3op,
  171. "div", amdalu3opi,
  172. "divl", amdalu3op,
  173. "divl", amdalu3opi,
  174. "divrem", amdalu3op,
  175. "divrem", amdalu3opi,
  176. "aseq", amdaluasop,
  177. "aseq", amdaluasopi,
  178. "asneq", amdaluasop,
  179. "asneq", amdaluasopi,
  180. "mulu", amdalu3op,
  181. "mulu", amdalu3opi,
  182. 0, 0,
  183. 0, 0,
  184. "inhw", amdalu3op,
  185. "inhw", amdalu3opi,
  186. "extract", amdalu3op,
  187. "extract", amdalu3opi,
  188. "exhw", amdalu3op,
  189. "exhw", amdalu3opi,
  190. "exhws", amdalu2op,
  191. 0, 0,
  192. "sll", amdalu3op,
  193. "sll", amdalu3opi,
  194. "srl", amdalu3op,
  195. "srl", amdalu3opi,
  196. 0, 0,
  197. 0, 0,
  198. "sra", amdalu3op,
  199. "sra", amdalu3opi,
  200. "iret", amdunk,
  201. "halt", amdunk,
  202. 0, 0,
  203. 0, 0,
  204. "iretinv", amdunk,
  205. 0, 0,
  206. 0, 0,
  207. 0, 0,
  208. "and", amdalu3op,
  209. "and", amdalu3opi,
  210. "or", amdalu3op,
  211. "or", amdalu3opi,
  212. "xor", amdalu3op,
  213. "xor", amdalu3opi,
  214. "xnor", amdalu3op,
  215. "xnor", amdalu3opi,
  216. "nor", amdalu3op,
  217. "nor", amdalu3opi,
  218. "nand", amdalu3op,
  219. "nand", amdalu3opi,
  220. "andn", amdalu3op,
  221. "andn", amdalu3opi,
  222. "setip", amdalu3op,
  223. "inv", amdunk,
  224. "jmp", "%j",
  225. "jmp", "%J",
  226. 0, 0,
  227. 0, 0,
  228. "jmpf", amdjs,
  229. "jmpf", amdju,
  230. 0, 0,
  231. 0, 0,
  232. "call", amdjs,
  233. "call", amdju,
  234. 0, 0,
  235. 0, 0,
  236. "jmpt", amdjs,
  237. "jmpt", amdju,
  238. 0, 0,
  239. 0, 0,
  240. 0, 0,
  241. 0, 0,
  242. 0, 0,
  243. 0, 0,
  244. "jmpfdec", amdunk,
  245. "jmpfdec", amdunk,
  246. "mftlb", "r%c,r%a",
  247. 0, 0,
  248. 0, 0,
  249. 0, 0,
  250. 0, 0,
  251. 0, 0,
  252. 0, 0,
  253. 0, 0,
  254. "mttlb", "r%a,r%b",
  255. 0, 0,
  256. "jmpi", "r%b",
  257. 0, 0,
  258. 0, 0,
  259. 0, 0,
  260. "jmpfi", amdji,
  261. 0, 0,
  262. "mfsr", "r%c,s%a",
  263. 0, 0,
  264. "calli", amdji,
  265. 0, 0,
  266. 0, 0,
  267. 0, 0,
  268. "jmpti", amdji,
  269. 0, 0,
  270. "mtsr", "s%a,r%b",
  271. 0, 0,
  272. 0, 0,
  273. 0, 0,
  274. 0, 0,
  275. 0, 0,
  276. 0, 0,
  277. 0, 0,
  278. 0, 0,
  279. "emulate", amdunk,
  280. 0, 0, /* D8: vector 24 */
  281. 0, 0,
  282. 0, 0,
  283. 0, 0,
  284. 0, 0,
  285. 0, 0, /* DD: vector 29 */
  286. "multm", amdalu3op,
  287. "multmu", amdalu3op,
  288. "multiply", amdalu3op,
  289. "divide", amdalu3op,
  290. "multiplu", amdalu3op,
  291. "dividu", amdalu3op,
  292. "convert", amdunk,
  293. "sqrt", amdunk,
  294. "class", amdunk,
  295. 0, 0, /* E7: vector 39 */
  296. 0, 0,
  297. 0, 0, /* E9: vector 41 */
  298. "feq", amdunk,
  299. "deq", amdunk,
  300. "fgt", amdunk,
  301. "dgt", amdunk,
  302. "fge", amdunk,
  303. "dge", amdunk,
  304. "fadd", amdunk,
  305. "dadd", amdunk,
  306. "fsub", amdunk,
  307. "dsub", amdunk,
  308. "fmul", amdunk,
  309. "dmul", amdunk,
  310. "fdiv", amdunk,
  311. "ddiv", amdunk,
  312. 0, 0, /* F8: vector 56 */
  313. "fdmul", amdunk,
  314. 0, 0, /* FA: vector 58 */
  315. 0, 0,
  316. 0, 0,
  317. 0, 0,
  318. 0, 0,
  319. 0, 0, /* FF: vector 63 */
  320. };
  321. static int
  322. mkinstr(Instr *i, ulong pc, ulong w)
  323. {
  324. i->addr = pc;
  325. i->op = (w >> 24) & 0xFF;
  326. i->rc = (w >> 16) & 0xFF;
  327. i->ra = (w >> 8) & 0xFF;
  328. i->rb = (w >> 0) & 0xFF;
  329. i->imm = ((w >> 8) & 0xFF00) | (w & 0xFF);
  330. i->w0 = w;
  331. return 1;
  332. }
  333. static void
  334. bprint(Instr *i, char *fmt, ...)
  335. {
  336. va_list arg;
  337. va_start(arg, fmt);
  338. i->curr = vseprint(i->curr, i->end, fmt, arg);
  339. va_end(arg);
  340. }
  341. static void
  342. format(char *mnemonic, Instr *i, char *f)
  343. {
  344. char *s;
  345. int a;
  346. if (mnemonic)
  347. format(0, i, mnemonic);
  348. if (f == 0)
  349. return;
  350. if (i->curr < i->end)
  351. *i->curr++ = '\t';
  352. for ( ; *f && i->curr < i->end; f++) {
  353. if (*f != '%') {
  354. *i->curr++ = *f;
  355. continue;
  356. }
  357. switch (*++f) {
  358. case 'm':
  359. s = memacc[i->rc & 7];
  360. if(s == 0 || i->rc & (7<<6)){
  361. bprint(i, "?0x%.2x", i->rc);
  362. break;
  363. }
  364. if(i->rc & (1<<5))
  365. bprint(i, "%c", 'P');
  366. if(i->rc & (1<<4))
  367. bprint(i, "%c", 'S');
  368. if(i->rc & (1<<3))
  369. bprint(i, "%c", 'U');
  370. bprint(i, "%s", s);
  371. break;
  372. case 'a':
  373. bprint(i, "%d", i->ra);
  374. break;
  375. case 'b':
  376. bprint(i, "%d", i->rb);
  377. break;
  378. case 'c':
  379. bprint(i, "%d", i->rc);
  380. break;
  381. case 's':
  382. bprint(i, "$%.2ux", i->rb);
  383. break;
  384. case 'i':
  385. bprint(i, "$%.4ux", i->imm | ~0xFFFF);
  386. break;
  387. case 'I':
  388. bprint(i, "$%.4ux", i->imm);
  389. break;
  390. case 'j':
  391. a = i->imm;
  392. if(a & 0x8000)
  393. a |= ~0xFFFF;
  394. i->curr += symoff(i->curr, i->end-i->curr, i->addr+(a<<2), CANY);
  395. bprint(i, "(SB)");
  396. break;
  397. case 'J':
  398. a = i->imm;
  399. i->curr += symoff(i->curr, i->end-i->curr, a<<2, CANY);
  400. bprint(i, "(SB)");
  401. break;
  402. case 'w':
  403. bprint(i, "[%.8lux]", i->w0);
  404. break;
  405. case '\0':
  406. bprint(i, "%");
  407. return;
  408. default:
  409. bprint(i, "%%%c", *f);
  410. break;
  411. }
  412. }
  413. }
  414. /*
  415. * used by 9i
  416. */
  417. int
  418. _a29000disinst(ulong pc, ulong w, char *buf, int n)
  419. {
  420. Instr i;
  421. Opcode *o;
  422. i.curr = buf;
  423. i.end = buf+n-1;
  424. mkinstr(&i, pc, w);
  425. o = &opcodes[i.op];
  426. format(o->mnemonic, &i, o->fmt);
  427. *i.curr = '\0';
  428. return 4;
  429. }
  430. static int
  431. a29000inst(Map *map, ulong pc, char, char *buf, int n)
  432. {
  433. Instr i;
  434. Opcode *o;
  435. long w;
  436. if (get4(map, pc, &w) < 0) {
  437. werrstr("can't read instruction: %r");
  438. return -1;
  439. }
  440. i.curr = buf;
  441. i.end = buf+n-1;
  442. mkinstr(&i, pc, w);
  443. o = &opcodes[i.op];
  444. format(o->mnemonic, &i, o->fmt);
  445. return 4;
  446. }
  447. static int
  448. a29000das(Map *map, ulong pc, char *buf, int n)
  449. {
  450. Instr i;
  451. long w;
  452. if (get4(map, pc, &w) < 0) {
  453. werrstr("can't read instruction: %r");
  454. return -1;
  455. }
  456. i.curr = buf;
  457. i.end = buf+n;
  458. if (i.end-i.curr > 8)
  459. i.curr = _hexify(buf, w, 7);
  460. *i.curr = 0;
  461. return 4;
  462. }
  463. static int
  464. a29000instlen(Map*, ulong)
  465. {
  466. return 4;
  467. }