span.c 30 KB

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