span.c 22 KB

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