span.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424
  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. void
  11. span(void)
  12. {
  13. Prog *p, *q;
  14. int32_t v, c, idat;
  15. int m, n, again;
  16. xdefine("etext", STEXT, 0L);
  17. idat = INITDAT;
  18. for(p = firstp; p != P; p = p->link) {
  19. if(p->as == ATEXT)
  20. curtext = p;
  21. n = 0;
  22. if(p->to.type == D_BRANCH)
  23. if(p->pcond == P)
  24. p->pcond = p;
  25. if((q = p->pcond) != P)
  26. if(q->back != 2)
  27. n = 1;
  28. p->back = n;
  29. if(p->as == AADJSP) {
  30. p->to.type = D_SP;
  31. v = -p->from.offset;
  32. p->from.offset = v;
  33. p->as = AADDL;
  34. if(v < 0) {
  35. p->as = ASUBL;
  36. v = -v;
  37. p->from.offset = v;
  38. }
  39. if(v == 0)
  40. p->as = ANOP;
  41. }
  42. }
  43. n = 0;
  44. start:
  45. if(debug['v'])
  46. Bprint(&bso, "%5.2f span\n", cputime());
  47. Bflush(&bso);
  48. c = INITTEXT;
  49. for(p = firstp; p != P; p = p->link) {
  50. if(p->as == ATEXT)
  51. curtext = p;
  52. if(p->to.type == D_BRANCH)
  53. if(p->back)
  54. p->pc = c;
  55. asmins(p);
  56. p->pc = c;
  57. m = andptr-and;
  58. p->mark = m;
  59. c += m;
  60. }
  61. loop:
  62. n++;
  63. if(debug['v'])
  64. Bprint(&bso, "%5.2f span %d\n", cputime(), n);
  65. Bflush(&bso);
  66. if(n > 50) {
  67. print("span must be looping\n");
  68. errorexit();
  69. }
  70. again = 0;
  71. c = INITTEXT;
  72. for(p = firstp; p != P; p = p->link) {
  73. if(p->as == ATEXT)
  74. curtext = p;
  75. if(p->to.type == D_BRANCH) {
  76. if(p->back)
  77. p->pc = c;
  78. asmins(p);
  79. m = andptr-and;
  80. if(m != p->mark) {
  81. p->mark = m;
  82. again++;
  83. }
  84. }
  85. p->pc = c;
  86. c += p->mark;
  87. }
  88. if(again) {
  89. textsize = c;
  90. goto loop;
  91. }
  92. if(INITRND) {
  93. INITDAT = rnd(c, INITRND);
  94. if(INITDAT != idat) {
  95. idat = INITDAT;
  96. goto start;
  97. }
  98. }
  99. xdefine("etext", STEXT, c);
  100. if(debug['v'])
  101. Bprint(&bso, "etext = %lux\n", c);
  102. Bflush(&bso);
  103. for(p = textp; p != P; p = p->pcond)
  104. p->from.sym->value = p->pc;
  105. textsize = c - INITTEXT;
  106. }
  107. void
  108. xdefine(char *p, int t, int32_t v)
  109. {
  110. Sym *s;
  111. s = lookup(p, 0);
  112. if(s->type == 0 || s->type == SXREF) {
  113. s->type = t;
  114. s->value = v;
  115. }
  116. if(s->type == STEXT && s->value == 0)
  117. s->value = v;
  118. }
  119. void
  120. putsymb(char *s, int t, int32_t v, int ver)
  121. {
  122. int i, f;
  123. if(t == 'f')
  124. s++;
  125. lput(v);
  126. if(ver)
  127. t += 'a' - 'A';
  128. cput(t+0x80); /* 0x80 is variable length */
  129. if(t == 'Z' || t == 'z') {
  130. cput(s[0]);
  131. for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
  132. cput(s[i]);
  133. cput(s[i+1]);
  134. }
  135. cput(0);
  136. cput(0);
  137. i++;
  138. }
  139. else {
  140. for(i=0; s[i]; i++)
  141. cput(s[i]);
  142. cput(0);
  143. }
  144. symsize += 4 + 1 + i + 1;
  145. if(debug['n']) {
  146. if(t == 'z' || t == 'Z') {
  147. Bprint(&bso, "%c %.8lux ", t, v);
  148. for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
  149. f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
  150. Bprint(&bso, "/%x", f);
  151. }
  152. Bprint(&bso, "\n");
  153. return;
  154. }
  155. if(ver)
  156. Bprint(&bso, "%c %.8lux %s<%d>\n", t, v, s, ver);
  157. else
  158. Bprint(&bso, "%c %.8lux %s\n", t, v, s);
  159. }
  160. }
  161. void
  162. asmsym(void)
  163. {
  164. Prog *p;
  165. Auto *a;
  166. Sym *s;
  167. int h;
  168. s = lookup("etext", 0);
  169. if(s->type == STEXT)
  170. putsymb(s->name, 'T', s->value, s->version);
  171. for(h=0; h<NHASH; h++)
  172. for(s=hash[h]; s!=S; s=s->link)
  173. switch(s->type) {
  174. case SCONST:
  175. putsymb(s->name, 'D', s->value, s->version);
  176. continue;
  177. case SDATA:
  178. putsymb(s->name, 'D', s->value+INITDAT, s->version);
  179. continue;
  180. case SBSS:
  181. putsymb(s->name, 'B', s->value+INITDAT, s->version);
  182. continue;
  183. case SFILE:
  184. putsymb(s->name, 'f', s->value, s->version);
  185. continue;
  186. }
  187. for(p=textp; p!=P; p=p->pcond) {
  188. s = p->from.sym;
  189. if(s->type != STEXT)
  190. continue;
  191. /* filenames first */
  192. for(a=p->to.autom; a; a=a->link)
  193. if(a->type == D_FILE)
  194. putsymb(a->asym->name, 'z', a->aoffset, 0);
  195. else
  196. if(a->type == D_FILE1)
  197. putsymb(a->asym->name, 'Z', a->aoffset, 0);
  198. putsymb(s->name, 'T', s->value, s->version);
  199. /* frame, auto and param after */
  200. putsymb(".frame", 'm', p->to.offset+4, 0);
  201. for(a=p->to.autom; a; a=a->link)
  202. if(a->type == D_AUTO)
  203. putsymb(a->asym->name, 'a', -a->aoffset, 0);
  204. else
  205. if(a->type == D_PARAM)
  206. putsymb(a->asym->name, 'p', a->aoffset, 0);
  207. }
  208. if(debug['v'] || debug['n'])
  209. Bprint(&bso, "symsize = %lud\n", symsize);
  210. Bflush(&bso);
  211. }
  212. void
  213. asmlc(void)
  214. {
  215. int32_t oldpc, oldlc;
  216. Prog *p;
  217. int32_t v, s;
  218. oldpc = INITTEXT;
  219. oldlc = 0;
  220. for(p = firstp; p != P; p = p->link) {
  221. if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
  222. if(p->as == ATEXT)
  223. curtext = p;
  224. if(debug['V'])
  225. Bprint(&bso, "%6lux %P\n",
  226. p->pc, p);
  227. continue;
  228. }
  229. if(debug['V'])
  230. Bprint(&bso, "\t\t%6ld", lcsize);
  231. v = (p->pc - oldpc) / MINLC;
  232. while(v) {
  233. s = 127;
  234. if(v < 127)
  235. s = v;
  236. cput(s+128); /* 129-255 +pc */
  237. if(debug['V'])
  238. Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
  239. v -= s;
  240. lcsize++;
  241. }
  242. s = p->line - oldlc;
  243. oldlc = p->line;
  244. oldpc = p->pc + MINLC;
  245. if(s > 64 || s < -64) {
  246. cput(0); /* 0 vv +lc */
  247. cput(s>>24);
  248. cput(s>>16);
  249. cput(s>>8);
  250. cput(s);
  251. if(debug['V']) {
  252. if(s > 0)
  253. Bprint(&bso, " lc+%ld(%d,%ld)\n",
  254. s, 0, s);
  255. else
  256. Bprint(&bso, " lc%ld(%d,%ld)\n",
  257. s, 0, s);
  258. Bprint(&bso, "%6lux %P\n",
  259. p->pc, p);
  260. }
  261. lcsize += 5;
  262. continue;
  263. }
  264. if(s > 0) {
  265. cput(0+s); /* 1-64 +lc */
  266. if(debug['V']) {
  267. Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
  268. Bprint(&bso, "%6lux %P\n",
  269. p->pc, p);
  270. }
  271. } else {
  272. cput(64-s); /* 65-128 -lc */
  273. if(debug['V']) {
  274. Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
  275. Bprint(&bso, "%6lux %P\n",
  276. p->pc, p);
  277. }
  278. }
  279. lcsize++;
  280. }
  281. while(lcsize & 1) {
  282. s = 129;
  283. cput(s);
  284. lcsize++;
  285. }
  286. if(debug['v'] || debug['V'])
  287. Bprint(&bso, "lcsize = %ld\n", lcsize);
  288. Bflush(&bso);
  289. }
  290. int
  291. prefixof(Adr *a)
  292. {
  293. switch(a->type) {
  294. case D_INDIR+D_CS:
  295. return 0x2e;
  296. case D_INDIR+D_DS:
  297. return 0x3e;
  298. case D_INDIR+D_ES:
  299. return 0x26;
  300. case D_INDIR+D_FS:
  301. return 0x64;
  302. case D_INDIR+D_GS:
  303. return 0x65;
  304. }
  305. return 0;
  306. }
  307. int
  308. oclass(Adr *a)
  309. {
  310. int32_t v;
  311. if(a->type >= D_INDIR || a->index != D_NONE) {
  312. if(a->index != D_NONE && a->scale == 0) {
  313. if(a->type == D_ADDR) {
  314. switch(a->index) {
  315. case D_EXTERN:
  316. case D_STATIC:
  317. return Yi32;
  318. case D_AUTO:
  319. case D_PARAM:
  320. return Yiauto;
  321. }
  322. return Yxxx;
  323. }
  324. return Ycol;
  325. }
  326. return Ym;
  327. }
  328. switch(a->type)
  329. {
  330. case D_AL:
  331. return Yal;
  332. case D_AX:
  333. return Yax;
  334. case D_CL:
  335. return Ycl;
  336. case D_DL:
  337. case D_BL:
  338. case D_AH:
  339. case D_CH:
  340. case D_DH:
  341. case D_BH:
  342. return Yrb;
  343. case D_CX:
  344. return Ycx;
  345. case D_DX:
  346. case D_BX:
  347. return Yrx;
  348. case D_SP:
  349. case D_BP:
  350. case D_SI:
  351. case D_DI:
  352. return Yrl;
  353. case D_F0+0:
  354. return Yf0;
  355. case D_F0+1:
  356. case D_F0+2:
  357. case D_F0+3:
  358. case D_F0+4:
  359. case D_F0+5:
  360. case D_F0+6:
  361. case D_F0+7:
  362. return Yrf;
  363. case D_NONE:
  364. return Ynone;
  365. case D_CS: return Ycs;
  366. case D_SS: return Yss;
  367. case D_DS: return Yds;
  368. case D_ES: return Yes;
  369. case D_FS: return Yfs;
  370. case D_GS: return Ygs;
  371. case D_GDTR: return Ygdtr;
  372. case D_IDTR: return Yidtr;
  373. case D_LDTR: return Yldtr;
  374. case D_MSW: return Ymsw;
  375. case D_TASK: return Ytask;
  376. case D_CR+0: return Ycr0;
  377. case D_CR+1: return Ycr1;
  378. case D_CR+2: return Ycr2;
  379. case D_CR+3: return Ycr3;
  380. case D_CR+4: return Ycr4;
  381. case D_CR+5: return Ycr5;
  382. case D_CR+6: return Ycr6;
  383. case D_CR+7: return Ycr7;
  384. case D_DR+0: return Ydr0;
  385. case D_DR+1: return Ydr1;
  386. case D_DR+2: return Ydr2;
  387. case D_DR+3: return Ydr3;
  388. case D_DR+4: return Ydr4;
  389. case D_DR+5: return Ydr5;
  390. case D_DR+6: return Ydr6;
  391. case D_DR+7: return Ydr7;
  392. case D_TR+0: return Ytr0;
  393. case D_TR+1: return Ytr1;
  394. case D_TR+2: return Ytr2;
  395. case D_TR+3: return Ytr3;
  396. case D_TR+4: return Ytr4;
  397. case D_TR+5: return Ytr5;
  398. case D_TR+6: return Ytr6;
  399. case D_TR+7: return Ytr7;
  400. case D_EXTERN:
  401. case D_STATIC:
  402. case D_AUTO:
  403. case D_PARAM:
  404. return Ym;
  405. case D_CONST:
  406. case D_ADDR:
  407. if(a->sym == S) {
  408. v = a->offset;
  409. if(v == 0)
  410. return Yi0;
  411. if(v == 1)
  412. return Yi1;
  413. if(v >= -128 && v <= 127)
  414. return Yi8;
  415. }
  416. return Yi32;
  417. case D_BRANCH:
  418. return Ybr;
  419. }
  420. return Yxxx;
  421. }
  422. void
  423. asmidx(Adr *a, int base)
  424. {
  425. int i;
  426. switch(a->index) {
  427. default:
  428. goto bad;
  429. case D_NONE:
  430. i = 4 << 3;
  431. goto bas;
  432. case D_AX:
  433. case D_CX:
  434. case D_DX:
  435. case D_BX:
  436. case D_BP:
  437. case D_SI:
  438. case D_DI:
  439. i = reg[a->index] << 3;
  440. break;
  441. }
  442. switch(a->scale) {
  443. default:
  444. goto bad;
  445. case 1:
  446. break;
  447. case 2:
  448. i |= (1<<6);
  449. break;
  450. case 4:
  451. i |= (2<<6);
  452. break;
  453. case 8:
  454. i |= (3<<6);
  455. break;
  456. }
  457. bas:
  458. switch(base) {
  459. default:
  460. goto bad;
  461. case D_NONE: /* must be mod=00 */
  462. i |= 5;
  463. break;
  464. case D_AX:
  465. case D_CX:
  466. case D_DX:
  467. case D_BX:
  468. case D_SP:
  469. case D_BP:
  470. case D_SI:
  471. case D_DI:
  472. i |= reg[base];
  473. break;
  474. }
  475. *andptr++ = i;
  476. return;
  477. bad:
  478. diag("asmidx: bad address %D", a);
  479. *andptr++ = 0;
  480. return;
  481. }
  482. static void
  483. put4(int32_t v)
  484. {
  485. if(dlm && curp != P && reloca != nil){
  486. dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1);
  487. reloca = nil;
  488. }
  489. andptr[0] = v;
  490. andptr[1] = v>>8;
  491. andptr[2] = v>>16;
  492. andptr[3] = v>>24;
  493. andptr += 4;
  494. }
  495. int32_t
  496. vaddr(Adr *a)
  497. {
  498. int t;
  499. int32_t v;
  500. Sym *s;
  501. t = a->type;
  502. v = a->offset;
  503. if(t == D_ADDR)
  504. t = a->index;
  505. switch(t) {
  506. case D_STATIC:
  507. case D_EXTERN:
  508. s = a->sym;
  509. if(s != nil) {
  510. if(dlm && curp != P)
  511. reloca = a;
  512. switch(s->type) {
  513. case SUNDEF:
  514. ckoff(s, v);
  515. case STEXT:
  516. case SCONST:
  517. v += s->value;
  518. break;
  519. default:
  520. v += INITDAT + s->value;
  521. }
  522. }
  523. }
  524. return v;
  525. }
  526. void
  527. asmand(Adr *a, int r)
  528. {
  529. int32_t v;
  530. int t;
  531. Adr aa;
  532. v = a->offset;
  533. t = a->type;
  534. if(a->index != D_NONE) {
  535. if(t >= D_INDIR) {
  536. t -= D_INDIR;
  537. if(t == D_NONE) {
  538. *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
  539. asmidx(a, t);
  540. put4(v);
  541. return;
  542. }
  543. if(v == 0 && t != D_BP) {
  544. *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
  545. asmidx(a, t);
  546. return;
  547. }
  548. if(v >= -128 && v < 128) {
  549. *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
  550. asmidx(a, t);
  551. *andptr++ = v;
  552. return;
  553. }
  554. *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
  555. asmidx(a, t);
  556. put4(v);
  557. return;
  558. }
  559. switch(t) {
  560. default:
  561. goto bad;
  562. case D_STATIC:
  563. case D_EXTERN:
  564. aa.type = D_NONE+D_INDIR;
  565. break;
  566. case D_AUTO:
  567. case D_PARAM:
  568. aa.type = D_SP+D_INDIR;
  569. break;
  570. }
  571. aa.offset = vaddr(a);
  572. aa.index = a->index;
  573. aa.scale = a->scale;
  574. asmand(&aa, r);
  575. return;
  576. }
  577. if(t >= D_AL && t <= D_F0+7) {
  578. if(v)
  579. goto bad;
  580. *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
  581. return;
  582. }
  583. if(t >= D_INDIR) {
  584. t -= D_INDIR;
  585. if(t == D_NONE || D_CS <= t && t <= D_GS) {
  586. *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
  587. put4(v);
  588. return;
  589. }
  590. if(t == D_SP) {
  591. if(v == 0) {
  592. *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
  593. asmidx(a, D_SP);
  594. return;
  595. }
  596. if(v >= -128 && v < 128) {
  597. *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
  598. asmidx(a, D_SP);
  599. *andptr++ = v;
  600. return;
  601. }
  602. *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
  603. asmidx(a, D_SP);
  604. put4(v);
  605. return;
  606. }
  607. if(t >= D_AX && t <= D_DI) {
  608. if(v == 0 && t != D_BP) {
  609. *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
  610. return;
  611. }
  612. if(v >= -128 && v < 128) {
  613. andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
  614. andptr[1] = v;
  615. andptr += 2;
  616. return;
  617. }
  618. *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
  619. put4(v);
  620. return;
  621. }
  622. goto bad;
  623. }
  624. switch(a->type) {
  625. default:
  626. goto bad;
  627. case D_STATIC:
  628. case D_EXTERN:
  629. aa.type = D_NONE+D_INDIR;
  630. break;
  631. case D_AUTO:
  632. case D_PARAM:
  633. aa.type = D_SP+D_INDIR;
  634. break;
  635. }
  636. aa.index = D_NONE;
  637. aa.scale = 1;
  638. aa.offset = vaddr(a);
  639. asmand(&aa, r);
  640. return;
  641. bad:
  642. diag("asmand: bad address %D", a);
  643. return;
  644. }
  645. #define E 0xff
  646. uint8_t ymovtab[] =
  647. {
  648. /* push */
  649. APUSHL, Ycs, Ynone, 0, 0x0e,E,0,0,
  650. APUSHL, Yss, Ynone, 0, 0x16,E,0,0,
  651. APUSHL, Yds, Ynone, 0, 0x1e,E,0,0,
  652. APUSHL, Yes, Ynone, 0, 0x06,E,0,0,
  653. APUSHL, Yfs, Ynone, 0, 0x0f,0xa0,E,0,
  654. APUSHL, Ygs, Ynone, 0, 0x0f,0xa8,E,0,
  655. APUSHW, Ycs, Ynone, 0, Pe,0x0e,E,0,
  656. APUSHW, Yss, Ynone, 0, Pe,0x16,E,0,
  657. APUSHW, Yds, Ynone, 0, Pe,0x1e,E,0,
  658. APUSHW, Yes, Ynone, 0, Pe,0x06,E,0,
  659. APUSHW, Yfs, Ynone, 0, Pe,0x0f,0xa0,E,
  660. APUSHW, Ygs, Ynone, 0, Pe,0x0f,0xa8,E,
  661. /* pop */
  662. APOPL, Ynone, Yds, 0, 0x1f,E,0,0,
  663. APOPL, Ynone, Yes, 0, 0x07,E,0,0,
  664. APOPL, Ynone, Yss, 0, 0x17,E,0,0,
  665. APOPL, Ynone, Yfs, 0, 0x0f,0xa1,E,0,
  666. APOPL, Ynone, Ygs, 0, 0x0f,0xa9,E,0,
  667. APOPW, Ynone, Yds, 0, Pe,0x1f,E,0,
  668. APOPW, Ynone, Yes, 0, Pe,0x07,E,0,
  669. APOPW, Ynone, Yss, 0, Pe,0x17,E,0,
  670. APOPW, Ynone, Yfs, 0, Pe,0x0f,0xa1,E,
  671. APOPW, Ynone, Ygs, 0, Pe,0x0f,0xa9,E,
  672. /* mov seg */
  673. AMOVW, Yes, Yml, 1, 0x8c,0,0,0,
  674. AMOVW, Ycs, Yml, 1, 0x8c,1,0,0,
  675. AMOVW, Yss, Yml, 1, 0x8c,2,0,0,
  676. AMOVW, Yds, Yml, 1, 0x8c,3,0,0,
  677. AMOVW, Yfs, Yml, 1, 0x8c,4,0,0,
  678. AMOVW, Ygs, Yml, 1, 0x8c,5,0,0,
  679. AMOVW, Yml, Yes, 2, 0x8e,0,0,0,
  680. AMOVW, Yml, Ycs, 2, 0x8e,1,0,0,
  681. AMOVW, Yml, Yss, 2, 0x8e,2,0,0,
  682. AMOVW, Yml, Yds, 2, 0x8e,3,0,0,
  683. AMOVW, Yml, Yfs, 2, 0x8e,4,0,0,
  684. AMOVW, Yml, Ygs, 2, 0x8e,5,0,0,
  685. /* mov cr */
  686. AMOVL, Ycr0, Yml, 3, 0x0f,0x20,0,0,
  687. AMOVL, Ycr2, Yml, 3, 0x0f,0x20,2,0,
  688. AMOVL, Ycr3, Yml, 3, 0x0f,0x20,3,0,
  689. AMOVL, Ycr4, Yml, 3, 0x0f,0x20,4,0,
  690. AMOVL, Yml, Ycr0, 4, 0x0f,0x22,0,0,
  691. AMOVL, Yml, Ycr2, 4, 0x0f,0x22,2,0,
  692. AMOVL, Yml, Ycr3, 4, 0x0f,0x22,3,0,
  693. AMOVL, Yml, Ycr4, 4, 0x0f,0x22,4,0,
  694. /* mov dr */
  695. AMOVL, Ydr0, Yml, 3, 0x0f,0x21,0,0,
  696. AMOVL, Ydr6, Yml, 3, 0x0f,0x21,6,0,
  697. AMOVL, Ydr7, Yml, 3, 0x0f,0x21,7,0,
  698. AMOVL, Yml, Ydr0, 4, 0x0f,0x23,0,0,
  699. AMOVL, Yml, Ydr6, 4, 0x0f,0x23,6,0,
  700. AMOVL, Yml, Ydr7, 4, 0x0f,0x23,7,0,
  701. /* mov tr */
  702. AMOVL, Ytr6, Yml, 3, 0x0f,0x24,6,0,
  703. AMOVL, Ytr7, Yml, 3, 0x0f,0x24,7,0,
  704. AMOVL, Yml, Ytr6, 4, 0x0f,0x26,6,E,
  705. AMOVL, Yml, Ytr7, 4, 0x0f,0x26,7,E,
  706. /* lgdt, sgdt, lidt, sidt */
  707. AMOVL, Ym, Ygdtr, 4, 0x0f,0x01,2,0,
  708. AMOVL, Ygdtr, Ym, 3, 0x0f,0x01,0,0,
  709. AMOVL, Ym, Yidtr, 4, 0x0f,0x01,3,0,
  710. AMOVL, Yidtr, Ym, 3, 0x0f,0x01,1,0,
  711. /* lldt, sldt */
  712. AMOVW, Yml, Yldtr, 4, 0x0f,0x00,2,0,
  713. AMOVW, Yldtr, Yml, 3, 0x0f,0x00,0,0,
  714. /* lmsw, smsw */
  715. AMOVW, Yml, Ymsw, 4, 0x0f,0x01,6,0,
  716. AMOVW, Ymsw, Yml, 3, 0x0f,0x01,4,0,
  717. /* ltr, str */
  718. AMOVW, Yml, Ytask, 4, 0x0f,0x00,3,0,
  719. AMOVW, Ytask, Yml, 3, 0x0f,0x00,1,0,
  720. /* load full pointer */
  721. AMOVL, Yml, Ycol, 5, 0,0,0,0,
  722. AMOVW, Yml, Ycol, 5, Pe,0,0,0,
  723. /* double shift */
  724. ASHLL, Ycol, Yml, 6, 0xa4,0xa5,0,0,
  725. ASHRL, Ycol, Yml, 6, 0xac,0xad,0,0,
  726. /* extra imul */
  727. AIMULW, Yml, Yrl, 7, Pq,0xaf,0,0,
  728. AIMULL, Yml, Yrl, 7, Pm,0xaf,0,0,
  729. 0
  730. };
  731. int
  732. isax(Adr *a)
  733. {
  734. switch(a->type) {
  735. case D_AX:
  736. case D_AL:
  737. case D_AH:
  738. case D_INDIR+D_AX:
  739. return 1;
  740. }
  741. if(a->index == D_AX)
  742. return 1;
  743. return 0;
  744. }
  745. void
  746. subreg(Prog *p, int from, int to)
  747. {
  748. if(debug['Q'])
  749. print("\n%P s/%R/%R/\n", p, from, to);
  750. if(p->from.type == from)
  751. p->from.type = to;
  752. if(p->to.type == from)
  753. p->to.type = to;
  754. if(p->from.index == from)
  755. p->from.index = to;
  756. if(p->to.index == from)
  757. p->to.index = to;
  758. from += D_INDIR;
  759. if(p->from.type == from)
  760. p->from.type = to+D_INDIR;
  761. if(p->to.type == from)
  762. p->to.type = to+D_INDIR;
  763. if(debug['Q'])
  764. print("%P\n", p);
  765. }
  766. void
  767. doasm(Prog *p)
  768. {
  769. Optab *o;
  770. Prog *q, pp;
  771. uint8_t *t;
  772. int z, op, ft, tt;
  773. int32_t v, pre;
  774. pre = prefixof(&p->from);
  775. if(pre)
  776. *andptr++ = pre;
  777. pre = prefixof(&p->to);
  778. if(pre)
  779. *andptr++ = pre;
  780. o = &optab[p->as];
  781. ft = oclass(&p->from) * Ymax;
  782. tt = oclass(&p->to) * Ymax;
  783. t = o->ytab;
  784. if(t == 0) {
  785. diag("asmins: noproto %P", p);
  786. return;
  787. }
  788. for(z=0; *t; z+=t[3],t+=4)
  789. if(ycover[ft+t[0]])
  790. if(ycover[tt+t[1]])
  791. goto found;
  792. goto domov;
  793. found:
  794. switch(o->prefix) {
  795. case Pq: /* 16 bit escape and opcode escape */
  796. *andptr++ = Pe;
  797. *andptr++ = Pm;
  798. break;
  799. case Pm: /* opcode escape */
  800. *andptr++ = Pm;
  801. break;
  802. case Pe: /* 16 bit escape */
  803. *andptr++ = Pe;
  804. break;
  805. case Pb: /* botch */
  806. break;
  807. }
  808. v = vaddr(&p->from);
  809. op = o->op[z];
  810. switch(t[2]) {
  811. default:
  812. diag("asmins: unknown z %d %P", t[2], p);
  813. return;
  814. case Zpseudo:
  815. break;
  816. case Zlit:
  817. for(; op = o->op[z]; z++)
  818. *andptr++ = op;
  819. break;
  820. case Zm_r:
  821. *andptr++ = op;
  822. asmand(&p->from, reg[p->to.type]);
  823. break;
  824. case Zaut_r:
  825. *andptr++ = 0x8d; /* leal */
  826. if(p->from.type != D_ADDR)
  827. diag("asmins: Zaut sb type ADDR");
  828. p->from.type = p->from.index;
  829. p->from.index = D_NONE;
  830. asmand(&p->from, reg[p->to.type]);
  831. p->from.index = p->from.type;
  832. p->from.type = D_ADDR;
  833. break;
  834. case Zm_o:
  835. *andptr++ = op;
  836. asmand(&p->from, o->op[z+1]);
  837. break;
  838. case Zr_m:
  839. *andptr++ = op;
  840. asmand(&p->to, reg[p->from.type]);
  841. break;
  842. case Zo_m:
  843. *andptr++ = op;
  844. asmand(&p->to, o->op[z+1]);
  845. break;
  846. case Zm_ibo:
  847. v = vaddr(&p->to);
  848. *andptr++ = op;
  849. asmand(&p->from, o->op[z+1]);
  850. *andptr++ = v;
  851. break;
  852. case Zibo_m:
  853. *andptr++ = op;
  854. asmand(&p->to, o->op[z+1]);
  855. *andptr++ = v;
  856. break;
  857. case Z_ib:
  858. v = vaddr(&p->to);
  859. case Zib_:
  860. *andptr++ = op;
  861. *andptr++ = v;
  862. break;
  863. case Zib_rp:
  864. *andptr++ = op + reg[p->to.type];
  865. *andptr++ = v;
  866. break;
  867. case Zil_rp:
  868. *andptr++ = op + reg[p->to.type];
  869. if(o->prefix == Pe) {
  870. *andptr++ = v;
  871. *andptr++ = v>>8;
  872. }
  873. else
  874. put4(v);
  875. break;
  876. case Zib_rr:
  877. *andptr++ = op;
  878. asmand(&p->to, reg[p->to.type]);
  879. *andptr++ = v;
  880. break;
  881. case Z_il:
  882. v = vaddr(&p->to);
  883. case Zil_:
  884. *andptr++ = op;
  885. if(o->prefix == Pe) {
  886. *andptr++ = v;
  887. *andptr++ = v>>8;
  888. }
  889. else
  890. put4(v);
  891. break;
  892. case Zm_ilo:
  893. v = vaddr(&p->to);
  894. *andptr++ = op;
  895. asmand(&p->from, o->op[z+1]);
  896. if(o->prefix == Pe) {
  897. *andptr++ = v;
  898. *andptr++ = v>>8;
  899. }
  900. else
  901. put4(v);
  902. break;
  903. case Zilo_m:
  904. *andptr++ = op;
  905. asmand(&p->to, o->op[z+1]);
  906. if(o->prefix == Pe) {
  907. *andptr++ = v;
  908. *andptr++ = v>>8;
  909. }
  910. else
  911. put4(v);
  912. break;
  913. case Zil_rr:
  914. *andptr++ = op;
  915. asmand(&p->to, reg[p->to.type]);
  916. if(o->prefix == Pe) {
  917. *andptr++ = v;
  918. *andptr++ = v>>8;
  919. }
  920. else
  921. put4(v);
  922. break;
  923. case Z_rp:
  924. *andptr++ = op + reg[p->to.type];
  925. break;
  926. case Zrp_:
  927. *andptr++ = op + reg[p->from.type];
  928. break;
  929. case Zclr:
  930. *andptr++ = op;
  931. asmand(&p->to, reg[p->to.type]);
  932. break;
  933. case Zbr:
  934. q = p->pcond;
  935. if(q) {
  936. v = q->pc - p->pc - 2;
  937. if(v >= -128 && v <= 127) {
  938. *andptr++ = op;
  939. *andptr++ = v;
  940. } else {
  941. v -= 6-2;
  942. *andptr++ = 0x0f;
  943. *andptr++ = o->op[z+1];
  944. *andptr++ = v;
  945. *andptr++ = v>>8;
  946. *andptr++ = v>>16;
  947. *andptr++ = v>>24;
  948. }
  949. }
  950. break;
  951. case Zcall:
  952. q = p->pcond;
  953. if(q) {
  954. v = q->pc - p->pc - 5;
  955. if(dlm && curp != P && p->to.sym->type == SUNDEF){
  956. /* v = 0 - p->pc - 5; */
  957. v = 0;
  958. ckoff(p->to.sym, v);
  959. v += p->to.sym->value;
  960. dynreloc(p->to.sym, p->pc+1, 0);
  961. }
  962. *andptr++ = op;
  963. *andptr++ = v;
  964. *andptr++ = v>>8;
  965. *andptr++ = v>>16;
  966. *andptr++ = v>>24;
  967. }
  968. break;
  969. case Zjmp:
  970. q = p->pcond;
  971. if(q) {
  972. v = q->pc - p->pc - 2;
  973. if(v >= -128 && v <= 127) {
  974. *andptr++ = op;
  975. *andptr++ = v;
  976. } else {
  977. v -= 5-2;
  978. *andptr++ = o->op[z+1];
  979. *andptr++ = v;
  980. *andptr++ = v>>8;
  981. *andptr++ = v>>16;
  982. *andptr++ = v>>24;
  983. }
  984. }
  985. break;
  986. case Zloop:
  987. q = p->pcond;
  988. if(q) {
  989. v = q->pc - p->pc - 2;
  990. if(v < -128 || v > 127)
  991. diag("loop too far: %P", p);
  992. *andptr++ = op;
  993. *andptr++ = v;
  994. }
  995. break;
  996. case Zbyte:
  997. *andptr++ = v;
  998. if(op > 1) {
  999. *andptr++ = v>>8;
  1000. if(op > 2) {
  1001. *andptr++ = v>>16;
  1002. *andptr++ = v>>24;
  1003. }
  1004. }
  1005. break;
  1006. case Zmov:
  1007. goto domov;
  1008. }
  1009. return;
  1010. domov:
  1011. for(t=ymovtab; *t; t+=8)
  1012. if(p->as == t[0])
  1013. if(ycover[ft+t[1]])
  1014. if(ycover[tt+t[2]])
  1015. goto mfound;
  1016. bad:
  1017. /*
  1018. * here, the assembly has failed.
  1019. * if its a byte instruction that has
  1020. * unaddressable registers, try to
  1021. * exchange registers and reissue the
  1022. * instruction with the operands renamed.
  1023. */
  1024. pp = *p;
  1025. z = p->from.type;
  1026. if(z >= D_BP && z <= D_DI) {
  1027. if(isax(&p->to)) {
  1028. *andptr++ = 0x87; /* xchg lhs,bx */
  1029. asmand(&p->from, reg[D_BX]);
  1030. subreg(&pp, z, D_BX);
  1031. doasm(&pp);
  1032. *andptr++ = 0x87; /* xchg lhs,bx */
  1033. asmand(&p->from, reg[D_BX]);
  1034. } else {
  1035. *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
  1036. subreg(&pp, z, D_AX);
  1037. doasm(&pp);
  1038. *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
  1039. }
  1040. return;
  1041. }
  1042. z = p->to.type;
  1043. if(z >= D_BP && z <= D_DI) {
  1044. if(isax(&p->from)) {
  1045. *andptr++ = 0x87; /* xchg rhs,bx */
  1046. asmand(&p->to, reg[D_BX]);
  1047. subreg(&pp, z, D_BX);
  1048. doasm(&pp);
  1049. *andptr++ = 0x87; /* xchg rhs,bx */
  1050. asmand(&p->to, reg[D_BX]);
  1051. } else {
  1052. *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
  1053. subreg(&pp, z, D_AX);
  1054. doasm(&pp);
  1055. *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
  1056. }
  1057. return;
  1058. }
  1059. diag("doasm: notfound t2=%ux from=%ux to=%ux %P", t[2], p->from.type, p->to.type, p);
  1060. return;
  1061. mfound:
  1062. switch(t[3]) {
  1063. default:
  1064. diag("asmins: unknown mov %d %P", t[3], p);
  1065. break;
  1066. case 0: /* lit */
  1067. for(z=4; t[z]!=E; z++)
  1068. *andptr++ = t[z];
  1069. break;
  1070. case 1: /* r,m */
  1071. *andptr++ = t[4];
  1072. asmand(&p->to, t[5]);
  1073. break;
  1074. case 2: /* m,r */
  1075. *andptr++ = t[4];
  1076. asmand(&p->from, t[5]);
  1077. break;
  1078. case 3: /* r,m - 2op */
  1079. *andptr++ = t[4];
  1080. *andptr++ = t[5];
  1081. asmand(&p->to, t[6]);
  1082. break;
  1083. case 4: /* m,r - 2op */
  1084. *andptr++ = t[4];
  1085. *andptr++ = t[5];
  1086. asmand(&p->from, t[6]);
  1087. break;
  1088. case 5: /* load full pointer, trash heap */
  1089. if(t[4])
  1090. *andptr++ = t[4];
  1091. switch(p->to.index) {
  1092. default:
  1093. goto bad;
  1094. case D_DS:
  1095. *andptr++ = 0xc5;
  1096. break;
  1097. case D_SS:
  1098. *andptr++ = 0x0f;
  1099. *andptr++ = 0xb2;
  1100. break;
  1101. case D_ES:
  1102. *andptr++ = 0xc4;
  1103. break;
  1104. case D_FS:
  1105. *andptr++ = 0x0f;
  1106. *andptr++ = 0xb4;
  1107. break;
  1108. case D_GS:
  1109. *andptr++ = 0x0f;
  1110. *andptr++ = 0xb5;
  1111. break;
  1112. }
  1113. asmand(&p->from, reg[p->to.type]);
  1114. break;
  1115. case 6: /* double shift */
  1116. z = p->from.type;
  1117. switch(z) {
  1118. default:
  1119. goto bad;
  1120. case D_CONST:
  1121. *andptr++ = 0x0f;
  1122. *andptr++ = t[4];
  1123. asmand(&p->to, reg[p->from.index]);
  1124. *andptr++ = p->from.offset;
  1125. break;
  1126. case D_CL:
  1127. case D_CX:
  1128. *andptr++ = 0x0f;
  1129. *andptr++ = t[5];
  1130. asmand(&p->to, reg[p->from.index]);
  1131. break;
  1132. }
  1133. break;
  1134. case 7: /* imul rm,r */
  1135. *andptr++ = t[4];
  1136. *andptr++ = t[5];
  1137. asmand(&p->from, reg[p->to.type]);
  1138. break;
  1139. }
  1140. }
  1141. void
  1142. asmins(Prog *p)
  1143. {
  1144. andptr = and;
  1145. doasm(p);
  1146. }
  1147. enum{
  1148. ABSD = 0,
  1149. ABSU = 1,
  1150. RELD = 2,
  1151. RELU = 3,
  1152. };
  1153. int modemap[4] = { 0, 1, -1, 2, };
  1154. typedef struct Reloc Reloc;
  1155. struct Reloc
  1156. {
  1157. int n;
  1158. int t;
  1159. uint8_t *m;
  1160. uint32_t *a;
  1161. };
  1162. Reloc rels;
  1163. static void
  1164. grow(Reloc *r)
  1165. {
  1166. int t;
  1167. uint8_t *m, *nm;
  1168. uint32_t *a, *na;
  1169. t = r->t;
  1170. r->t += 64;
  1171. m = r->m;
  1172. a = r->a;
  1173. r->m = nm = malloc(r->t*sizeof(uint8_t));
  1174. r->a = na = malloc(r->t*sizeof(uint32_t));
  1175. memmove(nm, m, t*sizeof(uint8_t));
  1176. memmove(na, a, t*sizeof(uint32_t));
  1177. free(m);
  1178. free(a);
  1179. }
  1180. void
  1181. dynreloc(Sym *s, uint32_t v, int abs)
  1182. {
  1183. int i, k, n;
  1184. uint8_t *m;
  1185. uint32_t *a;
  1186. Reloc *r;
  1187. if(s->type == SUNDEF)
  1188. k = abs ? ABSU : RELU;
  1189. else
  1190. k = abs ? ABSD : RELD;
  1191. /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, v, v, k); */
  1192. k = modemap[k];
  1193. r = &rels;
  1194. n = r->n;
  1195. if(n >= r->t)
  1196. grow(r);
  1197. m = r->m;
  1198. a = r->a;
  1199. for(i = n; i > 0; i--){
  1200. if(v < a[i-1]){ /* happens occasionally for data */
  1201. m[i] = m[i-1];
  1202. a[i] = a[i-1];
  1203. }
  1204. else
  1205. break;
  1206. }
  1207. m[i] = k;
  1208. a[i] = v;
  1209. r->n++;
  1210. }
  1211. static int
  1212. sput(char *s)
  1213. {
  1214. char *p;
  1215. p = s;
  1216. while(*s)
  1217. cput(*s++);
  1218. cput(0);
  1219. return s-p+1;
  1220. }
  1221. void
  1222. asmdyn()
  1223. {
  1224. int i, n, t, c;
  1225. Sym *s;
  1226. uint32_t la, ra, *a;
  1227. int64_t off;
  1228. uint8_t *m;
  1229. Reloc *r;
  1230. cflush();
  1231. off = seek(cout, 0, 1);
  1232. lput(0);
  1233. t = 0;
  1234. lput(imports);
  1235. t += 4;
  1236. for(i = 0; i < NHASH; i++)
  1237. for(s = hash[i]; s != S; s = s->link)
  1238. if(s->type == SUNDEF){
  1239. lput(s->sig);
  1240. t += 4;
  1241. t += sput(s->name);
  1242. }
  1243. la = 0;
  1244. r = &rels;
  1245. n = r->n;
  1246. m = r->m;
  1247. a = r->a;
  1248. lput(n);
  1249. t += 4;
  1250. for(i = 0; i < n; i++){
  1251. ra = *a-la;
  1252. if(*a < la)
  1253. diag("bad relocation order");
  1254. if(ra < 256)
  1255. c = 0;
  1256. else if(ra < 65536)
  1257. c = 1;
  1258. else
  1259. c = 2;
  1260. cput((c<<6)|*m++);
  1261. t++;
  1262. if(c == 0){
  1263. cput(ra);
  1264. t++;
  1265. }
  1266. else if(c == 1){
  1267. wput(ra);
  1268. t += 2;
  1269. }
  1270. else{
  1271. lput(ra);
  1272. t += 4;
  1273. }
  1274. la = *a++;
  1275. }
  1276. cflush();
  1277. seek(cout, off, 0);
  1278. lput(t);
  1279. if(debug['v']){
  1280. Bprint(&bso, "import table entries = %d\n", imports);
  1281. Bprint(&bso, "export table entries = %d\n", exports);
  1282. }
  1283. }