span.c 31 KB

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