qdb.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372
  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. * PowerPC-specific debugger interface,
  15. * including 64-bit modes
  16. * forsyth@terzarima.net
  17. */
  18. static char *powerexcep(Map*, Rgetter);
  19. static int powerfoll(Map*, uint64_t, Rgetter, uint64_t*);
  20. static int powerinst(Map*, uint64_t, char, char*, int);
  21. static int powerinstlen(Map*, uint64_t);
  22. static int powerdas(Map*, uint64_t, char*, int);
  23. /*
  24. * Machine description
  25. */
  26. Machdata powermach =
  27. {
  28. {0x02, 0x8f, 0xff, 0xff}, /* break point */ /* BUG */
  29. 4, /* break point size */
  30. beswab, /* short to local byte order */
  31. beswal, /* long to local byte order */
  32. beswav, /* vlong to local byte order */
  33. risctrace, /* print C traceback */
  34. riscframe, /* frame finder */
  35. powerexcep, /* print exception */
  36. 0, /* breakpoint fixup */
  37. beieeesftos, /* single precision float printer */
  38. beieeedftos, /* double precisioin float printer */
  39. powerfoll, /* following addresses */
  40. powerinst, /* print instruction */
  41. powerdas, /* dissembler */
  42. powerinstlen, /* instruction size */
  43. };
  44. static char *excname[] =
  45. {
  46. "reserved 0",
  47. "system reset",
  48. "machine check",
  49. "data access",
  50. "instruction access",
  51. "external interrupt",
  52. "alignment",
  53. "program exception",
  54. "floating-point unavailable",
  55. "decrementer",
  56. "i/o controller interface error",
  57. "reserved B",
  58. "system call",
  59. "trace trap",
  60. "floating point assist",
  61. "reserved",
  62. "ITLB miss",
  63. "DTLB load miss",
  64. "DTLB store miss",
  65. "instruction address breakpoint"
  66. "SMI interrupt"
  67. "reserved 15",
  68. "reserved 16",
  69. "reserved 17",
  70. "reserved 18",
  71. "reserved 19",
  72. "reserved 1A",
  73. /* the following are made up on a program exception */
  74. "floating point exception", /* FPEXC */
  75. "illegal instruction",
  76. "privileged instruction",
  77. "trap",
  78. "illegal operation",
  79. };
  80. static char*
  81. powerexcep(Map *map, Rgetter rget)
  82. {
  83. int32_t c;
  84. static char buf[32];
  85. c = (*rget)(map, "CAUSE") >> 8;
  86. if(c < nelem(excname))
  87. return excname[c];
  88. sprint(buf, "unknown trap #%lx", c);
  89. return buf;
  90. }
  91. /*
  92. * disassemble PowerPC opcodes
  93. */
  94. #define REGSP 1 /* should come from q.out.h, but there's a clash */
  95. #define REGSB 2
  96. static char FRAMENAME[] = ".frame";
  97. static Map *mymap;
  98. /*
  99. * ibm conventions for these: bit 0 is top bit
  100. * from table 10-1
  101. */
  102. typedef struct {
  103. uint8_t aa; /* bit 30 */
  104. uint8_t crba; /* bits 11-15 */
  105. uint8_t crbb; /* bits 16-20 */
  106. int32_t bd; /* bits 16-29 */
  107. uint8_t crfd; /* bits 6-8 */
  108. uint8_t crfs; /* bits 11-13 */
  109. uint8_t bi; /* bits 11-15 */
  110. uint8_t bo; /* bits 6-10 */
  111. uint8_t crbd; /* bits 6-10 */
  112. union {
  113. int16_t d; /* bits 16-31 */
  114. int16_t simm;
  115. uint16_t uimm;
  116. };
  117. uint8_t fm; /* bits 7-14 */
  118. uint8_t fra; /* bits 11-15 */
  119. uint8_t frb; /* bits 16-20 */
  120. uint8_t frc; /* bits 21-25 */
  121. uint8_t frs; /* bits 6-10 */
  122. uint8_t frd; /* bits 6-10 */
  123. uint8_t crm; /* bits 12-19 */
  124. int32_t li; /* bits 6-29 || b'00' */
  125. uint8_t lk; /* bit 31 */
  126. uint8_t mb; /* bits 21-25 */
  127. uint8_t me; /* bits 26-30 */
  128. uint8_t xmbe; /* bits 26,21-25: mb[5] || mb[0:4], also xme */
  129. uint8_t xsh; /* bits 30,16-20: sh[5] || sh[0:4] */
  130. uint8_t nb; /* bits 16-20 */
  131. uint8_t op; /* bits 0-5 */
  132. uint8_t oe; /* bit 21 */
  133. uint8_t ra; /* bits 11-15 */
  134. uint8_t rb; /* bits 16-20 */
  135. uint8_t rc; /* bit 31 */
  136. union {
  137. uint8_t rs; /* bits 6-10 */
  138. uint8_t rd;
  139. };
  140. uint8_t sh; /* bits 16-20 */
  141. uint16_t spr; /* bits 11-20 */
  142. uint8_t to; /* bits 6-10 */
  143. uint8_t imm; /* bits 16-19 */
  144. uint16_t xo; /* bits 21-30, 22-30, 26-30, or 30 (beware) */
  145. uint64_t imm64;
  146. int32_t w0;
  147. int32_t w1;
  148. uint64_t addr; /* pc of instruction */
  149. int16_t target;
  150. int16_t m64; /* 64-bit mode */
  151. char *curr; /* current fill level in output buffer */
  152. char *end; /* end of buffer */
  153. int size; /* number of longs in instr */
  154. char *err; /* errmsg */
  155. } Instr;
  156. #define IBF(v,a,b) (((unsigned long)(v)>>(32-(b)-1)) & ~(~0L<<(((b)-(a)+1))))
  157. #define IB(v,b) IBF((v),(b),(b))
  158. #pragma varargck argpos bprint 2
  159. static void
  160. bprint(Instr *i, char *fmt, ...)
  161. {
  162. va_list arg;
  163. va_start(arg, fmt);
  164. i->curr = vseprint(i->curr, i->end, fmt, arg);
  165. va_end(arg);
  166. }
  167. static int
  168. decode(uint64_t pc, Instr *i)
  169. {
  170. uint32_t w;
  171. if (get4(mymap, pc, &w) < 0) {
  172. werrstr("can't read instruction: %r");
  173. return -1;
  174. }
  175. i->m64 = asstype == APOWER64;
  176. i->aa = IB(w, 30);
  177. i->crba = IBF(w, 11, 15);
  178. i->crbb = IBF(w, 16, 20);
  179. i->bd = IBF(w, 16, 29)<<2;
  180. if(i->bd & 0x8000)
  181. i->bd |= ~0L<<16;
  182. i->crfd = IBF(w, 6, 8);
  183. i->crfs = IBF(w, 11, 13);
  184. i->bi = IBF(w, 11, 15);
  185. i->bo = IBF(w, 6, 10);
  186. i->crbd = IBF(w, 6, 10);
  187. i->uimm = IBF(w, 16, 31); /* also d, simm */
  188. i->fm = IBF(w, 7, 14);
  189. i->fra = IBF(w, 11, 15);
  190. i->frb = IBF(w, 16, 20);
  191. i->frc = IBF(w, 21, 25);
  192. i->frs = IBF(w, 6, 10);
  193. i->frd = IBF(w, 6, 10);
  194. i->crm = IBF(w, 12, 19);
  195. i->li = IBF(w, 6, 29)<<2;
  196. if(IB(w, 6))
  197. i->li |= ~0<<25;
  198. i->lk = IB(w, 31);
  199. i->mb = IBF(w, 21, 25);
  200. i->me = IBF(w, 26, 30);
  201. i->xmbe = (IB(w,26)<<5) | i->mb;
  202. i->nb = IBF(w, 16, 20);
  203. i->op = IBF(w, 0, 5);
  204. i->oe = IB(w, 21);
  205. i->ra = IBF(w, 11, 15);
  206. i->rb = IBF(w, 16, 20);
  207. i->rc = IB(w, 31);
  208. i->rs = IBF(w, 6, 10); /* also rd */
  209. i->sh = IBF(w, 16, 20);
  210. i->xsh = (IB(w, 30)<<5) | i->sh;
  211. i->spr = IBF(w, 11, 20);
  212. i->to = IBF(w, 6, 10);
  213. i->imm = IBF(w, 16, 19);
  214. i->xo = IBF(w, 21, 30); /* bits 21-30, 22-30, 26-30, or 30 (beware) */
  215. if(i->op == 58){ /* class of 64-bit loads */
  216. i->xo = i->simm & 3;
  217. i->simm &= ~3;
  218. }
  219. i->imm64 = i->simm;
  220. if(i->op == 15)
  221. i->imm64 <<= 16;
  222. else if(i->op == 25 || i->op == 27 || i->op == 29)
  223. i->imm64 = (uint64_t)(i->uimm<<16);
  224. i->w0 = w;
  225. i->target = -1;
  226. i->addr = pc;
  227. i->size = 1;
  228. return 1;
  229. }
  230. static int
  231. mkinstr(uint64_t pc, Instr *i)
  232. {
  233. Instr x;
  234. if(decode(pc, i) < 0)
  235. return -1;
  236. /*
  237. * combine ADDIS/ORI (CAU/ORIL) into MOVW
  238. * also ORIS/ORIL for unsigned in 64-bit mode
  239. */
  240. if ((i->op == 15 || i->op == 25) && i->ra==0) {
  241. if(decode(pc+4, &x) < 0)
  242. return -1;
  243. if (x.op == 24 && x.rs == x.ra && x.ra == i->rd) {
  244. i->imm64 |= (x.imm64 & 0xFFFF);
  245. if(i->op != 15)
  246. i->imm64 &= 0xFFFFFFFFUL;
  247. i->w1 = x.w0;
  248. i->target = x.rd;
  249. i->size++;
  250. return 1;
  251. }
  252. }
  253. return 1;
  254. }
  255. static int
  256. plocal(Instr *i)
  257. {
  258. int32_t offset;
  259. Symbol s;
  260. if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
  261. return -1;
  262. offset = s.value - i->imm64;
  263. if (offset > 0) {
  264. if(getauto(&s, offset, CAUTO, &s)) {
  265. bprint(i, "%s+%lld(SP)", s.name, s.value);
  266. return 1;
  267. }
  268. } else {
  269. if (getauto(&s, -offset-4, CPARAM, &s)) {
  270. bprint(i, "%s+%ld(FP)", s.name, -offset);
  271. return 1;
  272. }
  273. }
  274. return -1;
  275. }
  276. static int
  277. pglobal(Instr *i, uint64_t off, int anyoff, char *reg)
  278. {
  279. Symbol s, s2;
  280. uint64_t off1;
  281. if(findsym(off, CANY, &s) &&
  282. off-s.value < 4096 &&
  283. (s.class == CDATA || s.class == CTEXT)) {
  284. if(off==s.value && s.name[0]=='$'){
  285. off1 = 0;
  286. geta(mymap, s.value, &off1);
  287. if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){
  288. bprint(i, "$%s%s", s2.name, reg);
  289. return 1;
  290. }
  291. }
  292. bprint(i, "%s", s.name);
  293. if (s.value != off)
  294. bprint(i, "+%llux", off-s.value);
  295. bprint(i, reg);
  296. return 1;
  297. }
  298. if(!anyoff)
  299. return 0;
  300. bprint(i, "%llux%s", off, reg);
  301. return 1;
  302. }
  303. static void
  304. address(Instr *i)
  305. {
  306. if (i->ra == REGSP && plocal(i) >= 0)
  307. return;
  308. if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->imm64, 0, "(SB)"))
  309. return;
  310. if(i->simm < 0)
  311. bprint(i, "-%x(R%d)", -i->simm, i->ra);
  312. else
  313. bprint(i, "%llux(R%d)", i->imm64, i->ra);
  314. }
  315. static char *tcrbits[] = {"LT", "GT", "EQ", "VS"};
  316. static char *fcrbits[] = {"GE", "LE", "NE", "VC"};
  317. typedef struct Opcode Opcode;
  318. struct Opcode {
  319. uint8_t op;
  320. uint16_t xo;
  321. uint16_t xomask;
  322. char *mnemonic;
  323. void (*f)(Opcode *, Instr *);
  324. char *ken;
  325. int flags;
  326. };
  327. static void format(char *, Instr *, char *);
  328. static void
  329. branch(Opcode *o, Instr *i)
  330. {
  331. char buf[8];
  332. int bo, bi;
  333. bo = i->bo & ~1; /* ignore prediction bit */
  334. if(bo==4 || bo==12 || bo==20) { /* simple forms */
  335. if(bo != 20) {
  336. bi = i->bi&3;
  337. sprint(buf, "B%s%%L", bo==12? tcrbits[bi]: fcrbits[bi]);
  338. format(buf, i, nil);
  339. bprint(i, "\t");
  340. if(i->bi > 4)
  341. bprint(i, "CR(%d),", i->bi/4);
  342. } else
  343. format("BR%L\t", i, nil);
  344. if(i->op == 16)
  345. format(0, i, "%J");
  346. else if(i->op == 19 && i->xo == 528)
  347. format(0, i, "(CTR)");
  348. else if(i->op == 19 && i->xo == 16)
  349. format(0, i, "(LR)");
  350. } else
  351. format(o->mnemonic, i, o->ken);
  352. }
  353. static void
  354. addi(Opcode *o, Instr *i)
  355. {
  356. if (i->op==14 && i->ra == 0)
  357. format("MOVW", i, "%i,R%d");
  358. else if (i->ra == REGSB) {
  359. bprint(i, "MOVW\t$");
  360. address(i);
  361. bprint(i, ",R%d", i->rd);
  362. } else if(i->op==14 && i->simm < 0) {
  363. bprint(i, "SUB\t$%d,R%d", -i->simm, i->ra);
  364. if(i->rd != i->ra)
  365. bprint(i, ",R%d", i->rd);
  366. } else if(i->ra == i->rd) {
  367. format(o->mnemonic, i, "%i");
  368. bprint(i, ",R%d", i->rd);
  369. } else
  370. format(o->mnemonic, i, o->ken);
  371. }
  372. static void
  373. addis(Opcode *o, Instr *i)
  374. {
  375. int32_t v;
  376. v = i->imm64;
  377. if (i->op==15 && i->ra == 0)
  378. bprint(i, "MOVW\t$%lux,R%d", v, i->rd);
  379. else if (i->op==15 && i->ra == REGSB) {
  380. bprint(i, "MOVW\t$");
  381. address(i);
  382. bprint(i, ",R%d", i->rd);
  383. } else if(i->op==15 && v < 0) {
  384. bprint(i, "SUB\t$%ld,R%d", -v, i->ra);
  385. if(i->rd != i->ra)
  386. bprint(i, ",R%d", i->rd);
  387. } else {
  388. format(o->mnemonic, i, nil);
  389. bprint(i, "\t$%ld,R%d", v, i->ra);
  390. if(i->rd != i->ra)
  391. bprint(i, ",R%d", i->rd);
  392. }
  393. }
  394. static void
  395. andi(Opcode *o, Instr *i)
  396. {
  397. if (i->ra == i->rs)
  398. format(o->mnemonic, i, "%I,R%d");
  399. else
  400. format(o->mnemonic, i, o->ken);
  401. }
  402. static void
  403. gencc(Opcode *o, Instr *i)
  404. {
  405. format(o->mnemonic, i, o->ken);
  406. }
  407. static void
  408. gen(Opcode *o, Instr *i)
  409. {
  410. format(o->mnemonic, i, o->ken);
  411. if (i->rc)
  412. bprint(i, " [illegal Rc]");
  413. }
  414. static void
  415. ldx(Opcode *o, Instr *i)
  416. {
  417. if(i->ra == 0)
  418. format(o->mnemonic, i, "(R%b),R%d");
  419. else
  420. format(o->mnemonic, i, "(R%b+R%a),R%d");
  421. if(i->rc)
  422. bprint(i, " [illegal Rc]");
  423. }
  424. static void
  425. stx(Opcode *o, Instr *i)
  426. {
  427. if(i->ra == 0)
  428. format(o->mnemonic, i, "R%d,(R%b)");
  429. else
  430. format(o->mnemonic, i, "R%d,(R%b+R%a)");
  431. if(i->rc && i->xo != 150)
  432. bprint(i, " [illegal Rc]");
  433. }
  434. static void
  435. fldx(Opcode *o, Instr *i)
  436. {
  437. if(i->ra == 0)
  438. format(o->mnemonic, i, "(R%b),F%d");
  439. else
  440. format(o->mnemonic, i, "(R%b+R%a),F%d");
  441. if(i->rc)
  442. bprint(i, " [illegal Rc]");
  443. }
  444. static void
  445. fstx(Opcode *o, Instr *i)
  446. {
  447. if(i->ra == 0)
  448. format(o->mnemonic, i, "F%d,(R%b)");
  449. else
  450. format(o->mnemonic, i, "F%d,(R%b+R%a)");
  451. if(i->rc)
  452. bprint(i, " [illegal Rc]");
  453. }
  454. static void
  455. dcb(Opcode *o, Instr *i)
  456. {
  457. if(i->ra == 0)
  458. format(o->mnemonic, i, "(R%b)");
  459. else
  460. format(o->mnemonic, i, "(R%b+R%a)");
  461. if(i->rd)
  462. bprint(i, " [illegal Rd]");
  463. if(i->rc)
  464. bprint(i, " [illegal Rc]");
  465. }
  466. static void
  467. lw(Opcode *o, Instr *i, char r)
  468. {
  469. format(o->mnemonic, i, nil);
  470. bprint(i, "\t");
  471. address(i);
  472. bprint(i, ",%c%d", r, i->rd);
  473. }
  474. static void
  475. load(Opcode *o, Instr *i)
  476. {
  477. lw(o, i, 'R');
  478. }
  479. static void
  480. fload(Opcode *o, Instr *i)
  481. {
  482. lw(o, i, 'F');
  483. }
  484. static void
  485. sw(Opcode *o, Instr *i, char r)
  486. {
  487. int offset;
  488. Symbol s;
  489. if (i->rs == REGSP) {
  490. if (findsym(i->addr, CTEXT, &s) && findlocal(&s, FRAMENAME, &s)) {
  491. offset = s.value-i->imm64;
  492. if (offset > 0 && getauto(&s, offset, CAUTO, &s)) {
  493. format(o->mnemonic, i, nil);
  494. bprint(i, "\t%c%d,%s-%d(SP)", r, i->rd, s.name, offset);
  495. return;
  496. }
  497. }
  498. }
  499. if (i->rs == REGSB && mach->sb) {
  500. format(o->mnemonic, i, nil);
  501. bprint(i, "\t%c%d,", r, i->rd);
  502. address(i);
  503. return;
  504. }
  505. if (r == 'F')
  506. format(o->mnemonic, i, "F%d,%l");
  507. else
  508. format(o->mnemonic, i, o->ken);
  509. }
  510. static void
  511. store(Opcode *o, Instr *i)
  512. {
  513. sw(o, i, 'R');
  514. }
  515. static void
  516. fstore(Opcode *o, Instr *i)
  517. {
  518. sw(o, i, 'F');
  519. }
  520. static void
  521. shifti(Opcode *o, Instr *i)
  522. {
  523. if (i->ra == i->rs)
  524. format(o->mnemonic, i, "$%k,R%a");
  525. else
  526. format(o->mnemonic, i, o->ken);
  527. }
  528. static void
  529. shift(Opcode *o, Instr *i)
  530. {
  531. if (i->ra == i->rs)
  532. format(o->mnemonic, i, "R%b,R%a");
  533. else
  534. format(o->mnemonic, i, o->ken);
  535. }
  536. static void
  537. add(Opcode *o, Instr *i)
  538. {
  539. if (i->rd == i->ra)
  540. format(o->mnemonic, i, "R%b,R%d");
  541. else if (i->rd == i->rb)
  542. format(o->mnemonic, i, "R%a,R%d");
  543. else
  544. format(o->mnemonic, i, o->ken);
  545. }
  546. static void
  547. sub(Opcode *o, Instr *i)
  548. {
  549. format(o->mnemonic, i, nil);
  550. bprint(i, "\t");
  551. if(i->op == 31) {
  552. bprint(i, "\tR%d,R%d", i->ra, i->rb); /* subtract Ra from Rb */
  553. if(i->rd != i->rb)
  554. bprint(i, ",R%d", i->rd);
  555. } else
  556. bprint(i, "\tR%d,$%d,R%d", i->ra, i->simm, i->rd);
  557. }
  558. static void
  559. qdiv(Opcode *o, Instr *i)
  560. {
  561. format(o->mnemonic, i, nil);
  562. if(i->op == 31)
  563. bprint(i, "\tR%d,R%d", i->rb, i->ra);
  564. else
  565. bprint(i, "\t$%d,R%d", i->simm, i->ra);
  566. if(i->ra != i->rd)
  567. bprint(i, ",R%d", i->rd);
  568. }
  569. static void
  570. and(Opcode *o, Instr *i)
  571. {
  572. if (i->op == 31) {
  573. /* Rb,Rs,Ra */
  574. if (i->ra == i->rs)
  575. format(o->mnemonic, i, "R%b,R%a");
  576. else if (i->ra == i->rb)
  577. format(o->mnemonic, i, "R%s,R%a");
  578. else
  579. format(o->mnemonic, i, o->ken);
  580. } else {
  581. /* imm,Rs,Ra */
  582. if (i->ra == i->rs)
  583. format(o->mnemonic, i, "%I,R%a");
  584. else
  585. format(o->mnemonic, i, o->ken);
  586. }
  587. }
  588. static void
  589. or(Opcode *o, Instr *i)
  590. {
  591. if (i->op == 31) {
  592. /* Rb,Rs,Ra */
  593. if (i->rs == 0 && i->ra == 0 && i->rb == 0)
  594. format("NOP", i, nil);
  595. else if (i->rs == i->rb)
  596. format("MOVW", i, "R%b,R%a");
  597. else
  598. and(o, i);
  599. } else
  600. and(o, i);
  601. }
  602. static void
  603. shifted(Opcode *o, Instr *i)
  604. {
  605. format(o->mnemonic, i, nil);
  606. bprint(i, "\t$%lux,", (uint32_t)i->uimm<<16);
  607. if (i->rs == i->ra)
  608. bprint(i, "R%d", i->ra);
  609. else
  610. bprint(i, "R%d,R%d", i->rs, i->ra);
  611. }
  612. static void
  613. neg(Opcode *o, Instr *i)
  614. {
  615. if (i->rd == i->ra)
  616. format(o->mnemonic, i, "R%d");
  617. else
  618. format(o->mnemonic, i, o->ken);
  619. }
  620. static char ir2[] = "R%a,R%d"; /* reverse of IBM order */
  621. static char ir3[] = "R%b,R%a,R%d";
  622. static char ir3r[] = "R%a,R%b,R%d";
  623. static char il3[] = "R%b,R%s,R%a";
  624. static char il2u[] = "%I,R%d,R%a";
  625. static char il3s[] = "$%k,R%s,R%a";
  626. static char il2[] = "R%s,R%a";
  627. static char icmp3[] = "R%a,R%b,%D";
  628. static char cr3op[] = "%b,%a,%d";
  629. static char ir2i[] = "%i,R%a,R%d";
  630. static char fp2[] = "F%b,F%d";
  631. static char fp3[] = "F%b,F%a,F%d";
  632. static char fp3c[] = "F%c,F%a,F%d";
  633. static char fp4[] = "F%a,F%c,F%b,F%d";
  634. static char fpcmp[] = "F%a,F%b,%D";
  635. static char ldop[] = "%l,R%d";
  636. static char stop[] = "R%d,%l";
  637. static char fldop[] = "%l,F%d";
  638. static char fstop[] = "F%d,%l";
  639. static char rldc[] = "R%b,R%s,$%E,R%a";
  640. static char rlim[] = "R%b,R%s,$%z,R%a";
  641. static char rlimi[] = "$%k,R%s,$%z,R%a";
  642. static char rldi[] = "$%e,R%s,$%E,R%a";
  643. #define OEM IBF(~0,22,30)
  644. #define FP4 IBF(~0,26,30)
  645. #define ALL (~0)
  646. #define RLDC 0xF
  647. #define RLDI 0xE
  648. /*
  649. notes:
  650. 10-26: crfD = rD>>2; rD&3 mbz
  651. also, L bit (bit 10) mbz or selects 64-bit operands
  652. */
  653. static Opcode opcodes[] = {
  654. {31, 266, OEM, "ADD%V%C", add, ir3},
  655. {31, 10, OEM, "ADDC%V%C", add, ir3},
  656. {31, 138, OEM, "ADDE%V%C", add, ir3},
  657. {14, 0, 0, "ADD", addi, ir2i},
  658. {12, 0, 0, "ADDC", addi, ir2i},
  659. {13, 0, 0, "ADDCCC", addi, ir2i},
  660. {15, 0, 0, "ADD", addis, 0},
  661. {31, 234, OEM, "ADDME%V%C", gencc, ir2},
  662. {31, 202, OEM, "ADDZE%V%C", gencc, ir2},
  663. {31, 28, ALL, "AND%C", and, il3},
  664. {31, 60, ALL, "ANDN%C", and, il3},
  665. {28, 0, 0, "ANDCC", andi, il2u},
  666. {29, 0, 0, "ANDCC", shifted, 0},
  667. {18, 0, 0, "B%L", gencc, "%j"},
  668. {16, 0, 0, "BC%L", branch, "%d,%a,%J"},
  669. {19, 528, ALL, "BC%L", branch, "%d,%a,(CTR)"},
  670. {19, 16, ALL, "BC%L", branch, "%d,%a,(LR)"},
  671. {31, 0, ALL, "CMP", 0, icmp3},
  672. {11, 0, 0, "CMP", 0, "R%a,%i,%D"},
  673. {31, 32, ALL, "CMPU", 0, icmp3},
  674. {10, 0, 0, "CMPU", 0, "R%a,%I,%D"},
  675. {31, 58, ALL, "CNTLZD%C", gencc, ir2}, /* 64 */
  676. {31, 26, ALL, "CNTLZ%W%C", gencc, ir2},
  677. {19, 257, ALL, "CRAND", gen, cr3op},
  678. {19, 129, ALL, "CRANDN", gen, cr3op},
  679. {19, 289, ALL, "CREQV", gen, cr3op},
  680. {19, 225, ALL, "CRNAND", gen, cr3op},
  681. {19, 33, ALL, "CRNOR", gen, cr3op},
  682. {19, 449, ALL, "CROR", gen, cr3op},
  683. {19, 417, ALL, "CRORN", gen, cr3op},
  684. {19, 193, ALL, "CRXOR", gen, cr3op},
  685. {31, 86, ALL, "DCBF", dcb, 0},
  686. {31, 470, ALL, "DCBI", dcb, 0},
  687. {31, 54, ALL, "DCBST", dcb, 0},
  688. {31, 278, ALL, "DCBT", dcb, 0},
  689. {31, 246, ALL, "DCBTST", dcb, 0},
  690. {31, 1014, ALL, "DCBZ", dcb, 0},
  691. {31, 454, ALL, "DCCCI", dcb, 0},
  692. {31, 966, ALL, "ICCCI", dcb, 0},
  693. {31, 489, OEM, "DIVD%V%C", qdiv, ir3}, /* 64 */
  694. {31, 457, OEM, "DIVDU%V%C", qdiv, ir3}, /* 64 */
  695. {31, 491, OEM, "DIVW%V%C", qdiv, ir3},
  696. {31, 459, OEM, "DIVWU%V%C", qdiv, ir3},
  697. {31, 310, ALL, "ECIWX", ldx, 0},
  698. {31, 438, ALL, "ECOWX", stx, 0},
  699. {31, 854, ALL, "EIEIO", gen, 0},
  700. {31, 284, ALL, "EQV%C", gencc, il3},
  701. {31, 954, ALL, "EXTSB%C", gencc, il2},
  702. {31, 922, ALL, "EXTSH%C", gencc, il2},
  703. {31, 986, ALL, "EXTSW%C", gencc, il2}, /* 64 */
  704. {63, 264, ALL, "FABS%C", gencc, fp2},
  705. {63, 21, ALL, "FADD%C", gencc, fp3},
  706. {59, 21, ALL, "FADDS%C", gencc, fp3},
  707. {63, 32, ALL, "FCMPO", gen, fpcmp},
  708. {63, 0, ALL, "FCMPU", gen, fpcmp},
  709. {63, 846, ALL, "FCFID%C", gencc, fp2}, /* 64 */
  710. {63, 814, ALL, "FCTID%C", gencc, fp2}, /* 64 */
  711. {63, 815, ALL, "FCTIDZ%C", gencc, fp2}, /* 64 */
  712. {63, 14, ALL, "FCTIW%C", gencc, fp2},
  713. {63, 15, ALL, "FCTIWZ%C", gencc, fp2},
  714. {63, 18, ALL, "FDIV%C", gencc, fp3},
  715. {59, 18, ALL, "FDIVS%C", gencc, fp3},
  716. {63, 29, FP4, "FMADD%C", gencc, fp4},
  717. {59, 29, FP4, "FMADDS%C", gencc, fp4},
  718. {63, 72, ALL, "FMOVD%C", gencc, fp2},
  719. {63, 28, FP4, "FMSUB%C", gencc, fp4},
  720. {59, 28, FP4, "FMSUBS%C", gencc, fp4},
  721. {63, 25, FP4, "FMUL%C", gencc, fp3c},
  722. {59, 25, FP4, "FMULS%C", gencc, fp3c},
  723. {63, 136, ALL, "FNABS%C", gencc, fp2},
  724. {63, 40, ALL, "FNEG%C", gencc, fp2},
  725. {63, 31, FP4, "FNMADD%C", gencc, fp4},
  726. {59, 31, FP4, "FNMADDS%C", gencc, fp4},
  727. {63, 30, FP4, "FNMSUB%C", gencc, fp4},
  728. {59, 30, FP4, "FNMSUBS%C", gencc, fp4},
  729. {59, 24, ALL, "FRES%C", gencc, fp2}, /* optional */
  730. {63, 12, ALL, "FRSP%C", gencc, fp2},
  731. {63, 26, ALL, "FRSQRTE%C", gencc, fp2}, /* optional */
  732. {63, 23, FP4, "FSEL%CC", gencc, fp4}, /* optional */
  733. {63, 22, ALL, "FSQRT%C", gencc, fp2}, /* optional */
  734. {59, 22, ALL, "FSQRTS%C", gencc, fp2}, /* optional */
  735. {63, 20, FP4, "FSUB%C", gencc, fp3},
  736. {59, 20, FP4, "FSUBS%C", gencc, fp3},
  737. {31, 982, ALL, "ICBI", dcb, 0}, /* optional */
  738. {19, 150, ALL, "ISYNC", gen, 0},
  739. {34, 0, 0, "MOVBZ", load, ldop},
  740. {35, 0, 0, "MOVBZU", load, ldop},
  741. {31, 119, ALL, "MOVBZU", ldx, 0},
  742. {31, 87, ALL, "MOVBZ", ldx, 0},
  743. {50, 0, 0, "FMOVD", fload, fldop},
  744. {51, 0, 0, "FMOVDU", fload, fldop},
  745. {31, 631, ALL, "FMOVDU", fldx, 0},
  746. {31, 599, ALL, "FMOVD", fldx, 0},
  747. {48, 0, 0, "FMOVS", load, fldop},
  748. {49, 0, 0, "FMOVSU", load, fldop},
  749. {31, 567, ALL, "FMOVSU", fldx, 0},
  750. {31, 535, ALL, "FMOVS", fldx, 0},
  751. {42, 0, 0, "MOVH", load, ldop},
  752. {43, 0, 0, "MOVHU", load, ldop},
  753. {31, 375, ALL, "MOVHU", ldx, 0},
  754. {31, 343, ALL, "MOVH", ldx, 0},
  755. {31, 790, ALL, "MOVHBR", ldx, 0},
  756. {40, 0, 0, "MOVHZ", load, ldop},
  757. {41, 0, 0, "MOVHZU", load, ldop},
  758. {31, 311, ALL, "MOVHZU", ldx, 0},
  759. {31, 279, ALL, "MOVHZ", ldx, 0},
  760. {46, 0, 0, "MOVMW", load, ldop},
  761. {31, 597, ALL, "LSW", gen, "(R%a),$%n,R%d"},
  762. {31, 533, ALL, "LSW", ldx, 0},
  763. {31, 20, ALL, "LWAR", ldx, 0},
  764. {31, 84, ALL, "LWARD", ldx, 0}, /* 64 */
  765. {58, 0, ALL, "MOVD", load, ldop}, /* 64 */
  766. {58, 1, ALL, "MOVDU", load, ldop}, /* 64 */
  767. {31, 53, ALL, "MOVDU", ldx, 0}, /* 64 */
  768. {31, 21, ALL, "MOVD", ldx, 0}, /* 64 */
  769. {31, 534, ALL, "MOVWBR", ldx, 0},
  770. {58, 2, ALL, "MOVW", load, ldop}, /* 64 (lwa) */
  771. {31, 373, ALL, "MOVWU", ldx, 0}, /* 64 */
  772. {31, 341, ALL, "MOVW", ldx, 0}, /* 64 */
  773. {32, 0, 0, "MOVW%Z", load, ldop},
  774. {33, 0, 0, "MOVW%ZU", load, ldop},
  775. {31, 55, ALL, "MOVW%ZU", ldx, 0},
  776. {31, 23, ALL, "MOVW%Z", ldx, 0},
  777. {19, 0, ALL, "MOVFL", gen, "%S,%D"},
  778. {63, 64, ALL, "MOVCRFS", gen, "%S,%D"},
  779. {31, 512, ALL, "MOVW", gen, "XER,%D"},
  780. {31, 19, ALL, "MOVW", gen, "CR,R%d"},
  781. {63, 583, ALL, "MOVW%C", gen, "FPSCR, F%d"}, /* mffs */
  782. {31, 83, ALL, "MOVW", gen, "MSR,R%d"},
  783. {31, 339, ALL, "MOVW", gen, "%P,R%d"},
  784. {31, 595, ALL, "MOVW", gen, "SEG(%a),R%d"},
  785. {31, 659, ALL, "MOVW", gen, "SEG(R%b),R%d"},
  786. {31, 323, ALL, "MOVW", gen, "DCR(%Q),R%d"},
  787. {31, 451, ALL, "MOVW", gen, "R%s,DCR(%Q)"},
  788. {31, 259, ALL, "MOVW", gen, "DCR(R%a),R%d"},
  789. {31, 387, ALL, "MOVW", gen, "R%s,DCR(R%a)"},
  790. {31, 144, ALL, "MOVFL", gen, "R%s,%m,CR"},
  791. {63, 70, ALL, "MTFSB0%C", gencc, "%D"},
  792. {63, 38, ALL, "MTFSB1%C", gencc, "%D"},
  793. {63, 711, ALL, "MOVFL%C", gencc, "F%b,%M,FPSCR"}, /* mtfsf */
  794. {63, 134, ALL, "MOVFL%C", gencc, "%K,%D"},
  795. {31, 146, ALL, "MOVW", gen, "R%s,MSR"},
  796. {31, 178, ALL, "MOVD", gen, "R%s,MSR"},
  797. {31, 467, ALL, "MOVW", gen, "R%s,%P"},
  798. {31, 210, ALL, "MOVW", gen, "R%s,SEG(%a)"},
  799. {31, 242, ALL, "MOVW", gen, "R%s,SEG(R%b)"},
  800. {31, 73, ALL, "MULHD%C", gencc, ir3},
  801. {31, 9, ALL, "MULHDU%C", gencc, ir3},
  802. {31, 233, OEM, "MULLD%V%C", gencc, ir3},
  803. {31, 75, ALL, "MULHW%C", gencc, ir3},
  804. {31, 11, ALL, "MULHWU%C", gencc, ir3},
  805. {31, 235, OEM, "MULLW%V%C", gencc, ir3},
  806. {7, 0, 0, "MULLW", qdiv, "%i,R%a,R%d"},
  807. {31, 476, ALL, "NAND%C", gencc, il3},
  808. {31, 104, OEM, "NEG%V%C", neg, ir2},
  809. {31, 124, ALL, "NOR%C", gencc, il3},
  810. {31, 444, ALL, "OR%C", or, il3},
  811. {31, 412, ALL, "ORN%C", or, il3},
  812. {24, 0, 0, "OR", and, "%I,R%d,R%a"},
  813. {25, 0, 0, "OR", shifted, 0},
  814. {19, 50, ALL, "RFI", gen, 0},
  815. {19, 51, ALL, "RFCI", gen, 0},
  816. {30, 8, RLDC, "RLDCL%C", gencc, rldc}, /* 64 */
  817. {30, 9, RLDC, "RLDCR%C", gencc, rldc}, /* 64 */
  818. {30, 0, RLDI, "RLDCL%C", gencc, rldi}, /* 64 */
  819. {30, 1<<1, RLDI, "RLDCR%C", gencc, rldi}, /* 64 */
  820. {30, 2<<1, RLDI, "RLDC%C", gencc, rldi}, /* 64 */
  821. {30, 3<<1, RLDI, "RLDMI%C", gencc, rldi}, /* 64 */
  822. {20, 0, 0, "RLWMI%C", gencc, rlimi},
  823. {21, 0, 0, "RLWNM%C", gencc, rlimi},
  824. {23, 0, 0, "RLWNM%C", gencc, rlim},
  825. {17, 1, ALL, "SYSCALL", gen, 0},
  826. {31, 27, ALL, "SLD%C", shift, il3}, /* 64 */
  827. {31, 24, ALL, "SLW%C", shift, il3},
  828. {31, 794, ALL, "SRAD%C", shift, il3}, /* 64 */
  829. {31, (413<<1)|0, ALL, "SRAD%C", shifti, il3s}, /* 64 */
  830. {31, (413<<1)|1, ALL, "SRAD%C", shifti, il3s}, /* 64 */
  831. {31, 792, ALL, "SRAW%C", shift, il3},
  832. {31, 824, ALL, "SRAW%C", shifti, il3s},
  833. {31, 539, ALL, "SRD%C", shift, il3}, /* 64 */
  834. {31, 536, ALL, "SRW%C", shift, il3},
  835. {38, 0, 0, "MOVB", store, stop},
  836. {39, 0, 0, "MOVBU", store, stop},
  837. {31, 247, ALL, "MOVBU", stx, 0},
  838. {31, 215, ALL, "MOVB", stx, 0},
  839. {54, 0, 0, "FMOVD", fstore, fstop},
  840. {55, 0, 0, "FMOVDU", fstore, fstop},
  841. {31, 759, ALL, "FMOVDU", fstx, 0},
  842. {31, 727, ALL, "FMOVD", fstx, 0},
  843. {52, 0, 0, "FMOVS", fstore, fstop},
  844. {53, 0, 0, "FMOVSU", fstore, fstop},
  845. {31, 695, ALL, "FMOVSU", fstx, 0},
  846. {31, 663, ALL, "FMOVS", fstx, 0},
  847. {44, 0, 0, "MOVH", store, stop},
  848. {31, 918, ALL, "MOVHBR", stx, 0},
  849. {45, 0, 0, "MOVHU", store, stop},
  850. {31, 439, ALL, "MOVHU", stx, 0},
  851. {31, 407, ALL, "MOVH", stx, 0},
  852. {47, 0, 0, "MOVMW", store, stop},
  853. {31, 725, ALL, "STSW", gen, "R%d,$%n,(R%a)"},
  854. {31, 661, ALL, "STSW", stx, 0},
  855. {36, 0, 0, "MOVW", store, stop},
  856. {31, 662, ALL, "MOVWBR", stx, 0},
  857. {31, 150, ALL, "STWCCC", stx, 0},
  858. {31, 214, ALL, "STDCCC", stx, 0}, /* 64 */
  859. {37, 0, 0, "MOVWU", store, stop},
  860. {31, 183, ALL, "MOVWU", stx, 0},
  861. {31, 151, ALL, "MOVW", stx, 0},
  862. {62, 0, 0, "MOVD%U", store, stop}, /* 64 */
  863. {31, 149, ALL, "MOVD", stx, 0,}, /* 64 */
  864. {31, 181, ALL, "MOVDU", stx, 0}, /* 64 */
  865. {31, 498, ALL, "SLBIA", gen, 0}, /* 64 */
  866. {31, 434, ALL, "SLBIE", gen, "R%b"}, /* 64 */
  867. {31, 466, ALL, "SLBIEX", gen, "R%b"}, /* 64 */
  868. {31, 915, ALL, "SLBMFEE", gen, "R%b,R%d"}, /* 64 */
  869. {31, 851, ALL, "SLBMFEV", gen, "R%b,R%d"}, /* 64 */
  870. {31, 402, ALL, "SLBMTE", gen, "R%s,R%b"}, /* 64 */
  871. {31, 40, OEM, "SUB%V%C", sub, ir3},
  872. {31, 8, OEM, "SUBC%V%C", sub, ir3},
  873. {31, 136, OEM, "SUBE%V%C", sub, ir3},
  874. {8, 0, 0, "SUBC", gen, "R%a,%i,R%d"},
  875. {31, 232, OEM, "SUBME%V%C", sub, ir2},
  876. {31, 200, OEM, "SUBZE%V%C", sub, ir2},
  877. {31, 598, ALL, "SYNC", gen, 0}, /* TO DO: there's a parameter buried in there */
  878. {2, 0, 0, "TD", gen, "%d,R%a,%i"}, /* 64 */
  879. {31, 370, ALL, "TLBIA", gen, 0}, /* optional */
  880. {31, 306, ALL, "TLBIE", gen, "R%b"}, /* optional */
  881. {31, 274, ALL, "TLBIEL", gen, "R%b"}, /* optional */
  882. {31, 1010, ALL, "TLBLI", gen, "R%b"}, /* optional */
  883. {31, 978, ALL, "TLBLD", gen, "R%b"}, /* optional */
  884. {31, 566, ALL, "TLBSYNC", gen, 0}, /* optional */
  885. {31, 68, ALL, "TD", gen, "%d,R%a,R%b"}, /* 64 */
  886. {31, 4, ALL, "TW", gen, "%d,R%a,R%b"},
  887. {3, 0, 0, "TW", gen, "%d,R%a,%i"},
  888. {31, 316, ALL, "XOR", and, il3},
  889. {26, 0, 0, "XOR", and, il2u},
  890. {27, 0, 0, "XOR", shifted, 0},
  891. {0},
  892. };
  893. typedef struct Spr Spr;
  894. struct Spr {
  895. int n;
  896. char *name;
  897. };
  898. static Spr sprname[] = {
  899. {0, "MQ"},
  900. {1, "XER"},
  901. {268, "TBL"},
  902. {269, "TBU"},
  903. {8, "LR"},
  904. {9, "CTR"},
  905. {528, "IBAT0U"},
  906. {529, "IBAT0L"},
  907. {530, "IBAT1U"},
  908. {531, "IBAT1L"},
  909. {532, "IBAT2U"},
  910. {533, "IBAT2L"},
  911. {534, "IBAT3U"},
  912. {535, "IBAT3L"},
  913. {536, "DBAT0U"},
  914. {537, "DBAT0L"},
  915. {538, "DBAT1U"},
  916. {539, "DBAT1L"},
  917. {540, "DBAT2U"},
  918. {541, "DBAT2L"},
  919. {542, "DBAT3U"},
  920. {543, "DBAT3L"},
  921. {25, "SDR1"},
  922. {19, "DAR"},
  923. {272, "SPRG0"},
  924. {273, "SPRG1"},
  925. {274, "SPRG2"},
  926. {275, "SPRG3"},
  927. {18, "DSISR"},
  928. {26, "SRR0"},
  929. {27, "SRR1"},
  930. {284, "TBLW"},
  931. {285, "TBUW"},
  932. {22, "DEC"},
  933. {282, "EAR"},
  934. {1008, "HID0"},
  935. {1009, "HID1"},
  936. {976, "DMISS"},
  937. {977, "DCMP"},
  938. {978, "HASH1"},
  939. {979, "HASH2"},
  940. {980, "IMISS"},
  941. {981, "ICMP"},
  942. {982, "RPA"},
  943. {1010, "IABR"},
  944. {1013, "DABR"},
  945. {0,0},
  946. };
  947. static int
  948. shmask(uint64_t *m)
  949. {
  950. int i;
  951. for(i=0; i<63; i++)
  952. if(*m & ((uint64_t)1<<i))
  953. break;
  954. if(i > 63)
  955. return 0;
  956. if(*m & ~((uint64_t)1<<i)){ /* more than one bit: do multiples of bytes */
  957. i = (i/8)*8;
  958. if(i == 0)
  959. return 0;
  960. }
  961. *m >>= i;
  962. return i;
  963. }
  964. static void
  965. format(char *mnemonic, Instr *i, char *f)
  966. {
  967. int n, s;
  968. uint32_t mask;
  969. uint64_t vmask;
  970. if (mnemonic)
  971. format(0, i, mnemonic);
  972. if (f == 0)
  973. return;
  974. if (mnemonic)
  975. bprint(i, "\t");
  976. for ( ; *f; f++) {
  977. if (*f != '%') {
  978. bprint(i, "%c", *f);
  979. continue;
  980. }
  981. switch (*++f) {
  982. case 'a':
  983. bprint(i, "%d", i->ra);
  984. break;
  985. case 'b':
  986. bprint(i, "%d", i->rb);
  987. break;
  988. case 'c':
  989. bprint(i, "%d", i->frc);
  990. break;
  991. case 'd':
  992. case 's':
  993. bprint(i, "%d", i->rd);
  994. break;
  995. case 'C':
  996. if(i->rc)
  997. bprint(i, "CC");
  998. break;
  999. case 'D':
  1000. if(i->rd & 3)
  1001. bprint(i, "CR(INVAL:%d)", i->rd);
  1002. else if(i->op == 63)
  1003. bprint(i, "FPSCR(%d)", i->crfd);
  1004. else
  1005. bprint(i, "CR(%d)", i->crfd);
  1006. break;
  1007. case 'e':
  1008. bprint(i, "%d", i->xsh);
  1009. break;
  1010. case 'E':
  1011. switch(IBF(i->w0,27,30)){ /* low bit is top bit of shift in rldiX cases */
  1012. case 8: i->mb = i->xmbe; i->me = 63; break; /* rldcl */
  1013. case 9: i->mb = 0; i->me = i->xmbe; break; /* rldcr */
  1014. case 4: case 5:
  1015. i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldic */
  1016. case 0: case 1:
  1017. i->mb = i->xmbe; i->me = 63; break; /* rldicl */
  1018. case 2: case 3:
  1019. i->mb = 0; i->me = i->xmbe; break; /* rldicr */
  1020. case 6: case 7:
  1021. i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldimi */
  1022. }
  1023. vmask = (~(uint64_t)0>>i->mb) & (~(uint64_t)0<<(63-i->me));
  1024. s = shmask(&vmask);
  1025. if(s)
  1026. bprint(i, "(%llux<<%d)", vmask, s);
  1027. else
  1028. bprint(i, "%llux", vmask);
  1029. break;
  1030. case 'i':
  1031. bprint(i, "$%d", i->simm);
  1032. break;
  1033. case 'I':
  1034. bprint(i, "$%ux", i->uimm);
  1035. break;
  1036. case 'j':
  1037. if(i->aa)
  1038. pglobal(i, i->li, 1, "(SB)");
  1039. else
  1040. pglobal(i, i->addr+i->li, 1, "");
  1041. break;
  1042. case 'J':
  1043. if(i->aa)
  1044. pglobal(i, i->bd, 1, "(SB)");
  1045. else
  1046. pglobal(i, i->addr+i->bd, 1, "");
  1047. break;
  1048. case 'k':
  1049. bprint(i, "%d", i->sh);
  1050. break;
  1051. case 'K':
  1052. bprint(i, "$%x", i->imm);
  1053. break;
  1054. case 'L':
  1055. if(i->lk)
  1056. bprint(i, "L");
  1057. break;
  1058. case 'l':
  1059. if(i->simm < 0)
  1060. bprint(i, "-%x(R%d)", -i->simm, i->ra);
  1061. else
  1062. bprint(i, "%x(R%d)", i->simm, i->ra);
  1063. break;
  1064. case 'm':
  1065. bprint(i, "%ux", i->crm);
  1066. break;
  1067. case 'M':
  1068. bprint(i, "%ux", i->fm);
  1069. break;
  1070. case 'n':
  1071. bprint(i, "%d", i->nb==0? 32: i->nb); /* eg, pg 10-103 */
  1072. break;
  1073. case 'P':
  1074. n = ((i->spr&0x1f)<<5)|((i->spr>>5)&0x1f);
  1075. for(s=0; sprname[s].name; s++)
  1076. if(sprname[s].n == n)
  1077. break;
  1078. if(sprname[s].name) {
  1079. if(s < 10)
  1080. bprint(i, sprname[s].name);
  1081. else
  1082. bprint(i, "SPR(%s)", sprname[s].name);
  1083. } else
  1084. bprint(i, "SPR(%d)", n);
  1085. break;
  1086. case 'Q':
  1087. n = ((i->spr&0x1f)<<5)|((i->spr>>5)&0x1f);
  1088. bprint(i, "%d", n);
  1089. break;
  1090. case 'S':
  1091. if(i->ra & 3)
  1092. bprint(i, "CR(INVAL:%d)", i->ra);
  1093. else if(i->op == 63)
  1094. bprint(i, "FPSCR(%d)", i->crfs);
  1095. else
  1096. bprint(i, "CR(%d)", i->crfs);
  1097. break;
  1098. case 'U':
  1099. if(i->rc)
  1100. bprint(i, "U");
  1101. break;
  1102. case 'V':
  1103. if(i->oe)
  1104. bprint(i, "V");
  1105. break;
  1106. case 'w':
  1107. bprint(i, "[%lux]", i->w0);
  1108. break;
  1109. case 'W':
  1110. if(i->m64)
  1111. bprint(i, "W");
  1112. break;
  1113. case 'Z':
  1114. if(i->m64)
  1115. bprint(i, "Z");
  1116. break;
  1117. case 'z':
  1118. if(i->mb <= i->me)
  1119. mask = ((uint32_t)~0L>>i->mb) & (~0L<<(31-i->me));
  1120. else
  1121. mask = ~(((uint32_t)~0L>>(i->me+1)) & (~0L<<(31-(i->mb-1))));
  1122. bprint(i, "%lux", mask);
  1123. break;
  1124. case '\0':
  1125. bprint(i, "%%");
  1126. return;
  1127. default:
  1128. bprint(i, "%%%c", *f);
  1129. break;
  1130. }
  1131. }
  1132. }
  1133. static int
  1134. printins(Map *map, uint64_t pc, char *buf, int n)
  1135. {
  1136. Instr i;
  1137. Opcode *o;
  1138. mymap = map;
  1139. memset(&i, 0, sizeof(i));
  1140. i.curr = buf;
  1141. i.end = buf+n-1;
  1142. if(mkinstr(pc, &i) < 0)
  1143. return -1;
  1144. for(o = opcodes; o->mnemonic != 0; o++)
  1145. if(i.op == o->op && (i.xo & o->xomask) == o->xo) {
  1146. if (o->f)
  1147. (*o->f)(o, &i);
  1148. else
  1149. format(o->mnemonic, &i, o->ken);
  1150. return i.size*4;
  1151. }
  1152. bprint(&i, "unknown %lux", i.w0);
  1153. return i.size*4;
  1154. }
  1155. static int
  1156. powerinst(Map *map, uint64_t pc, char modifier, char *buf, int n)
  1157. {
  1158. USED(modifier);
  1159. return printins(map, pc, buf, n);
  1160. }
  1161. static int
  1162. powerdas(Map *map, uint64_t pc, char *buf, int n)
  1163. {
  1164. Instr instr;
  1165. mymap = map;
  1166. memset(&instr, 0, sizeof(instr));
  1167. instr.curr = buf;
  1168. instr.end = buf+n-1;
  1169. if (mkinstr(pc, &instr) < 0)
  1170. return -1;
  1171. if (instr.end-instr.curr > 8)
  1172. instr.curr = _hexify(instr.curr, instr.w0, 7);
  1173. if (instr.end-instr.curr > 9 && instr.size == 2) {
  1174. *instr.curr++ = ' ';
  1175. instr.curr = _hexify(instr.curr, instr.w1, 7);
  1176. }
  1177. *instr.curr = 0;
  1178. return instr.size*4;
  1179. }
  1180. static int
  1181. powerinstlen(Map *map, uint64_t pc)
  1182. {
  1183. Instr i;
  1184. mymap = map;
  1185. if (mkinstr(pc, &i) < 0)
  1186. return -1;
  1187. return i.size*4;
  1188. }
  1189. static int
  1190. powerfoll(Map *map, uint64_t pc, Rgetter rget, uint64_t *foll)
  1191. {
  1192. char *reg;
  1193. Instr i;
  1194. mymap = map;
  1195. if (mkinstr(pc, &i) < 0)
  1196. return -1;
  1197. foll[0] = pc+4;
  1198. foll[1] = pc+4;
  1199. switch(i.op) {
  1200. default:
  1201. return 1;
  1202. case 18: /* branch */
  1203. foll[0] = i.li;
  1204. if(!i.aa)
  1205. foll[0] += pc;
  1206. break;
  1207. case 16: /* conditional branch */
  1208. foll[0] = i.bd;
  1209. if(!i.aa)
  1210. foll[0] += pc;
  1211. break;
  1212. case 19: /* conditional branch to register */
  1213. if(i.xo == 528)
  1214. reg = "CTR";
  1215. else if(i.xo == 16)
  1216. reg = "LR";
  1217. else
  1218. return 1; /* not a branch */
  1219. foll[0] = (*rget)(map, reg);
  1220. break;
  1221. }
  1222. if(i.lk)
  1223. return 2;
  1224. return 1;
  1225. }