span.c 23 KB

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