asm.c 31 KB

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