span.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757
  1. #include "l.h"
  2. static int rexflag;
  3. static int asmode;
  4. void
  5. span(void)
  6. {
  7. Prog *p, *q;
  8. long v;
  9. vlong c, idat;
  10. int m, n, again;
  11. xdefine("etext", STEXT, 0L);
  12. idat = INITDAT;
  13. for(p = firstp; p != P; p = p->link) {
  14. if(p->as == ATEXT)
  15. curtext = p;
  16. n = 0;
  17. if(p->to.type == D_BRANCH)
  18. if(p->pcond == P)
  19. p->pcond = p;
  20. if((q = p->pcond) != P)
  21. if(q->back != 2)
  22. n = 1;
  23. p->back = n;
  24. if(p->as == AADJSP) {
  25. p->to.type = D_SP;
  26. v = -p->from.offset;
  27. p->from.offset = v;
  28. p->as = p->mode != 64? AADDL: AADDQ;
  29. if(v < 0) {
  30. p->as = p->mode != 64? ASUBL: ASUBQ;
  31. v = -v;
  32. p->from.offset = v;
  33. }
  34. if(v == 0)
  35. p->as = ANOP;
  36. }
  37. }
  38. n = 0;
  39. start:
  40. if(debug['v'])
  41. Bprint(&bso, "%5.2f span\n", cputime());
  42. Bflush(&bso);
  43. c = INITTEXT;
  44. for(p = firstp; p != P; p = p->link) {
  45. if(p->as == ATEXT)
  46. curtext = p;
  47. if(p->to.type == D_BRANCH)
  48. if(p->back)
  49. p->pc = c;
  50. asmins(p);
  51. p->pc = c;
  52. m = andptr-and;
  53. p->mark = m;
  54. c += m;
  55. }
  56. loop:
  57. n++;
  58. if(debug['v'])
  59. Bprint(&bso, "%5.2f span %d\n", cputime(), n);
  60. Bflush(&bso);
  61. if(n > 50) {
  62. print("span must be looping\n");
  63. errorexit();
  64. }
  65. again = 0;
  66. c = INITTEXT;
  67. for(p = firstp; p != P; p = p->link) {
  68. if(p->as == ATEXT)
  69. curtext = p;
  70. if(p->to.type == D_BRANCH || p->back & 0100) {
  71. if(p->back)
  72. p->pc = c;
  73. asmins(p);
  74. m = andptr-and;
  75. if(m != p->mark) {
  76. p->mark = m;
  77. again++;
  78. }
  79. }
  80. p->pc = c;
  81. c += p->mark;
  82. }
  83. if(again) {
  84. textsize = c;
  85. goto loop;
  86. }
  87. if(INITRND) {
  88. INITDAT = rnd(c, INITRND);
  89. if(INITDAT != idat) {
  90. idat = INITDAT;
  91. goto start;
  92. }
  93. }
  94. xdefine("etext", STEXT, c);
  95. if(debug['v'])
  96. Bprint(&bso, "etext = %llux\n", c);
  97. Bflush(&bso);
  98. for(p = textp; p != P; p = p->pcond)
  99. p->from.sym->value = p->pc;
  100. textsize = c - INITTEXT;
  101. }
  102. void
  103. xdefine(char *p, int t, vlong v)
  104. {
  105. Sym *s;
  106. s = lookup(p, 0);
  107. if(s->type == 0 || s->type == SXREF) {
  108. s->type = t;
  109. s->value = v;
  110. }
  111. if(s->type == STEXT && s->value == 0)
  112. s->value = v;
  113. }
  114. void
  115. putsymb(char *s, int t, vlong v, int ver)
  116. {
  117. int i, f, l;
  118. if(t == 'f')
  119. s++;
  120. l = 4;
  121. switch(HEADTYPE){
  122. default:
  123. break;
  124. case 5:
  125. if(debug['8'])
  126. break;
  127. case 2:
  128. case 6:
  129. lput(v>>32);
  130. l = 8;
  131. break;
  132. }
  133. lput(v);
  134. if(ver)
  135. t += 'a' - 'A';
  136. cput(t+0x80); /* 0x80 is variable length */
  137. if(t == 'Z' || t == 'z') {
  138. cput(s[0]);
  139. for(i=1; s[i] != 0 || s[i+1] != 0; i += 2) {
  140. cput(s[i]);
  141. cput(s[i+1]);
  142. }
  143. cput(0);
  144. cput(0);
  145. i++;
  146. }
  147. else {
  148. for(i=0; s[i]; i++)
  149. cput(s[i]);
  150. cput(0);
  151. }
  152. symsize += l + 1 + i + 1;
  153. if(debug['n']) {
  154. if(t == 'z' || t == 'Z') {
  155. Bprint(&bso, "%c %.8llux ", t, v);
  156. for(i=1; s[i] != 0 || s[i+1] != 0; i+=2) {
  157. f = ((s[i]&0xff) << 8) | (s[i+1]&0xff);
  158. Bprint(&bso, "/%x", f);
  159. }
  160. Bprint(&bso, "\n");
  161. return;
  162. }
  163. if(ver)
  164. Bprint(&bso, "%c %.8llux %s<%d>\n", t, v, s, ver);
  165. else
  166. Bprint(&bso, "%c %.8llux %s\n", t, v, s);
  167. }
  168. }
  169. void
  170. asmsym(void)
  171. {
  172. Prog *p;
  173. Auto *a;
  174. Sym *s;
  175. int h;
  176. s = lookup("etext", 0);
  177. if(s->type == STEXT)
  178. putsymb(s->name, 'T', s->value, s->version);
  179. for(h=0; h<NHASH; h++)
  180. for(s=hash[h]; s!=S; s=s->link)
  181. switch(s->type) {
  182. case SCONST:
  183. putsymb(s->name, 'D', s->value, s->version);
  184. continue;
  185. case SDATA:
  186. putsymb(s->name, 'D', s->value+INITDAT, s->version);
  187. continue;
  188. case SBSS:
  189. putsymb(s->name, 'B', s->value+INITDAT, s->version);
  190. continue;
  191. case SFILE:
  192. putsymb(s->name, 'f', s->value, s->version);
  193. continue;
  194. }
  195. for(p=textp; p!=P; p=p->pcond) {
  196. s = p->from.sym;
  197. if(s->type != STEXT)
  198. continue;
  199. /* filenames first */
  200. for(a=p->to.autom; a; a=a->link)
  201. if(a->type == D_FILE)
  202. putsymb(a->asym->name, 'z', a->aoffset, 0);
  203. else
  204. if(a->type == D_FILE1)
  205. putsymb(a->asym->name, 'Z', a->aoffset, 0);
  206. putsymb(s->name, 'T', s->value, s->version);
  207. /* frame, auto and param after */
  208. putsymb(".frame", 'm', p->to.offset+8, 0);
  209. for(a=p->to.autom; a; a=a->link)
  210. if(a->type == D_AUTO)
  211. putsymb(a->asym->name, 'a', -a->aoffset, 0);
  212. else
  213. if(a->type == D_PARAM)
  214. putsymb(a->asym->name, 'p', a->aoffset, 0);
  215. }
  216. if(debug['v'] || debug['n'])
  217. Bprint(&bso, "symsize = %lud\n", symsize);
  218. Bflush(&bso);
  219. }
  220. void
  221. asmlc(void)
  222. {
  223. vlong oldpc;
  224. Prog *p;
  225. long oldlc, v, s;
  226. oldpc = INITTEXT;
  227. oldlc = 0;
  228. for(p = firstp; p != P; p = p->link) {
  229. if(p->line == oldlc || p->as == ATEXT || p->as == ANOP) {
  230. if(p->as == ATEXT)
  231. curtext = p;
  232. if(debug['V'])
  233. Bprint(&bso, "%6llux %P\n",
  234. p->pc, p);
  235. continue;
  236. }
  237. if(debug['V'])
  238. Bprint(&bso, "\t\t%6ld", lcsize);
  239. v = (p->pc - oldpc) / MINLC;
  240. while(v) {
  241. s = 127;
  242. if(v < 127)
  243. s = v;
  244. cput(s+128); /* 129-255 +pc */
  245. if(debug['V'])
  246. Bprint(&bso, " pc+%ld*%d(%ld)", s, MINLC, s+128);
  247. v -= s;
  248. lcsize++;
  249. }
  250. s = p->line - oldlc;
  251. oldlc = p->line;
  252. oldpc = p->pc + MINLC;
  253. if(s > 64 || s < -64) {
  254. cput(0); /* 0 vv +lc */
  255. cput(s>>24);
  256. cput(s>>16);
  257. cput(s>>8);
  258. cput(s);
  259. if(debug['V']) {
  260. if(s > 0)
  261. Bprint(&bso, " lc+%ld(%d,%ld)\n",
  262. s, 0, s);
  263. else
  264. Bprint(&bso, " lc%ld(%d,%ld)\n",
  265. s, 0, s);
  266. Bprint(&bso, "%6llux %P\n",
  267. p->pc, p);
  268. }
  269. lcsize += 5;
  270. continue;
  271. }
  272. if(s > 0) {
  273. cput(0+s); /* 1-64 +lc */
  274. if(debug['V']) {
  275. Bprint(&bso, " lc+%ld(%ld)\n", s, 0+s);
  276. Bprint(&bso, "%6llux %P\n",
  277. p->pc, p);
  278. }
  279. } else {
  280. cput(64-s); /* 65-128 -lc */
  281. if(debug['V']) {
  282. Bprint(&bso, " lc%ld(%ld)\n", s, 64-s);
  283. Bprint(&bso, "%6llux %P\n",
  284. p->pc, p);
  285. }
  286. }
  287. lcsize++;
  288. }
  289. while(lcsize & 1) {
  290. s = 129;
  291. cput(s);
  292. lcsize++;
  293. }
  294. if(debug['v'] || debug['V'])
  295. Bprint(&bso, "lcsize = %ld\n", lcsize);
  296. Bflush(&bso);
  297. }
  298. int
  299. oclass(Adr *a)
  300. {
  301. vlong v;
  302. long l;
  303. if(a->type >= D_INDIR || a->index != D_NONE) {
  304. if(a->index != D_NONE && a->scale == 0) {
  305. if(a->type == D_ADDR) {
  306. switch(a->index) {
  307. case D_EXTERN:
  308. case D_STATIC:
  309. return Yi32; /* TO DO: Yi64 */
  310. case D_AUTO:
  311. case D_PARAM:
  312. return Yiauto;
  313. }
  314. return Yxxx;
  315. }
  316. return Ycol;
  317. }
  318. return Ym;
  319. }
  320. switch(a->type)
  321. {
  322. case D_AL:
  323. return Yal;
  324. case D_AX:
  325. return Yax;
  326. /*
  327. case D_SPB:
  328. */
  329. case D_BPB:
  330. case D_SIB:
  331. case D_DIB:
  332. case D_R8B:
  333. case D_R9B:
  334. case D_R10B:
  335. case D_R11B:
  336. case D_R12B:
  337. case D_R13B:
  338. case D_R14B:
  339. case D_R15B:
  340. if(asmode != 64)
  341. return Yxxx;
  342. case D_DL:
  343. case D_BL:
  344. case D_AH:
  345. case D_CH:
  346. case D_DH:
  347. case D_BH:
  348. return Yrb;
  349. case D_CL:
  350. return Ycl;
  351. case D_CX:
  352. return Ycx;
  353. case D_DX:
  354. case D_BX:
  355. return Yrx;
  356. case D_R8: /* not really Yrl */
  357. case D_R9:
  358. case D_R10:
  359. case D_R11:
  360. case D_R12:
  361. case D_R13:
  362. case D_R14:
  363. case D_R15:
  364. if(asmode != 64)
  365. return Yxxx;
  366. case D_SP:
  367. case D_BP:
  368. case D_SI:
  369. case D_DI:
  370. return Yrl;
  371. case D_F0+0:
  372. return Yf0;
  373. case D_F0+1:
  374. case D_F0+2:
  375. case D_F0+3:
  376. case D_F0+4:
  377. case D_F0+5:
  378. case D_F0+6:
  379. case D_F0+7:
  380. return Yrf;
  381. case D_M0+0:
  382. case D_M0+1:
  383. case D_M0+2:
  384. case D_M0+3:
  385. case D_M0+4:
  386. case D_M0+5:
  387. case D_M0+6:
  388. case D_M0+7:
  389. return Ymr;
  390. case D_X0+0:
  391. case D_X0+1:
  392. case D_X0+2:
  393. case D_X0+3:
  394. case D_X0+4:
  395. case D_X0+5:
  396. case D_X0+6:
  397. case D_X0+7:
  398. case D_X0+8:
  399. case D_X0+9:
  400. case D_X0+10:
  401. case D_X0+11:
  402. case D_X0+12:
  403. case D_X0+13:
  404. case D_X0+14:
  405. case D_X0+15:
  406. return Yxr;
  407. case D_NONE:
  408. return Ynone;
  409. case D_CS: return Ycs;
  410. case D_SS: return Yss;
  411. case D_DS: return Yds;
  412. case D_ES: return Yes;
  413. case D_FS: return Yfs;
  414. case D_GS: return Ygs;
  415. case D_GDTR: return Ygdtr;
  416. case D_IDTR: return Yidtr;
  417. case D_LDTR: return Yldtr;
  418. case D_MSW: return Ymsw;
  419. case D_TASK: return Ytask;
  420. case D_CR+0: return Ycr0;
  421. case D_CR+1: return Ycr1;
  422. case D_CR+2: return Ycr2;
  423. case D_CR+3: return Ycr3;
  424. case D_CR+4: return Ycr4;
  425. case D_CR+5: return Ycr5;
  426. case D_CR+6: return Ycr6;
  427. case D_CR+7: return Ycr7;
  428. case D_CR+8: return Ycr8;
  429. case D_DR+0: return Ydr0;
  430. case D_DR+1: return Ydr1;
  431. case D_DR+2: return Ydr2;
  432. case D_DR+3: return Ydr3;
  433. case D_DR+4: return Ydr4;
  434. case D_DR+5: return Ydr5;
  435. case D_DR+6: return Ydr6;
  436. case D_DR+7: return Ydr7;
  437. case D_TR+0: return Ytr0;
  438. case D_TR+1: return Ytr1;
  439. case D_TR+2: return Ytr2;
  440. case D_TR+3: return Ytr3;
  441. case D_TR+4: return Ytr4;
  442. case D_TR+5: return Ytr5;
  443. case D_TR+6: return Ytr6;
  444. case D_TR+7: return Ytr7;
  445. case D_EXTERN:
  446. case D_STATIC:
  447. case D_AUTO:
  448. case D_PARAM:
  449. return Ym;
  450. case D_CONST:
  451. case D_ADDR:
  452. if(a->sym == S) {
  453. v = a->offset;
  454. if(v == 0)
  455. return Yi0;
  456. if(v == 1)
  457. return Yi1;
  458. if(v >= -128 && v <= 127)
  459. return Yi8;
  460. l = v;
  461. if((vlong)l == v)
  462. return Ys32; /* can sign extend */
  463. if((v>>32) == 0)
  464. return Yi32; /* unsigned */
  465. return Yi64;
  466. }
  467. return Yi32; /* TO DO: D_ADDR as Yi64 */
  468. case D_BRANCH:
  469. return Ybr;
  470. }
  471. return Yxxx;
  472. }
  473. void
  474. asmidx(Adr *a, int base)
  475. {
  476. int i;
  477. switch(a->index) {
  478. default:
  479. goto bad;
  480. case D_NONE:
  481. i = 4 << 3;
  482. goto bas;
  483. case D_R8:
  484. case D_R9:
  485. case D_R10:
  486. case D_R11:
  487. case D_R12:
  488. case D_R13:
  489. case D_R14:
  490. case D_R15:
  491. if(asmode != 64)
  492. goto bad;
  493. case D_AX:
  494. case D_CX:
  495. case D_DX:
  496. case D_BX:
  497. case D_BP:
  498. case D_SI:
  499. case D_DI:
  500. i = reg[a->index] << 3;
  501. break;
  502. }
  503. switch(a->scale) {
  504. default:
  505. goto bad;
  506. case 1:
  507. break;
  508. case 2:
  509. i |= (1<<6);
  510. break;
  511. case 4:
  512. i |= (2<<6);
  513. break;
  514. case 8:
  515. i |= (3<<6);
  516. break;
  517. }
  518. bas:
  519. switch(base) {
  520. default:
  521. goto bad;
  522. case D_NONE: /* must be mod=00 */
  523. i |= 5;
  524. break;
  525. case D_R8:
  526. case D_R9:
  527. case D_R10:
  528. case D_R11:
  529. case D_R12:
  530. case D_R13:
  531. case D_R14:
  532. case D_R15:
  533. if(asmode != 64)
  534. goto bad;
  535. case D_AX:
  536. case D_CX:
  537. case D_DX:
  538. case D_BX:
  539. case D_SP:
  540. case D_BP:
  541. case D_SI:
  542. case D_DI:
  543. i |= reg[base];
  544. break;
  545. }
  546. *andptr++ = i;
  547. return;
  548. bad:
  549. diag("asmidx: bad address %D", a);
  550. *andptr++ = 0;
  551. return;
  552. }
  553. static void
  554. put4(long v)
  555. {
  556. if(dlm && curp != P && reloca != nil){
  557. dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1);
  558. reloca = nil;
  559. }
  560. andptr[0] = v;
  561. andptr[1] = v>>8;
  562. andptr[2] = v>>16;
  563. andptr[3] = v>>24;
  564. andptr += 4;
  565. }
  566. static void
  567. put8(vlong v)
  568. {
  569. if(dlm && curp != P && reloca != nil){
  570. dynreloc(reloca->sym, curp->pc + andptr - &and[0], 1); /* TO DO */
  571. reloca = nil;
  572. }
  573. andptr[0] = v;
  574. andptr[1] = v>>8;
  575. andptr[2] = v>>16;
  576. andptr[3] = v>>24;
  577. andptr[4] = v>>32;
  578. andptr[5] = v>>40;
  579. andptr[6] = v>>48;
  580. andptr[7] = v>>56;
  581. andptr += 8;
  582. }
  583. vlong
  584. vaddr(Adr *a)
  585. {
  586. int t;
  587. vlong v;
  588. Sym *s;
  589. t = a->type;
  590. v = a->offset;
  591. if(t == D_ADDR)
  592. t = a->index;
  593. switch(t) {
  594. case D_STATIC:
  595. case D_EXTERN:
  596. s = a->sym;
  597. if(s != nil) {
  598. if(dlm && curp != P)
  599. reloca = a;
  600. switch(s->type) {
  601. case SUNDEF:
  602. ckoff(s, v);
  603. case STEXT:
  604. case SCONST:
  605. if((uvlong)s->value < (uvlong)INITTEXT)
  606. v += INITTEXT; /* TO DO */
  607. v += s->value;
  608. break;
  609. default:
  610. v += INITDAT + s->value;
  611. }
  612. }
  613. }
  614. return v;
  615. }
  616. static void
  617. asmandsz(Adr *a, int r, int rex, int m64)
  618. {
  619. long v;
  620. int t;
  621. Adr aa;
  622. rex &= (0x40 | Rxr);
  623. v = a->offset;
  624. if ((vlong)v != a->offset)
  625. print("asmandsz: Trying to emit %#ullx and 32 bits is not sufficient\n",
  626. a->offset);
  627. t = a->type;
  628. if(a->index != D_NONE) {
  629. if(t >= D_INDIR) {
  630. t -= D_INDIR;
  631. rexflag |= (regrex[a->index] & Rxx) | (regrex[t] & Rxb) | rex;
  632. if(t == D_NONE) {
  633. *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
  634. asmidx(a, t);
  635. put4(v);
  636. return;
  637. }
  638. if(v == 0 && t != D_BP && t != D_R13) {
  639. *andptr++ = (0 << 6) | (4 << 0) | (r << 3);
  640. asmidx(a, t);
  641. return;
  642. }
  643. if(v >= -128 && v < 128) {
  644. *andptr++ = (1 << 6) | (4 << 0) | (r << 3);
  645. asmidx(a, t);
  646. *andptr++ = v;
  647. return;
  648. }
  649. *andptr++ = (2 << 6) | (4 << 0) | (r << 3);
  650. asmidx(a, t);
  651. put4(v);
  652. return;
  653. }
  654. switch(t) {
  655. default:
  656. goto bad;
  657. case D_STATIC:
  658. case D_EXTERN:
  659. aa.type = D_NONE+D_INDIR;
  660. break;
  661. case D_AUTO:
  662. case D_PARAM:
  663. aa.type = D_SP+D_INDIR;
  664. break;
  665. }
  666. aa.offset = vaddr(a);
  667. aa.index = a->index;
  668. aa.scale = a->scale;
  669. asmandsz(&aa, r, rex, m64);
  670. return;
  671. }
  672. if(t >= D_AL && t <= D_X0+15) {
  673. if(v)
  674. goto bad;
  675. *andptr++ = (3 << 6) | (reg[t] << 0) | (r << 3);
  676. rexflag |= (regrex[t] & (0x40 | Rxb)) | rex;
  677. return;
  678. }
  679. if(t >= D_INDIR) {
  680. t -= D_INDIR;
  681. rexflag |= (regrex[t] & Rxb) | rex;
  682. if(t == D_NONE) {
  683. if(asmode != 64){
  684. *andptr++ = (0 << 6) | (5 << 0) | (r << 3);
  685. put4(v);
  686. return;
  687. }
  688. /* temporary */
  689. *andptr++ = (0 << 6) | (4 << 0) | (r << 3); /* sib present */
  690. *andptr++ = (0 << 6) | (4 << 3) | (5 << 0); /* DS:d32 */
  691. put4(v);
  692. return;
  693. }
  694. if(t == D_SP || t == D_R12) {
  695. if(v == 0) {
  696. *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
  697. asmidx(a, t);
  698. return;
  699. }
  700. if(v >= -128 && v < 128) {
  701. *andptr++ = (1 << 6) | (reg[t] << 0) | (r << 3);
  702. asmidx(a, t);
  703. *andptr++ = v;
  704. return;
  705. }
  706. *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
  707. asmidx(a, t);
  708. put4(v);
  709. return;
  710. }
  711. if(t >= D_AX && t <= D_R15) {
  712. if(v == 0 && t != D_BP && t != D_R13) {
  713. *andptr++ = (0 << 6) | (reg[t] << 0) | (r << 3);
  714. return;
  715. }
  716. if(v >= -128 && v < 128) {
  717. andptr[0] = (1 << 6) | (reg[t] << 0) | (r << 3);
  718. andptr[1] = v;
  719. andptr += 2;
  720. return;
  721. }
  722. *andptr++ = (2 << 6) | (reg[t] << 0) | (r << 3);
  723. put4(v);
  724. return;
  725. }
  726. goto bad;
  727. }
  728. switch(a->type) {
  729. default:
  730. goto bad;
  731. case D_STATIC:
  732. case D_EXTERN:
  733. aa.type = D_NONE+D_INDIR;
  734. break;
  735. case D_AUTO:
  736. case D_PARAM:
  737. aa.type = D_SP+D_INDIR;
  738. break;
  739. }
  740. aa.index = D_NONE;
  741. aa.scale = 1;
  742. aa.offset = vaddr(a);
  743. asmandsz(&aa, r, rex, m64);
  744. return;
  745. bad:
  746. diag("asmand: bad address %D", a);
  747. return;
  748. }
  749. void
  750. asmand(Adr *a, Adr *ra)
  751. {
  752. asmandsz(a, reg[ra->type], regrex[ra->type], 0);
  753. }
  754. void
  755. asmando(Adr *a, int o)
  756. {
  757. asmandsz(a, o, 0, 0);
  758. }
  759. static void
  760. bytereg(Adr *a)
  761. {
  762. if(a->index == D_NONE && (a->type >= D_AX && a->type <= D_R15))
  763. a->type = D_AL + (a->type-D_AX);
  764. }
  765. #define E 0xff
  766. Movtab ymovtab[] =
  767. {
  768. /* push */
  769. {APUSHL, Ycs, Ynone, 0, 0x0e,E,0,0},
  770. {APUSHL, Yss, Ynone, 0, 0x16,E,0,0},
  771. {APUSHL, Yds, Ynone, 0, 0x1e,E,0,0},
  772. {APUSHL, Yes, Ynone, 0, 0x06,E,0,0},
  773. {APUSHL, Yfs, Ynone, 0, 0x0f,0xa0,E,0},
  774. {APUSHL, Ygs, Ynone, 0, 0x0f,0xa8,E,0},
  775. {APUSHQ, Yfs, Ynone, 0, 0x0f,0xa0,E,0},
  776. {APUSHQ, Ygs, Ynone, 0, 0x0f,0xa8,E,0},
  777. {APUSHW, Ycs, Ynone, 0, Pe,0x0e,E,0},
  778. {APUSHW, Yss, Ynone, 0, Pe,0x16,E,0},
  779. {APUSHW, Yds, Ynone, 0, Pe,0x1e,E,0},
  780. {APUSHW, Yes, Ynone, 0, Pe,0x06,E,0},
  781. {APUSHW, Yfs, Ynone, 0, Pe,0x0f,0xa0,E},
  782. {APUSHW, Ygs, Ynone, 0, Pe,0x0f,0xa8,E},
  783. /* pop */
  784. {APOPL, Ynone, Yds, 0, 0x1f,E,0,0},
  785. {APOPL, Ynone, Yes, 0, 0x07,E,0,0},
  786. {APOPL, Ynone, Yss, 0, 0x17,E,0,0},
  787. {APOPL, Ynone, Yfs, 0, 0x0f,0xa1,E,0},
  788. {APOPL, Ynone, Ygs, 0, 0x0f,0xa9,E,0},
  789. {APOPQ, Ynone, Yfs, 0, 0x0f,0xa1,E,0},
  790. {APOPQ, Ynone, Ygs, 0, 0x0f,0xa9,E,0},
  791. {APOPW, Ynone, Yds, 0, Pe,0x1f,E,0},
  792. {APOPW, Ynone, Yes, 0, Pe,0x07,E,0},
  793. {APOPW, Ynone, Yss, 0, Pe,0x17,E,0},
  794. {APOPW, Ynone, Yfs, 0, Pe,0x0f,0xa1,E},
  795. {APOPW, Ynone, Ygs, 0, Pe,0x0f,0xa9,E},
  796. /* mov seg */
  797. {AMOVW, Yes, Yml, 1, 0x8c,0,0,0},
  798. {AMOVW, Ycs, Yml, 1, 0x8c,1,0,0},
  799. {AMOVW, Yss, Yml, 1, 0x8c,2,0,0},
  800. {AMOVW, Yds, Yml, 1, 0x8c,3,0,0},
  801. {AMOVW, Yfs, Yml, 1, 0x8c,4,0,0},
  802. {AMOVW, Ygs, Yml, 1, 0x8c,5,0,0},
  803. {AMOVW, Yml, Yes, 2, 0x8e,0,0,0},
  804. {AMOVW, Yml, Ycs, 2, 0x8e,1,0,0},
  805. {AMOVW, Yml, Yss, 2, 0x8e,2,0,0},
  806. {AMOVW, Yml, Yds, 2, 0x8e,3,0,0},
  807. {AMOVW, Yml, Yfs, 2, 0x8e,4,0,0},
  808. {AMOVW, Yml, Ygs, 2, 0x8e,5,0,0},
  809. /* mov cr */
  810. {AMOVL, Ycr0, Yml, 3, 0x0f,0x20,0,0},
  811. {AMOVL, Ycr2, Yml, 3, 0x0f,0x20,2,0},
  812. {AMOVL, Ycr3, Yml, 3, 0x0f,0x20,3,0},
  813. {AMOVL, Ycr4, Yml, 3, 0x0f,0x20,4,0},
  814. {AMOVL, Ycr8, Yml, 3, 0x0f,0x20,8,0},
  815. {AMOVQ, Ycr0, Yml, 3, 0x0f,0x20,0,0},
  816. {AMOVQ, Ycr2, Yml, 3, 0x0f,0x20,2,0},
  817. {AMOVQ, Ycr3, Yml, 3, 0x0f,0x20,3,0},
  818. {AMOVQ, Ycr4, Yml, 3, 0x0f,0x20,4,0},
  819. {AMOVQ, Ycr8, Yml, 3, 0x0f,0x20,8,0},
  820. {AMOVL, Yml, Ycr0, 4, 0x0f,0x22,0,0},
  821. {AMOVL, Yml, Ycr2, 4, 0x0f,0x22,2,0},
  822. {AMOVL, Yml, Ycr3, 4, 0x0f,0x22,3,0},
  823. {AMOVL, Yml, Ycr4, 4, 0x0f,0x22,4,0},
  824. {AMOVL, Yml, Ycr8, 4, 0x0f,0x22,8,0},
  825. {AMOVQ, Yml, Ycr0, 4, 0x0f,0x22,0,0},
  826. {AMOVQ, Yml, Ycr2, 4, 0x0f,0x22,2,0},
  827. {AMOVQ, Yml, Ycr3, 4, 0x0f,0x22,3,0},
  828. {AMOVQ, Yml, Ycr4, 4, 0x0f,0x22,4,0},
  829. {AMOVQ, Yml, Ycr8, 4, 0x0f,0x22,8,0},
  830. /* mov dr */
  831. {AMOVL, Ydr0, Yml, 3, 0x0f,0x21,0,0},
  832. {AMOVL, Ydr6, Yml, 3, 0x0f,0x21,6,0},
  833. {AMOVL, Ydr7, Yml, 3, 0x0f,0x21,7,0},
  834. {AMOVQ, Ydr0, Yml, 3, 0x0f,0x21,0,0},
  835. {AMOVQ, Ydr6, Yml, 3, 0x0f,0x21,6,0},
  836. {AMOVQ, Ydr7, Yml, 3, 0x0f,0x21,7,0},
  837. {AMOVL, Yml, Ydr0, 4, 0x0f,0x23,0,0},
  838. {AMOVL, Yml, Ydr6, 4, 0x0f,0x23,6,0},
  839. {AMOVL, Yml, Ydr7, 4, 0x0f,0x23,7,0},
  840. {AMOVQ, Yml, Ydr0, 4, 0x0f,0x23,0,0},
  841. {AMOVQ, Yml, Ydr6, 4, 0x0f,0x23,6,0},
  842. {AMOVQ, Yml, Ydr7, 4, 0x0f,0x23,7,0},
  843. /* mov tr */
  844. {AMOVL, Ytr6, Yml, 3, 0x0f,0x24,6,0},
  845. {AMOVL, Ytr7, Yml, 3, 0x0f,0x24,7,0},
  846. {AMOVL, Yml, Ytr6, 4, 0x0f,0x26,6,E},
  847. {AMOVL, Yml, Ytr7, 4, 0x0f,0x26,7,E},
  848. /* lgdt, sgdt, lidt, sidt */
  849. {AMOVL, Ym, Ygdtr, 4, 0x0f,0x01,2,0},
  850. {AMOVL, Ygdtr, Ym, 3, 0x0f,0x01,0,0},
  851. {AMOVL, Ym, Yidtr, 4, 0x0f,0x01,3,0},
  852. {AMOVL, Yidtr, Ym, 3, 0x0f,0x01,1,0},
  853. {AMOVQ, Ym, Ygdtr, 4, 0x0f,0x01,2,0},
  854. {AMOVQ, Ygdtr, Ym, 3, 0x0f,0x01,0,0},
  855. {AMOVQ, Ym, Yidtr, 4, 0x0f,0x01,3,0},
  856. {AMOVQ, Yidtr, Ym, 3, 0x0f,0x01,1,0},
  857. /* lldt, sldt */
  858. {AMOVW, Yml, Yldtr, 4, 0x0f,0x00,2,0},
  859. {AMOVW, Yldtr, Yml, 3, 0x0f,0x00,0,0},
  860. /* lmsw, smsw */
  861. {AMOVW, Yml, Ymsw, 4, 0x0f,0x01,6,0},
  862. {AMOVW, Ymsw, Yml, 3, 0x0f,0x01,4,0},
  863. /* ltr, str */
  864. {AMOVW, Yml, Ytask, 4, 0x0f,0x00,3,0},
  865. {AMOVW, Ytask, Yml, 3, 0x0f,0x00,1,0},
  866. /* load full pointer */
  867. {AMOVL, Yml, Ycol, 5, 0,0,0,0},
  868. {AMOVW, Yml, Ycol, 5, Pe,0,0,0},
  869. /* double shift */
  870. {ASHLL, Ycol, Yml, 6, 0xa4,0xa5,0,0},
  871. {ASHRL, Ycol, Yml, 6, 0xac,0xad,0,0},
  872. {ASHLQ, Ycol, Yml, 6, Pw,0xa4,0xa5,0},
  873. {ASHRQ, Ycol, Yml, 6, Pw,0xac,0xad,0},
  874. {ASHLW, Ycol, Yml, 6, Pe,0xa4,0xa5,0},
  875. {ASHRW, Ycol, Yml, 6, Pe,0xac,0xad,0},
  876. 0
  877. };
  878. int
  879. isax(Adr *a)
  880. {
  881. switch(a->type) {
  882. case D_AX:
  883. case D_AL:
  884. case D_AH:
  885. case D_INDIR+D_AX:
  886. return 1;
  887. }
  888. if(a->index == D_AX)
  889. return 1;
  890. return 0;
  891. }
  892. void
  893. subreg(Prog *p, int from, int to)
  894. {
  895. if(debug['Q'])
  896. print("\n%P s/%R/%R/\n", p, from, to);
  897. if(p->from.type == from)
  898. p->from.type = to;
  899. if(p->to.type == from)
  900. p->to.type = to;
  901. if(p->from.index == from)
  902. p->from.index = to;
  903. if(p->to.index == from)
  904. p->to.index = to;
  905. from += D_INDIR;
  906. if(p->from.type == from)
  907. p->from.type = to+D_INDIR;
  908. if(p->to.type == from)
  909. p->to.type = to+D_INDIR;
  910. if(debug['Q'])
  911. print("%P\n", p);
  912. }
  913. static int
  914. mediaop(Optab *o, int op, int osize, int z)
  915. {
  916. switch(op){
  917. case Pm:
  918. case Pe:
  919. case Pf2:
  920. case Pf3:
  921. if(osize != 1){
  922. if(op != Pm)
  923. *andptr++ = op;
  924. *andptr++ = Pm;
  925. op = o->op[++z];
  926. break;
  927. }
  928. default:
  929. if(andptr == and || andptr[-1] != Pm)
  930. *andptr++ = Pm;
  931. break;
  932. }
  933. *andptr++ = op;
  934. return z;
  935. }
  936. void
  937. doasm(Prog *p)
  938. {
  939. Optab *o;
  940. Prog *q, pp;
  941. uchar *t;
  942. Movtab *mo;
  943. int z, op, ft, tt, xo, l;
  944. vlong v;
  945. o = opindex[p->as];
  946. if(o == nil) {
  947. diag("asmins: missing op %P", p);
  948. return;
  949. }
  950. ft = oclass(&p->from) * Ymax;
  951. tt = oclass(&p->to) * Ymax;
  952. t = o->ytab;
  953. if(t == 0) {
  954. diag("asmins: noproto %P", p);
  955. return;
  956. }
  957. xo = o->op[0] == 0x0f;
  958. for(z=0; *t; z+=t[3]+xo,t+=4)
  959. if(ycover[ft+t[0]])
  960. if(ycover[tt+t[1]])
  961. goto found;
  962. goto domov;
  963. found:
  964. switch(o->prefix) {
  965. case Pq: /* 16 bit escape and opcode escape */
  966. *andptr++ = Pe;
  967. *andptr++ = Pm;
  968. break;
  969. case Pf2: /* xmm opcode escape */
  970. case Pf3:
  971. *andptr++ = o->prefix;
  972. *andptr++ = Pm;
  973. break;
  974. case Pm: /* opcode escape */
  975. *andptr++ = Pm;
  976. break;
  977. case Pe: /* 16 bit escape */
  978. *andptr++ = Pe;
  979. break;
  980. case Pw: /* 64-bit escape */
  981. if(p->mode != 64)
  982. diag("asmins: illegal 64: %P", p);
  983. rexflag |= Pw;
  984. break;
  985. case Pb: /* botch */
  986. bytereg(&p->from);
  987. bytereg(&p->to);
  988. break;
  989. case P32: /* 32 bit but illegal if 64-bit mode */
  990. if(p->mode == 64)
  991. diag("asmins: illegal in 64-bit mode: %P", p);
  992. break;
  993. case Py: /* 64-bit only, no prefix */
  994. if(p->mode != 64)
  995. diag("asmins: illegal in %d-bit mode: %P", p->mode, p);
  996. break;
  997. }
  998. v = vaddr(&p->from);
  999. op = o->op[z];
  1000. if(op == 0x0f) {
  1001. *andptr++ = op;
  1002. op = o->op[++z];
  1003. }
  1004. switch(t[2]) {
  1005. default:
  1006. diag("asmins: unknown z %d %P", t[2], p);
  1007. return;
  1008. case Zpseudo:
  1009. break;
  1010. case Zlit:
  1011. for(; op = o->op[z]; z++)
  1012. *andptr++ = op;
  1013. break;
  1014. case Zmb_r:
  1015. bytereg(&p->from);
  1016. /* fall through */
  1017. case Zm_r:
  1018. *andptr++ = op;
  1019. asmand(&p->from, &p->to);
  1020. break;
  1021. case Zm_r_xm:
  1022. mediaop(o, op, t[3], z);
  1023. asmand(&p->from, &p->to);
  1024. break;
  1025. case Zm_r_xm_nr:
  1026. rexflag = 0;
  1027. mediaop(o, op, t[3], z);
  1028. asmand(&p->from, &p->to);
  1029. break;
  1030. case Zm_r_i_xm:
  1031. mediaop(o, op, t[3], z);
  1032. asmand(&p->from, &p->to);
  1033. *andptr++ = p->to.offset;
  1034. break;
  1035. case Zm_r_3d:
  1036. *andptr++ = 0x0f;
  1037. *andptr++ = 0x0f;
  1038. asmand(&p->from, &p->to);
  1039. *andptr++ = op;
  1040. break;
  1041. case Zibm_r:
  1042. *andptr++ = op;
  1043. asmand(&p->from, &p->to);
  1044. *andptr++ = p->to.offset;
  1045. break;
  1046. case Zaut_r:
  1047. *andptr++ = 0x8d; /* leal */
  1048. if(p->from.type != D_ADDR)
  1049. diag("asmins: Zaut sb type ADDR");
  1050. p->from.type = p->from.index;
  1051. p->from.index = D_NONE;
  1052. asmand(&p->from, &p->to);
  1053. p->from.index = p->from.type;
  1054. p->from.type = D_ADDR;
  1055. break;
  1056. case Zm_o:
  1057. *andptr++ = op;
  1058. asmando(&p->from, o->op[z+1]);
  1059. break;
  1060. case Zr_m:
  1061. *andptr++ = op;
  1062. asmand(&p->to, &p->from);
  1063. break;
  1064. case Zr_m_xm:
  1065. mediaop(o, op, t[3], z);
  1066. asmand(&p->to, &p->from);
  1067. break;
  1068. case Zr_m_xm_nr:
  1069. rexflag = 0;
  1070. mediaop(o, op, t[3], z);
  1071. asmand(&p->to, &p->from);
  1072. break;
  1073. case Zr_m_i_xm:
  1074. mediaop(o, op, t[3], z);
  1075. asmand(&p->to, &p->from);
  1076. *andptr++ = p->from.offset;
  1077. break;
  1078. case Zo_m:
  1079. *andptr++ = op;
  1080. asmando(&p->to, o->op[z+1]);
  1081. break;
  1082. case Zo_m64:
  1083. *andptr++ = op;
  1084. asmandsz(&p->to, o->op[z+1], 0, 1);
  1085. break;
  1086. case Zm_ibo:
  1087. v = vaddr(&p->to);
  1088. *andptr++ = op;
  1089. asmando(&p->from, o->op[z+1]);
  1090. *andptr++ = v;
  1091. break;
  1092. case Zibo_m:
  1093. *andptr++ = op;
  1094. asmando(&p->to, o->op[z+1]);
  1095. *andptr++ = v;
  1096. break;
  1097. case Zibo_m_xm:
  1098. z = mediaop(o, op, t[3], z);
  1099. asmando(&p->to, o->op[z+1]);
  1100. *andptr++ = v;
  1101. break;
  1102. case Z_ib:
  1103. v = vaddr(&p->to);
  1104. case Zib_:
  1105. *andptr++ = op;
  1106. *andptr++ = v;
  1107. break;
  1108. case Zib_rp:
  1109. rexflag |= regrex[p->to.type] & (Rxb|0x40);
  1110. *andptr++ = op + reg[p->to.type];
  1111. *andptr++ = v;
  1112. break;
  1113. case Zil_rp:
  1114. rexflag |= regrex[p->to.type] & Rxb;
  1115. *andptr++ = op + reg[p->to.type];
  1116. if(o->prefix == Pe) {
  1117. *andptr++ = v;
  1118. *andptr++ = v>>8;
  1119. }
  1120. else
  1121. put4(v);
  1122. break;
  1123. case Zo_iw:
  1124. *andptr++ = op;
  1125. if(p->from.type != D_NONE){
  1126. *andptr++ = v;
  1127. *andptr++ = v>>8;
  1128. }
  1129. break;
  1130. case Ziq_rp:
  1131. l = v>>32;
  1132. if(l == 0){
  1133. //p->mark |= 0100;
  1134. //print("zero: %llux %P\n", v, p);
  1135. rexflag &= ~(0x40|Rxw);
  1136. rexflag |= regrex[p->to.type] & Rxb;
  1137. *andptr++ = 0xb8 + reg[p->to.type];
  1138. put4(v);
  1139. }else if(l == -1 && (v&((uvlong)1<<31))!=0){ /* sign extend */
  1140. //p->mark |= 0100;
  1141. //print("sign: %llux %P\n", v, p);
  1142. *andptr ++ = 0xc7;
  1143. asmando(&p->to, 0);
  1144. put4(v);
  1145. }else{ /* need all 8 */
  1146. //print("all: %llux %P\n", v, p);
  1147. rexflag |= regrex[p->to.type] & Rxb;
  1148. *andptr++ = op + reg[p->to.type];
  1149. put8(v);
  1150. }
  1151. break;
  1152. case Zib_rr:
  1153. *andptr++ = op;
  1154. asmand(&p->to, &p->to);
  1155. *andptr++ = v;
  1156. break;
  1157. case Z_il:
  1158. v = vaddr(&p->to);
  1159. case Zil_:
  1160. *andptr++ = op;
  1161. if(o->prefix == Pe) {
  1162. *andptr++ = v;
  1163. *andptr++ = v>>8;
  1164. }
  1165. else
  1166. put4(v);
  1167. break;
  1168. case Zm_ilo:
  1169. v = vaddr(&p->to);
  1170. *andptr++ = op;
  1171. asmando(&p->from, o->op[z+1]);
  1172. if(o->prefix == Pe) {
  1173. *andptr++ = v;
  1174. *andptr++ = v>>8;
  1175. }
  1176. else
  1177. put4(v);
  1178. break;
  1179. case Zilo_m:
  1180. *andptr++ = op;
  1181. asmando(&p->to, o->op[z+1]);
  1182. if(o->prefix == Pe) {
  1183. *andptr++ = v;
  1184. *andptr++ = v>>8;
  1185. }
  1186. else
  1187. put4(v);
  1188. break;
  1189. case Zil_rr:
  1190. *andptr++ = op;
  1191. asmand(&p->to, &p->to);
  1192. if(o->prefix == Pe) {
  1193. *andptr++ = v;
  1194. *andptr++ = v>>8;
  1195. }
  1196. else
  1197. put4(v);
  1198. break;
  1199. case Z_rp:
  1200. rexflag |= regrex[p->to.type] & (Rxb|0x40);
  1201. *andptr++ = op + reg[p->to.type];
  1202. break;
  1203. case Zrp_:
  1204. rexflag |= regrex[p->from.type] & (Rxb|0x40);
  1205. *andptr++ = op + reg[p->from.type];
  1206. break;
  1207. case Zclr:
  1208. *andptr++ = op;
  1209. asmand(&p->to, &p->to);
  1210. break;
  1211. case Zbr:
  1212. q = p->pcond;
  1213. if(q) {
  1214. v = q->pc - p->pc - 2;
  1215. if(v >= -128 && v <= 127) {
  1216. *andptr++ = op;
  1217. *andptr++ = v;
  1218. } else {
  1219. v -= 6-2;
  1220. *andptr++ = 0x0f;
  1221. *andptr++ = o->op[z+1];
  1222. *andptr++ = v;
  1223. *andptr++ = v>>8;
  1224. *andptr++ = v>>16;
  1225. *andptr++ = v>>24;
  1226. }
  1227. }
  1228. break;
  1229. case Zcall:
  1230. q = p->pcond;
  1231. if(q) {
  1232. v = q->pc - p->pc - 5;
  1233. if(dlm && curp != P && p->to.sym->type == SUNDEF){
  1234. /* v = 0 - p->pc - 5; */
  1235. v = 0;
  1236. ckoff(p->to.sym, v);
  1237. v += p->to.sym->value;
  1238. dynreloc(p->to.sym, p->pc+1, 0);
  1239. }
  1240. *andptr++ = op;
  1241. *andptr++ = v;
  1242. *andptr++ = v>>8;
  1243. *andptr++ = v>>16;
  1244. *andptr++ = v>>24;
  1245. }
  1246. break;
  1247. case Zjmp:
  1248. q = p->pcond;
  1249. if(q) {
  1250. v = q->pc - p->pc - 2;
  1251. if(v >= -128 && v <= 127) {
  1252. *andptr++ = op;
  1253. *andptr++ = v;
  1254. } else {
  1255. v -= 5-2;
  1256. *andptr++ = o->op[z+1];
  1257. *andptr++ = v;
  1258. *andptr++ = v>>8;
  1259. *andptr++ = v>>16;
  1260. *andptr++ = v>>24;
  1261. }
  1262. }
  1263. break;
  1264. case Zloop:
  1265. q = p->pcond;
  1266. if(q) {
  1267. v = q->pc - p->pc - 2;
  1268. if(v < -128 || v > 127)
  1269. diag("loop too far: %P", p);
  1270. *andptr++ = op;
  1271. *andptr++ = v;
  1272. }
  1273. break;
  1274. case Zbyte:
  1275. *andptr++ = v;
  1276. if(op > 1) {
  1277. *andptr++ = v>>8;
  1278. if(op > 2) {
  1279. *andptr++ = v>>16;
  1280. *andptr++ = v>>24;
  1281. if(op > 4) {
  1282. *andptr++ = v>>32;
  1283. *andptr++ = v>>40;
  1284. *andptr++ = v>>48;
  1285. *andptr++ = v>>56;
  1286. }
  1287. }
  1288. }
  1289. break;
  1290. }
  1291. return;
  1292. domov:
  1293. for(mo=ymovtab; mo->as; mo++)
  1294. if(p->as == mo->as)
  1295. if(ycover[ft+mo->ft])
  1296. if(ycover[tt+mo->tt]){
  1297. t = mo->op;
  1298. goto mfound;
  1299. }
  1300. bad:
  1301. if(p->mode != 64){
  1302. /*
  1303. * here, the assembly has failed.
  1304. * if its a byte instruction that has
  1305. * unaddressable registers, try to
  1306. * exchange registers and reissue the
  1307. * instruction with the operands renamed.
  1308. */
  1309. pp = *p;
  1310. z = p->from.type;
  1311. if(z >= D_BP && z <= D_DI) {
  1312. if(isax(&p->to)) {
  1313. *andptr++ = 0x87; /* xchg lhs,bx */
  1314. asmando(&p->from, reg[D_BX]);
  1315. subreg(&pp, z, D_BX);
  1316. doasm(&pp);
  1317. *andptr++ = 0x87; /* xchg lhs,bx */
  1318. asmando(&p->from, reg[D_BX]);
  1319. } else {
  1320. *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
  1321. subreg(&pp, z, D_AX);
  1322. doasm(&pp);
  1323. *andptr++ = 0x90 + reg[z]; /* xchg lsh,ax */
  1324. }
  1325. return;
  1326. }
  1327. z = p->to.type;
  1328. if(z >= D_BP && z <= D_DI) {
  1329. if(isax(&p->from)) {
  1330. *andptr++ = 0x87; /* xchg rhs,bx */
  1331. asmando(&p->to, reg[D_BX]);
  1332. subreg(&pp, z, D_BX);
  1333. doasm(&pp);
  1334. *andptr++ = 0x87; /* xchg rhs,bx */
  1335. asmando(&p->to, reg[D_BX]);
  1336. } else {
  1337. *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
  1338. subreg(&pp, z, D_AX);
  1339. doasm(&pp);
  1340. *andptr++ = 0x90 + reg[z]; /* xchg rsh,ax */
  1341. }
  1342. return;
  1343. }
  1344. }
  1345. diag("doasm: notfound from=%ux to=%ux %P", p->from.type, p->to.type, p);
  1346. return;
  1347. mfound:
  1348. switch(mo->code) {
  1349. default:
  1350. diag("asmins: unknown mov %d %P", mo->code, p);
  1351. break;
  1352. case 0: /* lit */
  1353. for(z=0; t[z]!=E; z++)
  1354. *andptr++ = t[z];
  1355. break;
  1356. case 1: /* r,m */
  1357. *andptr++ = t[0];
  1358. asmando(&p->to, t[1]);
  1359. break;
  1360. case 2: /* m,r */
  1361. *andptr++ = t[0];
  1362. asmando(&p->from, t[1]);
  1363. break;
  1364. case 3: /* r,m - 2op */
  1365. *andptr++ = t[0];
  1366. *andptr++ = t[1];
  1367. asmando(&p->to, t[2]);
  1368. rexflag |= regrex[p->from.type] & (Rxr|0x40);
  1369. break;
  1370. case 4: /* m,r - 2op */
  1371. *andptr++ = t[0];
  1372. *andptr++ = t[1];
  1373. asmando(&p->from, t[2]);
  1374. rexflag |= regrex[p->to.type] & (Rxr|0x40);
  1375. break;
  1376. case 5: /* load full pointer, trash heap */
  1377. if(t[0])
  1378. *andptr++ = t[0];
  1379. switch(p->to.index) {
  1380. default:
  1381. goto bad;
  1382. case D_DS:
  1383. *andptr++ = 0xc5;
  1384. break;
  1385. case D_SS:
  1386. *andptr++ = 0x0f;
  1387. *andptr++ = 0xb2;
  1388. break;
  1389. case D_ES:
  1390. *andptr++ = 0xc4;
  1391. break;
  1392. case D_FS:
  1393. *andptr++ = 0x0f;
  1394. *andptr++ = 0xb4;
  1395. break;
  1396. case D_GS:
  1397. *andptr++ = 0x0f;
  1398. *andptr++ = 0xb5;
  1399. break;
  1400. }
  1401. asmand(&p->from, &p->to);
  1402. break;
  1403. case 6: /* double shift */
  1404. if(t[0] == Pw){
  1405. if(p->mode != 64)
  1406. diag("asmins: illegal 64: %P", p);
  1407. rexflag |= Pw;
  1408. t++;
  1409. }else if(t[0] == Pe){
  1410. *andptr++ = Pe;
  1411. t++;
  1412. }
  1413. z = p->from.type;
  1414. switch(z) {
  1415. default:
  1416. goto bad;
  1417. case D_CONST:
  1418. *andptr++ = 0x0f;
  1419. *andptr++ = t[0];
  1420. asmandsz(&p->to, reg[p->from.index], regrex[p->from.index], 0);
  1421. *andptr++ = p->from.offset;
  1422. break;
  1423. case D_CL:
  1424. case D_CX:
  1425. *andptr++ = 0x0f;
  1426. *andptr++ = t[1];
  1427. asmandsz(&p->to, reg[p->from.index], regrex[p->from.index], 0);
  1428. break;
  1429. }
  1430. break;
  1431. }
  1432. }
  1433. void
  1434. asmins(Prog *p)
  1435. {
  1436. int n, np, c;
  1437. rexflag = 0;
  1438. andptr = and;
  1439. asmode = p->mode;
  1440. doasm(p);
  1441. if(rexflag){
  1442. /*
  1443. * as befits the whole approach of the architecture,
  1444. * the rex prefix must appear before the first opcode byte
  1445. * (and thus after any 66/67/f2/f3/26/2e/3e prefix bytes, but
  1446. * before the 0f opcode escape!), or it might be ignored.
  1447. * note that the handbook often misleadingly shows 66/f2/f3 in `opcode'.
  1448. */
  1449. if(p->mode != 64)
  1450. diag("asmins: illegal in mode %d: %P", p->mode, p);
  1451. n = andptr - and;
  1452. for(np = 0; np < n; np++) {
  1453. c = and[np];
  1454. if(c != 0xf2 && c != 0xf3 && (c < 0x64 || c > 0x67) && c != 0x2e && c != 0x3e && c != 0x26)
  1455. break;
  1456. }
  1457. memmove(and+np+1, and+np, n-np);
  1458. and[np] = 0x40 | rexflag;
  1459. andptr++;
  1460. }
  1461. }
  1462. enum{
  1463. ABSD = 0,
  1464. ABSU = 1,
  1465. RELD = 2,
  1466. RELU = 3,
  1467. };
  1468. int modemap[4] = { 0, 1, -1, 2, };
  1469. typedef struct Reloc Reloc;
  1470. struct Reloc
  1471. {
  1472. int n;
  1473. int t;
  1474. uchar *m;
  1475. ulong *a;
  1476. };
  1477. Reloc rels;
  1478. static void
  1479. grow(Reloc *r)
  1480. {
  1481. int t;
  1482. uchar *m, *nm;
  1483. ulong *a, *na;
  1484. t = r->t;
  1485. r->t += 64;
  1486. m = r->m;
  1487. a = r->a;
  1488. r->m = nm = malloc(r->t*sizeof(uchar));
  1489. r->a = na = malloc(r->t*sizeof(ulong));
  1490. memmove(nm, m, t*sizeof(uchar));
  1491. memmove(na, a, t*sizeof(ulong));
  1492. free(m);
  1493. free(a);
  1494. }
  1495. void
  1496. dynreloc(Sym *s, ulong v, int abs)
  1497. {
  1498. int i, k, n;
  1499. uchar *m;
  1500. ulong *a;
  1501. Reloc *r;
  1502. if(s->type == SUNDEF)
  1503. k = abs ? ABSU : RELU;
  1504. else
  1505. k = abs ? ABSD : RELD;
  1506. /* Bprint(&bso, "R %s a=%ld(%lx) %d\n", s->name, v, v, k); */
  1507. k = modemap[k];
  1508. r = &rels;
  1509. n = r->n;
  1510. if(n >= r->t)
  1511. grow(r);
  1512. m = r->m;
  1513. a = r->a;
  1514. for(i = n; i > 0; i--){
  1515. if(v < a[i-1]){ /* happens occasionally for data */
  1516. m[i] = m[i-1];
  1517. a[i] = a[i-1];
  1518. }
  1519. else
  1520. break;
  1521. }
  1522. m[i] = k;
  1523. a[i] = v;
  1524. r->n++;
  1525. }
  1526. static int
  1527. sput(char *s)
  1528. {
  1529. char *p;
  1530. p = s;
  1531. while(*s)
  1532. cput(*s++);
  1533. cput(0);
  1534. return s-p+1;
  1535. }
  1536. void
  1537. asmdyn()
  1538. {
  1539. int i, n, t, c;
  1540. Sym *s;
  1541. ulong la, ra, *a;
  1542. vlong off;
  1543. uchar *m;
  1544. Reloc *r;
  1545. cflush();
  1546. off = seek(cout, 0, 1);
  1547. lput(0);
  1548. t = 0;
  1549. lput(imports);
  1550. t += 4;
  1551. for(i = 0; i < NHASH; i++)
  1552. for(s = hash[i]; s != S; s = s->link)
  1553. if(s->type == SUNDEF){
  1554. lput(s->sig);
  1555. t += 4;
  1556. t += sput(s->name);
  1557. }
  1558. la = 0;
  1559. r = &rels;
  1560. n = r->n;
  1561. m = r->m;
  1562. a = r->a;
  1563. lput(n);
  1564. t += 4;
  1565. for(i = 0; i < n; i++){
  1566. ra = *a-la;
  1567. if(*a < la)
  1568. diag("bad relocation order");
  1569. if(ra < 256)
  1570. c = 0;
  1571. else if(ra < 65536)
  1572. c = 1;
  1573. else
  1574. c = 2;
  1575. cput((c<<6)|*m++);
  1576. t++;
  1577. if(c == 0){
  1578. cput(ra);
  1579. t++;
  1580. }
  1581. else if(c == 1){
  1582. wput(ra);
  1583. t += 2;
  1584. }
  1585. else{
  1586. lput(ra);
  1587. t += 4;
  1588. }
  1589. la = *a++;
  1590. }
  1591. cflush();
  1592. seek(cout, off, 0);
  1593. lput(t);
  1594. if(debug['v']){
  1595. Bprint(&bso, "import table entries = %d\n", imports);
  1596. Bprint(&bso, "export table entries = %d\n", exports);
  1597. }
  1598. }