asm.c 29 KB

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