asm.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429
  1. #include "l.h"
  2. /* can't include a.out.h due to name clashes, but these are taken from it */
  3. #define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7))
  4. #define V_MAGIC _MAGIC(0, 16) /* mips 3000 BE */
  5. #define M_MAGIC _MAGIC(0, 18) /* mips 4000 BE */
  6. #define N_MAGIC _MAGIC(0, 22) /* mips 4000 LE */
  7. #define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */
  8. long OFFSET;
  9. /*
  10. long BADOFFSET = -1;
  11. if(OFFSET <= BADOFFSET && OFFSET+4 > BADOFFSET)\
  12. abort();\
  13. OFFSET += 4;\
  14. if(OFFSET == BADOFFSET)\
  15. abort();\
  16. OFFSET++;\
  17. */
  18. #define LPUT(l) { \
  19. if (little) { \
  20. LLEPUT(l); \
  21. } else { \
  22. LBEPUT(l); \
  23. } \
  24. }
  25. #define LLEPUT(c)\
  26. {\
  27. cbp[0] = (c);\
  28. cbp[1] = (c)>>8;\
  29. cbp[2] = (c)>>16;\
  30. cbp[3] = (c)>>24;\
  31. cbp += 4;\
  32. cbc -= 4;\
  33. if(cbc <= 0)\
  34. cflush();\
  35. }
  36. #define LBEPUT(c)\
  37. {\
  38. cbp[0] = (c)>>24;\
  39. cbp[1] = (c)>>16;\
  40. cbp[2] = (c)>>8;\
  41. cbp[3] = (c);\
  42. cbp += 4;\
  43. cbc -= 4;\
  44. if(cbc <= 0)\
  45. cflush();\
  46. }
  47. #define HPUT(h) { \
  48. if (little) { \
  49. HLEPUT(h); \
  50. } else { \
  51. HBEPUT(h); \
  52. } \
  53. }
  54. #define HLEPUT(c)\
  55. {\
  56. cbp[0] = (c);\
  57. cbp[1] = (c)>>8;\
  58. cbp += 2;\
  59. cbc -= 2;\
  60. if(cbc <= 0)\
  61. cflush();\
  62. }
  63. #define HBEPUT(c)\
  64. {\
  65. cbp[0] = (c)>>8;\
  66. cbp[1] = (c);\
  67. cbp += 2;\
  68. cbc -= 2;\
  69. if(cbc <= 0)\
  70. cflush();\
  71. }
  72. #define CPUT(c)\
  73. {\
  74. cbp[0] = (c);\
  75. cbp++;\
  76. cbc--;\
  77. if(cbc <= 0)\
  78. cflush();\
  79. }
  80. void
  81. cput(long l)
  82. {
  83. CPUT(l);
  84. }
  85. void
  86. objput(long l) /* emit long in byte order appropriate to object machine */
  87. {
  88. LPUT(l);
  89. }
  90. void
  91. objhput(short s)
  92. {
  93. HPUT(s);
  94. }
  95. void
  96. wput(long l)
  97. {
  98. cbp[0] = l>>8;
  99. cbp[1] = l;
  100. cbp += 2;
  101. cbc -= 2;
  102. if(cbc <= 0)
  103. cflush();
  104. }
  105. void
  106. wputl(long l)
  107. {
  108. cbp[0] = l;
  109. cbp[1] = l>>8;
  110. cbp += 2;
  111. cbc -= 2;
  112. if(cbc <= 0)
  113. cflush();
  114. }
  115. void
  116. lput(long l) /* emit long in big-endian byte order */
  117. {
  118. LBEPUT(l);
  119. }
  120. void
  121. lputl(long l) /* emit long in big-endian byte order */
  122. {
  123. LLEPUT(l);
  124. }
  125. void
  126. llput(vlong v)
  127. {
  128. lput(v>>32);
  129. lput(v);
  130. }
  131. void
  132. llputl(vlong v)
  133. {
  134. lputl(v);
  135. lputl(v>>32);
  136. }
  137. long
  138. entryvalue(void)
  139. {
  140. char *a;
  141. Sym *s;
  142. a = INITENTRY;
  143. if(*a >= '0' && *a <= '9')
  144. return atolwhex(a);
  145. s = lookup(a, 0);
  146. if(s->type == 0)
  147. return INITTEXT;
  148. if(s->type != STEXT && s->type != SLEAF)
  149. diag("entry not text: %s", s->name);
  150. return s->value;
  151. }
  152. static void
  153. plan9bootimage(ulong sects, ulong submagicvers, ulong tm,
  154. ulong hdrtxtsz, ulong textsz, ulong textva, ulong lcsize)
  155. {
  156. lput(0x160L<<16|sects); /* magic and sections */
  157. lput(tm); /* time and date */
  158. lput(hdrtxtsz+datsize); /* offset to symbol table */
  159. lput(symsize); /* size of symbol table */
  160. lput((0x38L<<16)|7L); /* size of optional hdr and flags */
  161. lput(submagicvers); /* magic and version */
  162. lput(textsz); /* segment sizes */
  163. lput(datsize);
  164. lput(bsssize);
  165. lput(entryvalue()); /* va of entry */
  166. lput(textva); /* va of base of text */
  167. lput(INITDAT); /* va of base of data */
  168. lput(INITDAT+datsize); /* va of base of bss */
  169. lput(~0); /* gp reg mask */
  170. lput(lcsize); /* pcsize / cprmask[0] */
  171. lput(0); /* coproc reg masks[1⋯3] */
  172. lput(0);
  173. lput(0);
  174. lput(~0); /* gp value ?? */
  175. }
  176. static void
  177. symhdrs(ulong hdrtxtsz)
  178. {
  179. strnput(".text", 8); /* text segment */
  180. lput(INITTEXT); /* address */
  181. lput(INITTEXT);
  182. lput(textsize);
  183. lput(HEADR);
  184. lput(0);
  185. lput(HEADR+textsize+datsize+symsize);
  186. lput(lcsize); /* line number size */
  187. lput(0x20); /* flags */
  188. strnput(".data", 8); /* data segment */
  189. lput(INITDAT); /* address */
  190. lput(INITDAT);
  191. lput(datsize);
  192. lput(hdrtxtsz);
  193. lput(0);
  194. lput(0);
  195. lput(0);
  196. lput(0x40); /* flags */
  197. strnput(".bss", 8); /* bss segment */
  198. lput(INITDAT+datsize); /* address */
  199. lput(INITDAT+datsize);
  200. lput(bsssize);
  201. lput(0);
  202. lput(0);
  203. lput(0);
  204. lput(0);
  205. lput(0x80); /* flags */
  206. }
  207. void
  208. asmb(void)
  209. {
  210. Prog *p;
  211. long tm;
  212. ulong rndtxtsz;
  213. vlong t, etext;
  214. Optab *o;
  215. if(debug['v'])
  216. Bprint(&bso, "%5.2f asm\n", cputime());
  217. Bflush(&bso);
  218. OFFSET = HEADR;
  219. seek(cout, OFFSET, 0);
  220. pc = INITTEXT;
  221. for(p = firstp; p != P; p = p->link) {
  222. if(p->as == ATEXT) {
  223. curtext = p;
  224. autosize = p->to.offset + 4;
  225. }
  226. if(p->pc != pc) {
  227. diag("phase error %llux sb %llux", p->pc, pc);
  228. if(!debug['a'])
  229. prasm(curp);
  230. pc = p->pc;
  231. }
  232. curp = p;
  233. o = oplook(p); /* could probably avoid this call */
  234. if(asmout(p, o, 0)) {
  235. p = p->link;
  236. pc += 4;
  237. }
  238. pc += o->size;
  239. }
  240. if(debug['a'])
  241. Bprint(&bso, "\n");
  242. Bflush(&bso);
  243. cflush();
  244. etext = INITTEXT + textsize;
  245. for(t = pc; t < etext; t += sizeof(buf)-100) {
  246. if(etext-t > sizeof(buf)-100)
  247. datblk(t, sizeof(buf)-100, 1);
  248. else
  249. datblk(t, etext-t, 1);
  250. }
  251. Bflush(&bso);
  252. cflush();
  253. curtext = P;
  254. switch(HEADTYPE) {
  255. case 0:
  256. case 4:
  257. OFFSET = rnd(HEADR+textsize, 4096);
  258. seek(cout, OFFSET, 0);
  259. break;
  260. case 1:
  261. case 2:
  262. case 3:
  263. case 5:
  264. case 6:
  265. case 7:
  266. OFFSET = HEADR+textsize;
  267. seek(cout, OFFSET, 0);
  268. break;
  269. }
  270. for(t = 0; t < datsize; t += sizeof(buf)-100) {
  271. if(datsize-t > sizeof(buf)-100)
  272. datblk(t, sizeof(buf)-100, 0);
  273. else
  274. datblk(t, datsize-t, 0);
  275. }
  276. symsize = 0;
  277. lcsize = 0;
  278. if(!debug['s']) {
  279. if(debug['v'])
  280. Bprint(&bso, "%5.2f sym\n", cputime());
  281. Bflush(&bso);
  282. switch(HEADTYPE) {
  283. case 0:
  284. case 4:
  285. OFFSET = rnd(HEADR+textsize, 4096)+datsize;
  286. seek(cout, OFFSET, 0);
  287. break;
  288. case 3:
  289. case 2:
  290. case 1:
  291. case 5:
  292. case 6:
  293. case 7:
  294. OFFSET = HEADR+textsize+datsize;
  295. seek(cout, OFFSET, 0);
  296. break;
  297. }
  298. if(!debug['s'])
  299. asmsym();
  300. if(debug['v'])
  301. Bprint(&bso, "%5.2f pc\n", cputime());
  302. Bflush(&bso);
  303. if(!debug['s'])
  304. asmlc();
  305. cflush();
  306. }
  307. if(debug['v'])
  308. Bprint(&bso, "%5.2f header\n", cputime());
  309. Bflush(&bso);
  310. OFFSET = 0;
  311. seek(cout, OFFSET, 0);
  312. rndtxtsz = rnd(HEADR+textsize, (INITRND > 0? INITRND: 4096));
  313. tm = time(0);
  314. switch(HEADTYPE) {
  315. case 0:
  316. /* 0413: plan 9 boot image, text segment rounded (to 4KB) */
  317. plan9bootimage(0, 0413<<16|0437, 0, rndtxtsz, rndtxtsz,
  318. INITTEXT-HEADR, 0);
  319. break;
  320. case 1:
  321. /* 0407: plan 9 boot image, extra word */
  322. plan9bootimage(0, 0407<<16|0437, 0, HEADR+textsize, textsize,
  323. INITTEXT, lcsize);
  324. lput(0); /* extra; complete mystery */
  325. break;
  326. case 2: /* plan 9 format */
  327. if (little)
  328. lput(P_MAGIC); /* mips 3000 LE */
  329. else
  330. lput(V_MAGIC); /* mips 3000 BE */
  331. lput(textsize); /* sizes */
  332. lput(datsize);
  333. lput(bsssize);
  334. lput(symsize); /* nsyms */
  335. lput(entryvalue()); /* va of entry */
  336. lput(0L);
  337. lput(lcsize);
  338. break;
  339. case 3:
  340. /* 0407: plan 9 mips 4k boot image with symbols */
  341. plan9bootimage(3, 0407<<16|0437, tm, HEADR+textsize, textsize,
  342. INITTEXT, lcsize);
  343. symhdrs(HEADR+textsize);
  344. break;
  345. case 4:
  346. /* 0413: plan 9 mips 4k boot image with symbols */
  347. plan9bootimage(3, 0413<<16|01012, tm, rndtxtsz, textsize,
  348. INITTEXT, lcsize);
  349. symhdrs(rndtxtsz);
  350. break;
  351. case 5:
  352. elf32(MIPS, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
  353. break;
  354. case 6:
  355. break;
  356. case 7:
  357. elf64(MIPSR4K, little? ELFDATA2LSB: ELFDATA2MSB, 0, nil);
  358. break;
  359. }
  360. cflush();
  361. }
  362. void
  363. strnput(char *s, int n)
  364. {
  365. for(; *s; s++){
  366. CPUT(*s);
  367. n--;
  368. }
  369. for(; n > 0; n--)
  370. CPUT(0);
  371. }
  372. void
  373. cflush(void)
  374. {
  375. int n;
  376. n = sizeof(buf.cbuf) - cbc;
  377. if(n)
  378. write(cout, buf.cbuf, n);
  379. cbp = buf.cbuf;
  380. cbc = sizeof(buf.cbuf);
  381. }
  382. void
  383. nopstat(char *f, Count *c)
  384. {
  385. if(c->outof)
  386. Bprint(&bso, "%s delay %ld/%ld (%.2f)\n", f,
  387. c->outof - c->count, c->outof,
  388. (double)(c->outof - c->count)/c->outof);
  389. }
  390. void
  391. asmsym(void)
  392. {
  393. Prog *p;
  394. Auto *a;
  395. Sym *s;
  396. int h;
  397. s = lookup("etext", 0);
  398. if(s->type == STEXT)
  399. putsymb(s->name, 'T', s->value, s->version);
  400. for(h=0; h<NHASH; h++)
  401. for(s=hash[h]; s!=S; s=s->link)
  402. switch(s->type) {
  403. case SCONST:
  404. putsymb(s->name, 'D', s->value, s->version);
  405. continue;
  406. case SSTRING:
  407. putsymb(s->name, 'T', s->value, s->version);
  408. continue;
  409. case SDATA:
  410. putsymb(s->name, 'D', s->value+INITDAT, s->version);
  411. continue;
  412. case SBSS:
  413. putsymb(s->name, 'B', s->value+INITDAT, s->version);
  414. continue;
  415. case SFILE:
  416. putsymb(s->name, 'f', s->value, s->version);
  417. continue;
  418. }
  419. for(p=textp; p!=P; p=p->cond) {
  420. s = p->from.sym;
  421. if(s->type != STEXT && s->type != SLEAF)
  422. continue;
  423. /* filenames first */
  424. for(a=p->to.autom; a; a=a->link)
  425. if(a->type == D_FILE)
  426. putsymb(a->asym->name, 'z', a->aoffset, 0);
  427. else
  428. if(a->type == D_FILE1)
  429. putsymb(a->asym->name, 'Z', a->aoffset, 0);
  430. if(s->type == STEXT)
  431. putsymb(s->name, 'T', s->value, s->version);
  432. else
  433. putsymb(s->name, 'L', s->value, s->version);
  434. /* frame, auto and param after */
  435. putsymb(".frame", 'm', p->to.offset+4, 0);
  436. for(a=p->to.autom; a; a=a->link)
  437. if(a->type == D_AUTO)
  438. putsymb(a->asym->name, 'a', -a->aoffset, 0);
  439. else
  440. if(a->type == D_PARAM)
  441. putsymb(a->asym->name, 'p', a->aoffset, 0);
  442. }
  443. if(debug['v'] || debug['n'])
  444. Bprint(&bso, "symsize = %lud\n", symsize);
  445. Bflush(&bso);
  446. }
  447. void
  448. putsymb(char *s, int t, long v, int ver)
  449. {
  450. int i, f;
  451. if(t == 'f')
  452. s++;
  453. LBEPUT(v);
  454. if(ver)
  455. t += 'a' - 'A';
  456. CPUT(t+0x80); /* 0x80 is variable length */
  457. if(t == 'Z' || t == 'z') {
  458. CPUT(s[0]);
  459. for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
  460. CPUT(s[i]);
  461. CPUT(s[i+1]);
  462. }
  463. CPUT(0);
  464. CPUT(0);
  465. i++;
  466. }
  467. else {
  468. for(i=0; s[i]; i++)
  469. CPUT(s[i]);
  470. CPUT(0);
  471. }
  472. symsize += 4 + 1 + i + 1;
  473. if(debug['n']) {
  474. if(t == 'z' || t == 'Z') {
  475. Bprint(&bso, "%c %.8lux ", t, v);
  476. for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
  477. f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
  478. Bprint(&bso, "/%x", f);
  479. }
  480. Bprint(&bso, "\n");
  481. return;
  482. }
  483. if(ver)
  484. Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
  485. else
  486. Bprint(&bso, "%c %.8lux %s\n", t, v, s);
  487. }
  488. }
  489. #define MINLC 4
  490. void
  491. asmlc(void)
  492. {
  493. long oldlc, v, s;
  494. vlong oldpc;
  495. Prog *p;
  496. oldpc = INITTEXT;
  497. oldlc = 0;
  498. for(p = firstp; p != P; p = p->link) {
  499. if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
  500. if(p->as == ATEXT)
  501. curtext = p;
  502. if(debug['V'])
  503. Bprint(&bso, "%6llux %P\n", p->pc, p);
  504. continue;
  505. }
  506. if(debug['V'])
  507. Bprint(&bso, "\t\t%6ld", lcsize);
  508. v = (p->pc - oldpc) / MINLC;
  509. while(v) {
  510. s = 127;
  511. if(v < 127)
  512. s = v;
  513. CPUT(s+128); /* 129-255 +pc */
  514. if(debug['V'])
  515. Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
  516. v -= s;
  517. lcsize++;
  518. }
  519. s = p->line - oldlc;
  520. oldlc = p->line;
  521. oldpc = p->pc + MINLC;
  522. if(s > 64 || s < -64) {
  523. CPUT(0); /* 0 vv +lc */
  524. CPUT(s>>24);
  525. CPUT(s>>16);
  526. CPUT(s>>8);
  527. CPUT(s);
  528. if(debug['V']) {
  529. if(s > 0)
  530. Bprint(&bso, " lc+%ld(%d,%ld)\n",
  531. s, 0, s);
  532. else
  533. Bprint(&bso, " lc%ld(%d,%ld)\n",
  534. s, 0, s);
  535. Bprint(&bso, "%6llux %P\n", p->pc, p);
  536. }
  537. lcsize += 5;
  538. continue;
  539. }
  540. if(s > 0) {
  541. CPUT(0+s); /* 1-64 +lc */
  542. if(debug['V']) {
  543. Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
  544. Bprint(&bso, "%6llux %P\n", p->pc, p);
  545. }
  546. } else {
  547. CPUT(64-s); /* 65-128 -lc */
  548. if(debug['V']) {
  549. Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
  550. Bprint(&bso, "%6llux %P\n", p->pc, p);
  551. }
  552. }
  553. lcsize++;
  554. }
  555. while(lcsize & 1) {
  556. s = 129;
  557. CPUT(s);
  558. lcsize++;
  559. }
  560. if(debug['v'] || debug['V'])
  561. Bprint(&bso, "lcsize = %ld\n", lcsize);
  562. Bflush(&bso);
  563. }
  564. void
  565. datblk(long s, long n, int str)
  566. {
  567. Prog *p;
  568. char *cast;
  569. long l, fl, j, d;
  570. int i, c;
  571. memset(buf.dbuf, 0, n+100);
  572. for(p = datap; p != P; p = p->link) {
  573. curp = p;
  574. if(str != (p->from.sym->type == SSTRING))
  575. continue;
  576. l = p->from.sym->value + p->from.offset - s;
  577. c = p->reg;
  578. i = 0;
  579. if(l < 0) {
  580. if(l+c <= 0)
  581. continue;
  582. while(l < 0) {
  583. l++;
  584. i++;
  585. }
  586. }
  587. if(l >= n)
  588. continue;
  589. if(p->as != AINIT && p->as != ADYNT) {
  590. for(j=l+(c-i)-1; j>=l; j--)
  591. if(buf.dbuf[j]) {
  592. print("%P\n", p);
  593. diag("multiple initialization");
  594. break;
  595. }
  596. }
  597. switch(p->to.type) {
  598. default:
  599. diag("unknown mode in initialization\n%P", p);
  600. break;
  601. case D_FCONST:
  602. switch(c) {
  603. default:
  604. case 4:
  605. fl = ieeedtof(p->to.ieee);
  606. cast = (char*)&fl;
  607. for(; i<c; i++) {
  608. buf.dbuf[l] = cast[fnuxi8[i+4]];
  609. l++;
  610. }
  611. break;
  612. case 8:
  613. cast = (char*)p->to.ieee;
  614. for(; i<c; i++) {
  615. buf.dbuf[l] = cast[fnuxi8[i]];
  616. l++;
  617. }
  618. break;
  619. }
  620. break;
  621. case D_SCONST:
  622. for(; i<c; i++) {
  623. buf.dbuf[l] = p->to.sval[i];
  624. l++;
  625. }
  626. break;
  627. case D_CONST:
  628. d = p->to.offset;
  629. if(p->to.sym) {
  630. switch(p->to.sym->type) {
  631. case STEXT:
  632. case SLEAF:
  633. case SSTRING:
  634. d += p->to.sym->value;
  635. break;
  636. case SDATA:
  637. case SBSS:
  638. d += p->to.sym->value + INITDAT;
  639. break;
  640. }
  641. }
  642. cast = (char*)&d;
  643. switch(c) {
  644. default:
  645. diag("bad nuxi %d %d\n%P", c, i, curp);
  646. break;
  647. case 1:
  648. for(; i<c; i++) {
  649. buf.dbuf[l] = cast[inuxi1[i]];
  650. l++;
  651. }
  652. break;
  653. case 2:
  654. for(; i<c; i++) {
  655. buf.dbuf[l] = cast[inuxi2[i]];
  656. l++;
  657. }
  658. break;
  659. case 4:
  660. for(; i<c; i++) {
  661. buf.dbuf[l] = cast[inuxi4[i]];
  662. l++;
  663. }
  664. break;
  665. }
  666. break;
  667. }
  668. }
  669. write(cout, buf.dbuf, n);
  670. }
  671. #define OP_RRR(op,r1,r2,r3)\
  672. (op|(((r1)&31L)<<16)|(((r2)&31L)<<21)|(((r3)&31L)<<11))
  673. #define OP_IRR(op,i,r2,r3)\
  674. (op|((i)&0xffffL)|(((r2)&31L)<<21)|(((r3)&31L)<<16))
  675. #define OP_SRR(op,s,r2,r3)\
  676. (op|(((s)&31L)<<6)|(((r2)&31L)<<16)|(((r3)&31L)<<11))
  677. #define OP_FRRR(op,r1,r2,r3)\
  678. (op|(((r1)&31L)<<16)|(((r2)&31L)<<11)|(((r3)&31L)<<6))
  679. #define OP_JMP(op,i)\
  680. ((op)|((i)&0x3ffffffL))
  681. #define OP(x,y)\
  682. (((x)<<3)|((y)<<0))
  683. #define SP(x,y)\
  684. (((x)<<29)|((y)<<26))
  685. #define BCOND(x,y)\
  686. (((x)<<19)|((y)<<16))
  687. #define MMU(x,y)\
  688. (SP(2,0)|(16<<21)|((x)<<3)|((y)<<0))
  689. #define FPF(x,y)\
  690. (SP(2,1)|(16<<21)|((x)<<3)|((y)<<0))
  691. #define FPD(x,y)\
  692. (SP(2,1)|(17<<21)|((x)<<3)|((y)<<0))
  693. #define FPW(x,y)\
  694. (SP(2,1)|(20<<21)|((x)<<3)|((y)<<0))
  695. int vshift(int);
  696. int
  697. asmout(Prog *p, Optab *o, int aflag)
  698. {
  699. long o1, o2, o3, o4, o5, o6, o7, v;
  700. Prog *ct;
  701. int r, a;
  702. o1 = 0;
  703. o2 = 0;
  704. o3 = 0;
  705. o4 = 0;
  706. o5 = 0;
  707. o6 = 0;
  708. o7 = 0;
  709. switch(o->type) {
  710. default:
  711. diag("unknown type %d", o->type);
  712. if(!debug['a'])
  713. prasm(p);
  714. break;
  715. case 0: /* pseudo ops */
  716. if(aflag) {
  717. if(p->link) {
  718. if(p->as == ATEXT) {
  719. ct = curtext;
  720. o2 = autosize;
  721. curtext = p;
  722. autosize = p->to.offset + 4;
  723. o1 = asmout(p->link, oplook(p->link), aflag);
  724. curtext = ct;
  725. autosize = o2;
  726. } else
  727. o1 = asmout(p->link, oplook(p->link), aflag);
  728. }
  729. return o1;
  730. }
  731. break;
  732. case 1: /* mov[v] r1,r2 ==> OR r1,r0,r2 */
  733. o1 = OP_RRR(oprrr(AOR), p->from.reg, REGZERO, p->to.reg);
  734. break;
  735. case 2: /* add/sub r1,[r2],r3 */
  736. r = p->reg;
  737. if(r == NREG)
  738. r = p->to.reg;
  739. o1 = OP_RRR(oprrr(p->as), p->from.reg, r, p->to.reg);
  740. break;
  741. case 3: /* mov $soreg, r ==> or/add $i,o,r */
  742. v = regoff(&p->from);
  743. r = p->from.reg;
  744. if(r == NREG)
  745. r = o->param;
  746. a = AADDU;
  747. if(o->a1 == C_ANDCON)
  748. a = AOR;
  749. o1 = OP_IRR(opirr(a), v, r, p->to.reg);
  750. break;
  751. case 4: /* add $scon,[r1],r2 */
  752. v = regoff(&p->from);
  753. r = p->reg;
  754. if(r == NREG)
  755. r = p->to.reg;
  756. o1 = OP_IRR(opirr(p->as), v, r, p->to.reg);
  757. break;
  758. case 5: /* syscall */
  759. if(aflag)
  760. return 0;
  761. o1 = oprrr(p->as);
  762. break;
  763. case 6: /* beq r1,[r2],sbra */
  764. if(aflag)
  765. return 0;
  766. if(p->cond == P)
  767. v = -4 >> 2;
  768. else
  769. v = (p->cond->pc - pc-4) >> 2;
  770. if(((v << 16) >> 16) != v)
  771. diag("short branch too far: %ld\n%P", v, p);
  772. o1 = OP_IRR(opirr(p->as), v, p->from.reg, p->reg);
  773. break;
  774. case 7: /* mov r, soreg ==> sw o(r) */
  775. r = p->to.reg;
  776. if(r == NREG)
  777. r = o->param;
  778. v = regoff(&p->to);
  779. o1 = OP_IRR(opirr(p->as), v, r, p->from.reg);
  780. break;
  781. case 8: /* mov soreg, r ==> lw o(r) */
  782. r = p->from.reg;
  783. if(r == NREG)
  784. r = o->param;
  785. v = regoff(&p->from);
  786. o1 = OP_IRR(opirr(p->as+ALAST), v, r, p->to.reg);
  787. break;
  788. case 9: /* asl r1,[r2],r3 */
  789. r = p->reg;
  790. if(r == NREG)
  791. r = p->to.reg;
  792. o1 = OP_RRR(oprrr(p->as), r, p->from.reg, p->to.reg);
  793. break;
  794. case 10: /* add $con,[r1],r2 ==> mov $con,t; add t,[r1],r2 */
  795. v = regoff(&p->from);
  796. r = AOR;
  797. if(v < 0)
  798. r = AADDU;
  799. o1 = OP_IRR(opirr(r), v, 0, REGTMP);
  800. r = p->reg;
  801. if(r == NREG)
  802. r = p->to.reg;
  803. o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
  804. break;
  805. case 11: /* jmp lbra */
  806. if(aflag)
  807. return 0;
  808. if(p->cond == P)
  809. v = p->pc >> 2;
  810. else
  811. v = p->cond->pc >> 2;
  812. o1 = OP_JMP(opirr(p->as), v);
  813. if(!debug['Y'] && p->link && p->cond && isnop(p->link)) {
  814. nop.branch.count--;
  815. nop.branch.outof--;
  816. nop.jump.outof++;
  817. o2 = asmout(p->cond, oplook(p->cond), 1);
  818. if(o2) {
  819. o1 += 1;
  820. if(debug['a'])
  821. Bprint(&bso, " %.8llux: %.8lux %.8lux%P\n",
  822. p->pc, o1, o2, p);
  823. LPUT(o1);
  824. LPUT(o2);
  825. return 1;
  826. }
  827. }
  828. break;
  829. case 12: /* movbs r,r */
  830. v = 16;
  831. if(p->as == AMOVB)
  832. v = 24;
  833. o1 = OP_SRR(opirr(ASLL), v, p->from.reg, p->to.reg);
  834. o2 = OP_SRR(opirr(ASRA), v, p->to.reg, p->to.reg);
  835. break;
  836. case 13: /* movbu r,r */
  837. if(p->as == AMOVBU)
  838. o1 = OP_IRR(opirr(AAND), 0xffL, p->from.reg, p->to.reg);
  839. else
  840. o1 = OP_IRR(opirr(AAND), 0xffffL, p->from.reg, p->to.reg);
  841. break;
  842. case 16: /* sll $c,[r1],r2 */
  843. v = regoff(&p->from);
  844. r = p->reg;
  845. if(r == NREG)
  846. r = p->to.reg;
  847. /* OP_SRR will use only the low 5 bits of the shift value */
  848. if(v >= 32 && vshift(p->as))
  849. o1 = OP_SRR(opirr(p->as+ALAST), v-32, r, p->to.reg);
  850. else
  851. o1 = OP_SRR(opirr(p->as), v, r, p->to.reg);
  852. break;
  853. case 18: /* jmp [r1],0(r2) */
  854. if(aflag)
  855. return 0;
  856. r = p->reg;
  857. if(r == NREG)
  858. r = o->param;
  859. o1 = OP_RRR(oprrr(p->as), 0, p->to.reg, r);
  860. break;
  861. case 19: /* mov $lcon,r ==> lu+or */
  862. v = regoff(&p->from);
  863. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
  864. o2 = OP_IRR(opirr(AOR), v, p->to.reg, p->to.reg);
  865. break;
  866. case 20: /* mov lohi,r */
  867. r = OP(2,0); /* mfhi */
  868. if(p->from.type == D_LO)
  869. r = OP(2,2); /* mflo */
  870. o1 = OP_RRR(r, REGZERO, REGZERO, p->to.reg);
  871. break;
  872. case 21: /* mov r,lohi */
  873. r = OP(2,1); /* mthi */
  874. if(p->to.type == D_LO)
  875. r = OP(2,3); /* mtlo */
  876. o1 = OP_RRR(r, REGZERO, p->from.reg, REGZERO);
  877. break;
  878. case 22: /* mul r1,r2 */
  879. o1 = OP_RRR(oprrr(p->as), p->from.reg, p->reg, REGZERO);
  880. break;
  881. case 23: /* add $lcon,r1,r2 ==> lu+or+add */
  882. v = regoff(&p->from);
  883. if(p->to.reg == REGTMP || p->reg == REGTMP)
  884. diag("cant synthesize large constant\n%P", p);
  885. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  886. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  887. r = p->reg;
  888. if(r == NREG)
  889. r = p->to.reg;
  890. o3 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
  891. break;
  892. case 24: /* mov $ucon,,r ==> lu r */
  893. v = regoff(&p->from);
  894. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, p->to.reg);
  895. break;
  896. case 25: /* add/and $ucon,[r1],r2 ==> lu $con,t; add t,[r1],r2 */
  897. v = regoff(&p->from);
  898. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  899. r = p->reg;
  900. if(r == NREG)
  901. r = p->to.reg;
  902. o2 = OP_RRR(oprrr(p->as), REGTMP, r, p->to.reg);
  903. break;
  904. case 26: /* mov $lsext/auto/oreg,,r2 ==> lu+or+add */
  905. v = regoff(&p->from);
  906. if(p->to.reg == REGTMP)
  907. diag("cant synthesize large constant\n%P", p);
  908. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  909. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  910. r = p->from.reg;
  911. if(r == NREG)
  912. r = o->param;
  913. o3 = OP_RRR(oprrr(AADDU), REGTMP, r, p->to.reg);
  914. break;
  915. case 27: /* mov [sl]ext/auto/oreg,fr ==> lwc1 o(r) */
  916. r = p->from.reg;
  917. if(r == NREG)
  918. r = o->param;
  919. v = regoff(&p->from);
  920. switch(o->size) {
  921. case 20:
  922. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  923. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  924. o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
  925. o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg+1);
  926. o5 = OP_IRR(opirr(AMOVF+ALAST), 4, REGTMP, p->to.reg);
  927. break;
  928. case 16:
  929. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  930. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  931. o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
  932. o4 = OP_IRR(opirr(AMOVF+ALAST), 0, REGTMP, p->to.reg);
  933. break;
  934. case 8:
  935. o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg+1);
  936. o2 = OP_IRR(opirr(AMOVF+ALAST), v+4, r, p->to.reg);
  937. break;
  938. case 4:
  939. o1 = OP_IRR(opirr(AMOVF+ALAST), v, r, p->to.reg);
  940. break;
  941. }
  942. break;
  943. case 28: /* mov fr,[sl]ext/auto/oreg ==> swc1 o(r) */
  944. r = p->to.reg;
  945. if(r == NREG)
  946. r = o->param;
  947. v = regoff(&p->to);
  948. switch(o->size) {
  949. case 20:
  950. if(r == REGTMP)
  951. diag("cant synthesize large constant\n%P", p);
  952. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  953. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  954. o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
  955. o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg+1);
  956. o5 = OP_IRR(opirr(AMOVF), 4, REGTMP, p->from.reg);
  957. break;
  958. case 16:
  959. if(r == REGTMP)
  960. diag("cant synthesize large constant\n%P", p);
  961. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  962. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  963. o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
  964. o4 = OP_IRR(opirr(AMOVF), 0, REGTMP, p->from.reg);
  965. break;
  966. case 8:
  967. o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg+1);
  968. o2 = OP_IRR(opirr(AMOVF), v+4, r, p->from.reg);
  969. break;
  970. case 4:
  971. o1 = OP_IRR(opirr(AMOVF), v, r, p->from.reg);
  972. break;
  973. }
  974. break;
  975. case 30: /* movw r,fr */
  976. r = SP(2,1)|(4<<21); /* mtc1 */
  977. o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
  978. break;
  979. case 31: /* movw fr,r */
  980. r = SP(2,1)|(0<<21); /* mfc1 */
  981. o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
  982. break;
  983. case 32: /* fadd fr1,[fr2],fr3 */
  984. r = p->reg;
  985. if(r == NREG)
  986. o1 = OP_FRRR(oprrr(p->as), p->from.reg, p->to.reg, p->to.reg);
  987. else
  988. o1 = OP_FRRR(oprrr(p->as), p->from.reg, r, p->to.reg);
  989. break;
  990. case 33: /* fabs fr1,fr3 */
  991. o1 = OP_FRRR(oprrr(p->as), 0, p->from.reg, p->to.reg);
  992. break;
  993. case 34: /* mov $con,fr ==> or/add $i,r,r2 */
  994. v = regoff(&p->from);
  995. r = AADDU;
  996. if(o->a1 == C_ANDCON)
  997. r = AOR;
  998. o1 = OP_IRR(opirr(r), v, 0, REGTMP);
  999. o2 = OP_RRR(SP(2,1)|(4<<21), REGTMP, 0, p->to.reg); /* mtc1 */
  1000. break;
  1001. case 35: /* mov r,lext/luto/oreg ==> sw o(r) */
  1002. /*
  1003. * the lowbits of the constant cannot
  1004. * be moved into the offset of the load
  1005. * because the mips 4000 in 64-bit mode
  1006. * does a 64-bit add and it will screw up.
  1007. */
  1008. v = regoff(&p->to);
  1009. r = p->to.reg;
  1010. if(r == NREG)
  1011. r = o->param;
  1012. if(r == REGTMP)
  1013. diag("cant synthesize large constant\n%P", p);
  1014. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  1015. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  1016. o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
  1017. o4 = OP_IRR(opirr(p->as), 0, REGTMP, p->from.reg);
  1018. break;
  1019. case 36: /* mov lext/lauto/lreg,r ==> lw o(r30) */
  1020. v = regoff(&p->from);
  1021. r = p->from.reg;
  1022. if(r == NREG)
  1023. r = o->param;
  1024. if(r == REGTMP)
  1025. diag("cant synthesize large constant\n%P", p);
  1026. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  1027. o2 = OP_IRR(opirr(AOR), v, REGTMP, REGTMP);
  1028. o3 = OP_RRR(oprrr(AADDU), r, REGTMP, REGTMP);
  1029. o4 = OP_IRR(opirr(p->as+ALAST), 0, REGTMP, p->to.reg);
  1030. break;
  1031. case 37: /* movw r,mr */
  1032. r = SP(2,0)|(4<<21); /* mtc0 */
  1033. if(p->as == AMOVV)
  1034. r = SP(2,0)|(5<<21); /* dmtc0 */
  1035. o1 = OP_RRR(r, p->from.reg, 0, p->to.reg);
  1036. break;
  1037. case 38: /* movw mr,r */
  1038. r = SP(2,0)|(0<<21); /* mfc0 */
  1039. if(p->as == AMOVV)
  1040. r = SP(2,0)|(1<<21); /* dmfc0 */
  1041. o1 = OP_RRR(r, p->to.reg, 0, p->from.reg);
  1042. break;
  1043. case 39: /* rfe ==> jmp+rfe */
  1044. if(aflag)
  1045. return 0;
  1046. o1 = OP_RRR(oprrr(AJMP), 0, p->to.reg, REGZERO);
  1047. o2 = oprrr(p->as);
  1048. break;
  1049. case 40: /* word */
  1050. if(aflag)
  1051. return 0;
  1052. o1 = regoff(&p->to);
  1053. break;
  1054. case 41: /* movw r,fcr */
  1055. o1 = OP_RRR(SP(2,1)|(2<<21), REGZERO, 0, p->to.reg); /* mfcc1 */
  1056. o2 = OP_RRR(SP(2,1)|(6<<21), p->from.reg, 0, p->to.reg);/* mtcc1 */
  1057. break;
  1058. case 42: /* movw fcr,r */
  1059. o1 = OP_RRR(SP(2,1)|(2<<21), p->to.reg, 0, p->from.reg);/* mfcc1 */
  1060. break;
  1061. case 45: /* case r */
  1062. if(p->link == P)
  1063. v = p->pc+28;
  1064. else
  1065. v = p->link->pc;
  1066. if(v & (1<<15))
  1067. o1 = OP_IRR(opirr(ALAST), (v>>16)+1, REGZERO, REGTMP);
  1068. else
  1069. o1 = OP_IRR(opirr(ALAST), v>>16, REGZERO, REGTMP);
  1070. o2 = OP_SRR(opirr(ASLL), 2, p->from.reg, p->from.reg);
  1071. o3 = OP_RRR(oprrr(AADD), p->from.reg, REGTMP, REGTMP);
  1072. o4 = OP_IRR(opirr(AMOVW+ALAST), v, REGTMP, REGTMP);
  1073. o5 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
  1074. o6 = OP_RRR(oprrr(AJMP), 0, REGTMP, REGZERO);
  1075. o7 = OP_RRR(oprrr(ANOR), REGZERO, REGZERO, REGZERO);
  1076. break;
  1077. case 46: /* bcase $con,lbra */
  1078. if(p->cond == P)
  1079. v = p->pc;
  1080. else
  1081. v = p->cond->pc;
  1082. o1 = v;
  1083. break;
  1084. }
  1085. if(aflag)
  1086. return o1;
  1087. v = p->pc;
  1088. switch(o->size) {
  1089. default:
  1090. if(debug['a'])
  1091. Bprint(&bso, " %.8lux:\t\t%P\n", v, p);
  1092. break;
  1093. case 4:
  1094. if(debug['a'])
  1095. Bprint(&bso, " %.8lux: %.8lux\t%P\n", v, o1, p);
  1096. LPUT(o1);
  1097. break;
  1098. case 8:
  1099. if(debug['a'])
  1100. Bprint(&bso, " %.8lux: %.8lux %.8lux%P\n", v, o1, o2, p);
  1101. LPUT(o1);
  1102. LPUT(o2);
  1103. break;
  1104. case 12:
  1105. if(debug['a'])
  1106. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux%P\n", v, o1, o2, o3, p);
  1107. LPUT(o1);
  1108. LPUT(o2);
  1109. LPUT(o3);
  1110. break;
  1111. case 16:
  1112. if(debug['a'])
  1113. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux%P\n",
  1114. v, o1, o2, o3, o4, p);
  1115. LPUT(o1);
  1116. LPUT(o2);
  1117. LPUT(o3);
  1118. LPUT(o4);
  1119. break;
  1120. case 20:
  1121. if(debug['a'])
  1122. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
  1123. v, o1, o2, o3, o4, o5, p);
  1124. LPUT(o1);
  1125. LPUT(o2);
  1126. LPUT(o3);
  1127. LPUT(o4);
  1128. LPUT(o5);
  1129. break;
  1130. case 28:
  1131. if(debug['a'])
  1132. Bprint(&bso, " %.8lux: %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux %.8lux%P\n",
  1133. v, o1, o2, o3, o4, o5, o6, o7, p);
  1134. LPUT(o1);
  1135. LPUT(o2);
  1136. LPUT(o3);
  1137. LPUT(o4);
  1138. LPUT(o5);
  1139. LPUT(o6);
  1140. LPUT(o7);
  1141. break;
  1142. }
  1143. return 0;
  1144. }
  1145. int
  1146. isnop(Prog *p)
  1147. {
  1148. if(p->as != ANOR)
  1149. return 0;
  1150. if(p->reg != REGZERO && p->reg != NREG)
  1151. return 0;
  1152. if(p->from.type != D_REG || p->from.reg != REGZERO)
  1153. return 0;
  1154. if(p->to.type != D_REG || p->to.reg != REGZERO)
  1155. return 0;
  1156. return 1;
  1157. }
  1158. long
  1159. oprrr(int a)
  1160. {
  1161. switch(a) {
  1162. case AADD: return OP(4,0);
  1163. case AADDU: return OP(4,1);
  1164. case ASGT: return OP(5,2);
  1165. case ASGTU: return OP(5,3);
  1166. case AAND: return OP(4,4);
  1167. case AOR: return OP(4,5);
  1168. case AXOR: return OP(4,6);
  1169. case ASUB: return OP(4,2);
  1170. case ASUBU: return OP(4,3);
  1171. case ANOR: return OP(4,7);
  1172. case ASLL: return OP(0,4);
  1173. case ASRL: return OP(0,6);
  1174. case ASRA: return OP(0,7);
  1175. case AREM:
  1176. case ADIV: return OP(3,2);
  1177. case AREMU:
  1178. case ADIVU: return OP(3,3);
  1179. case AMUL: return OP(3,0);
  1180. case AMULU: return OP(3,1);
  1181. case AJMP: return OP(1,0);
  1182. case AJAL: return OP(1,1);
  1183. case ABREAK: return OP(1,5);
  1184. case ASYSCALL: return OP(1,4);
  1185. case ATLBP: return MMU(1,0);
  1186. case ATLBR: return MMU(0,1);
  1187. case ATLBWI: return MMU(0,2);
  1188. case ATLBWR: return MMU(0,6);
  1189. case ARFE: return MMU(2,0);
  1190. case ADIVF: return FPF(0,3);
  1191. case ADIVD: return FPD(0,3);
  1192. case AMULF: return FPF(0,2);
  1193. case AMULD: return FPD(0,2);
  1194. case ASUBF: return FPF(0,1);
  1195. case ASUBD: return FPD(0,1);
  1196. case AADDF: return FPF(0,0);
  1197. case AADDD: return FPD(0,0);
  1198. case AMOVFW: return FPF(4,4);
  1199. case AMOVDW: return FPD(4,4);
  1200. case AMOVWF: return FPW(4,0);
  1201. case AMOVDF: return FPD(4,0);
  1202. case AMOVWD: return FPW(4,1);
  1203. case AMOVFD: return FPF(4,1);
  1204. case AABSF: return FPF(0,5);
  1205. case AABSD: return FPD(0,5);
  1206. case AMOVF: return FPF(0,6);
  1207. case AMOVD: return FPD(0,6);
  1208. case ANEGF: return FPF(0,7);
  1209. case ANEGD: return FPD(0,7);
  1210. case ACMPEQF: return FPF(6,2);
  1211. case ACMPEQD: return FPD(6,2);
  1212. case ACMPGTF: return FPF(7,4);
  1213. case ACMPGTD: return FPD(7,4);
  1214. case ACMPGEF: return FPF(7,6);
  1215. case ACMPGED: return FPD(7,6);
  1216. case ADIVV: return OP(3,6);
  1217. case ADIVVU: return OP(3,7);
  1218. case AADDV: return OP(5,4);
  1219. case AADDVU: return OP(5,5);
  1220. }
  1221. diag("bad rrr %d", a);
  1222. return 0;
  1223. }
  1224. long
  1225. opirr(int a)
  1226. {
  1227. switch(a) {
  1228. case AADD: return SP(1,0);
  1229. case AADDU: return SP(1,1);
  1230. case ASGT: return SP(1,2);
  1231. case ASGTU: return SP(1,3);
  1232. case AAND: return SP(1,4);
  1233. case AOR: return SP(1,5);
  1234. case AXOR: return SP(1,6);
  1235. case ALAST: return SP(1,7);
  1236. case ASLL: return OP(0,0);
  1237. case ASRL: return OP(0,2);
  1238. case ASRA: return OP(0,3);
  1239. case AJMP: return SP(0,2);
  1240. case AJAL: return SP(0,3);
  1241. case ABEQ: return SP(0,4);
  1242. case ABNE: return SP(0,5);
  1243. case ABGEZ: return SP(0,1)|BCOND(0,1);
  1244. case ABGEZAL: return SP(0,1)|BCOND(2,1);
  1245. case ABGTZ: return SP(0,7);
  1246. case ABLEZ: return SP(0,6);
  1247. case ABLTZ: return SP(0,1)|BCOND(0,0);
  1248. case ABLTZAL: return SP(0,1)|BCOND(2,0);
  1249. case ABFPT: return SP(2,1)|(257<<16);
  1250. case ABFPF: return SP(2,1)|(256<<16);
  1251. case AMOVB:
  1252. case AMOVBU: return SP(5,0);
  1253. case AMOVH:
  1254. case AMOVHU: return SP(5,1);
  1255. case AMOVW: return SP(5,3);
  1256. case AMOVV: return SP(7,7);
  1257. case AMOVF: return SP(7,1);
  1258. case AMOVWL: return SP(5,2);
  1259. case AMOVWR: return SP(5,6);
  1260. case AMOVVL: return SP(5,4);
  1261. case AMOVVR: return SP(5,5);
  1262. case ABREAK: return SP(5,7);
  1263. case AMOVWL+ALAST: return SP(4,2);
  1264. case AMOVWR+ALAST: return SP(4,6);
  1265. case AMOVVL+ALAST: return SP(3,2);
  1266. case AMOVVR+ALAST: return SP(3,3);
  1267. case AMOVB+ALAST: return SP(4,0);
  1268. case AMOVBU+ALAST: return SP(4,4);
  1269. case AMOVH+ALAST: return SP(4,1);
  1270. case AMOVHU+ALAST: return SP(4,5);
  1271. case AMOVW+ALAST: return SP(4,3);
  1272. case AMOVV+ALAST: return SP(6,7);
  1273. case AMOVF+ALAST: return SP(6,1);
  1274. case ASLLV: return OP(7,0);
  1275. case ASRLV: return OP(7,2);
  1276. case ASRAV: return OP(7,3);
  1277. case ASLLV+ALAST: return OP(7,4);
  1278. case ASRLV+ALAST: return OP(7,6);
  1279. case ASRAV+ALAST: return OP(7,7);
  1280. case AADDV: return SP(3,0);
  1281. case AADDVU: return SP(3,1);
  1282. }
  1283. diag("bad irr %d", a);
  1284. abort();
  1285. return 0;
  1286. }
  1287. int
  1288. vshift(int a)
  1289. {
  1290. switch(a){
  1291. case ASLLV: return 1;
  1292. case ASRLV: return 1;
  1293. case ASRAV: return 1;
  1294. }
  1295. return 0;
  1296. }