txt.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759
  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 "gc.h"
  10. static int resvreg[nelem(reg)];
  11. static void gopcode64(int, Node*, Node*, Node*);
  12. static void gori64(int, Node*, Node*, Node*);
  13. static void gandi64(int, Node*, Node*, Node*);
  14. void
  15. ginit(void)
  16. {
  17. Type *t;
  18. thechar = 'q';
  19. thestring = "power";
  20. exregoffset = REGEXT;
  21. exfregoffset = FREGEXT;
  22. newvlongcode = 1;
  23. listinit();
  24. nstring = 0;
  25. mnstring = 0;
  26. nrathole = 0;
  27. pc = 0;
  28. breakpc = -1;
  29. continpc = -1;
  30. cases = C;
  31. firstp = P;
  32. lastp = P;
  33. tfield = types[TLONG];
  34. typeswitch = typechlv;
  35. zprog.link = P;
  36. zprog.as = AGOK;
  37. zprog.reg = NREG;
  38. zprog.from.type = D_NONE;
  39. zprog.from.name = D_NONE;
  40. zprog.from.reg = NREG;
  41. zprog.from3 = zprog.from;
  42. zprog.to = zprog.from;
  43. regnode.op = OREGISTER;
  44. regnode.class = CEXREG;
  45. regnode.reg = 0;
  46. regnode.complex = 0;
  47. regnode.addable = 11;
  48. regnode.type = types[TLONG];
  49. constnode.op = OCONST;
  50. constnode.class = CXXX;
  51. constnode.complex = 0;
  52. constnode.addable = 20;
  53. constnode.type = types[TLONG];
  54. fconstnode.op = OCONST;
  55. fconstnode.class = CXXX;
  56. fconstnode.complex = 0;
  57. fconstnode.addable = 20;
  58. fconstnode.type = types[TDOUBLE];
  59. nodsafe = new(ONAME, Z, Z);
  60. nodsafe->sym = slookup(".safe");
  61. nodsafe->type = types[TINT];
  62. nodsafe->etype = types[TINT]->etype;
  63. nodsafe->class = CAUTO;
  64. complex(nodsafe);
  65. t = typ(TARRAY, types[TCHAR]);
  66. symrathole = slookup(".rathole");
  67. symrathole->class = CGLOBL;
  68. symrathole->type = t;
  69. nodrat = new(ONAME, Z, Z);
  70. nodrat->sym = symrathole;
  71. nodrat->type = types[TIND];
  72. nodrat->etype = TVOID;
  73. nodrat->class = CGLOBL;
  74. complex(nodrat);
  75. nodrat->type = t;
  76. com64init();
  77. memset(reg, 0, sizeof(reg));
  78. reg[REGZERO] = 1; /* don't use */
  79. reg[REGTMP] = 1;
  80. reg[FREGCVI+NREG] = 1;
  81. reg[FREGZERO+NREG] = 1;
  82. reg[FREGHALF+NREG] = 1;
  83. reg[FREGONE+NREG] = 1;
  84. reg[FREGTWO+NREG] = 1;
  85. memmove(resvreg, reg, sizeof(reg));
  86. }
  87. void
  88. gclean(void)
  89. {
  90. int i;
  91. Sym *s;
  92. for(i=0; i<NREG; i++)
  93. if(reg[i] && !resvreg[i])
  94. diag(Z, "reg %d left allocated", i);
  95. for(i=NREG; i<NREG+NREG; i++)
  96. if(reg[i] && !resvreg[i])
  97. diag(Z, "freg %d left allocated", i-NREG);
  98. while(mnstring)
  99. outstring("", 1L);
  100. symstring->type->width = nstring;
  101. symrathole->type->width = nrathole;
  102. for(i=0; i<NHASH; i++)
  103. for(s = hash[i]; s != S; s = s->link) {
  104. if(s->type == T)
  105. continue;
  106. if(s->type->width == 0)
  107. continue;
  108. if(s->class != CGLOBL && s->class != CSTATIC)
  109. continue;
  110. if(s->type == types[TENUM])
  111. continue;
  112. gpseudo(AGLOBL, s, nodconst(s->type->width));
  113. }
  114. nextpc();
  115. p->as = AEND;
  116. outcode();
  117. }
  118. void
  119. nextpc(void)
  120. {
  121. p = alloc(sizeof(*p));
  122. *p = zprog;
  123. p->lineno = nearln;
  124. pc++;
  125. if(firstp == P) {
  126. firstp = p;
  127. lastp = p;
  128. return;
  129. }
  130. lastp->link = p;
  131. lastp = p;
  132. }
  133. void
  134. gargs(Node *n, Node *tn1, Node *tn2)
  135. {
  136. int32_t regs;
  137. Node fnxargs[20], *fnxp;
  138. regs = cursafe;
  139. fnxp = fnxargs;
  140. garg1(n, tn1, tn2, 0, &fnxp); /* compile fns to temps */
  141. curarg = 0;
  142. fnxp = fnxargs;
  143. garg1(n, tn1, tn2, 1, &fnxp); /* compile normal args and temps */
  144. cursafe = regs;
  145. }
  146. void
  147. garg1(Node *n, Node *tn1, Node *tn2, int f, Node **fnxp)
  148. {
  149. Node nod;
  150. if(n == Z)
  151. return;
  152. if(n->op == OLIST) {
  153. garg1(n->left, tn1, tn2, f, fnxp);
  154. garg1(n->right, tn1, tn2, f, fnxp);
  155. return;
  156. }
  157. if(f == 0) {
  158. if(n->complex >= FNX) {
  159. regsalloc(*fnxp, n);
  160. nod = znode;
  161. nod.op = OAS;
  162. nod.left = *fnxp;
  163. nod.right = n;
  164. nod.type = n->type;
  165. cgen(&nod, Z);
  166. (*fnxp)++;
  167. }
  168. return;
  169. }
  170. if(typesuv[n->type->etype]) {
  171. regaalloc(tn2, n);
  172. if(n->complex >= FNX) {
  173. cgen(*fnxp, tn2);
  174. (*fnxp)++;
  175. } else
  176. cgen(n, tn2);
  177. return;
  178. }
  179. if(REGARG && curarg == 0 && typechlp[n->type->etype]) {
  180. regaalloc1(tn1, n);
  181. if(n->complex >= FNX) {
  182. cgen(*fnxp, tn1);
  183. (*fnxp)++;
  184. } else
  185. cgen(n, tn1);
  186. return;
  187. }
  188. if(vconst(n) == 0) {
  189. regaalloc(tn2, n);
  190. gopcode(OAS, n, Z, tn2);
  191. return;
  192. }
  193. regalloc(tn1, n, Z);
  194. if(n->complex >= FNX) {
  195. cgen(*fnxp, tn1);
  196. (*fnxp)++;
  197. } else
  198. cgen(n, tn1);
  199. regaalloc(tn2, n);
  200. gopcode(OAS, tn1, Z, tn2);
  201. regfree(tn1);
  202. }
  203. Node*
  204. nod32const(int64_t v)
  205. {
  206. constnode.vconst = v & MASK(32);
  207. return &constnode;
  208. }
  209. Node*
  210. nodconst(int32_t v)
  211. {
  212. constnode.vconst = v;
  213. return &constnode;
  214. }
  215. Node*
  216. nodfconst(double d)
  217. {
  218. fconstnode.fconst = d;
  219. return &fconstnode;
  220. }
  221. void
  222. nodreg(Node *n, Node *nn, int reg)
  223. {
  224. *n = regnode;
  225. n->reg = reg;
  226. n->type = nn->type;
  227. n->lineno = nn->lineno;
  228. }
  229. void
  230. regret(Node *n, Node *nn)
  231. {
  232. int r;
  233. r = REGRET;
  234. if(typefd[nn->type->etype])
  235. r = FREGRET+NREG;
  236. nodreg(n, nn, r);
  237. reg[r]++;
  238. }
  239. void
  240. regalloc(Node *n, Node *tn, Node *o)
  241. {
  242. int i, j;
  243. static int lasti;
  244. switch(tn->type->etype) {
  245. case TCHAR:
  246. case TUCHAR:
  247. case TSHORT:
  248. case TUSHORT:
  249. case TINT:
  250. case TUINT:
  251. case TLONG:
  252. case TULONG:
  253. case TIND:
  254. if(o != Z && o->op == OREGISTER) {
  255. i = o->reg;
  256. if(i > 0 && i < NREG)
  257. goto out;
  258. }
  259. j = lasti + REGRET+1;
  260. for(i=REGRET+1; i<NREG; i++) {
  261. if(j >= NREG)
  262. j = REGRET+1;
  263. if(reg[j] == 0) {
  264. i = j;
  265. goto out;
  266. }
  267. j++;
  268. }
  269. diag(tn, "out of fixed registers");
  270. goto err;
  271. case TFLOAT:
  272. case TDOUBLE:
  273. if(o != Z && o->op == OREGISTER) {
  274. i = o->reg;
  275. if(i >= NREG && i < NREG+NREG)
  276. goto out;
  277. }
  278. j = lasti + NREG;
  279. for(i=NREG; i<NREG+NREG; i++) {
  280. if(j >= NREG+NREG)
  281. j = NREG;
  282. if(reg[j] == 0) {
  283. i = j;
  284. goto out;
  285. }
  286. j++;
  287. }
  288. diag(tn, "out of float registers");
  289. goto err;
  290. case TVLONG:
  291. case TUVLONG:
  292. n->op = OREGPAIR;
  293. n->complex = 0; /* already in registers */
  294. n->addable = 11;
  295. n->type = tn->type;
  296. n->lineno = nearln;
  297. n->left = alloc(sizeof(Node));
  298. n->right = alloc(sizeof(Node));
  299. if(o != Z && o->op == OREGPAIR) {
  300. regalloc(n->left, &regnode, o->left);
  301. regalloc(n->right, &regnode, o->right);
  302. } else {
  303. regalloc(n->left, &regnode, Z);
  304. regalloc(n->right, &regnode, Z);
  305. }
  306. n->right->type = types[TULONG];
  307. if(tn->type->etype == TUVLONG)
  308. n->left->type = types[TULONG]; /* TO DO: is this a bad idea? */
  309. return;
  310. }
  311. diag(tn, "unknown type in regalloc: %T", tn->type);
  312. err:
  313. i = 0;
  314. out:
  315. if(i)
  316. reg[i]++;
  317. lasti++;
  318. if(lasti >= 5)
  319. lasti = 0;
  320. nodreg(n, tn, i);
  321. }
  322. void
  323. regialloc(Node *n, Node *tn, Node *o)
  324. {
  325. Node nod;
  326. nod = *tn;
  327. nod.type = types[TIND];
  328. regalloc(n, &nod, o);
  329. }
  330. void
  331. regfree(Node *n)
  332. {
  333. int i;
  334. if(n->op == OREGPAIR) {
  335. regfree(n->left);
  336. regfree(n->right);
  337. return;
  338. }
  339. i = 0;
  340. if(n->op != OREGISTER && n->op != OINDREG)
  341. goto err;
  342. i = n->reg;
  343. if(i < 0 || i >= sizeof(reg))
  344. goto err;
  345. if(reg[i] <= 0)
  346. goto err;
  347. reg[i]--;
  348. return;
  349. err:
  350. diag(n, "error in regfree: %d [%d]", i, reg[i]);
  351. prtree(n, "regfree");
  352. }
  353. void
  354. regsalloc(Node *n, Node *nn)
  355. {
  356. cursafe = align(cursafe+stkoff, nn->type, Aaut3)-stkoff;
  357. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  358. // if(nn->type->etype == TDOUBLE || nn->type->etype == TVLONG){
  359. // extern int hasdoubled;
  360. // fprint(2, "stkoff=%ld cursafe=%ld curarg=%ld %d\n", stkoff, cursafe, curarg, hasdoubled);
  361. // }
  362. *n = *nodsafe;
  363. n->xoffset = -(stkoff + cursafe);
  364. n->type = nn->type;
  365. n->etype = nn->type->etype;
  366. n->lineno = nn->lineno;
  367. }
  368. void
  369. regaalloc1(Node *n, Node *nn)
  370. {
  371. nodreg(n, nn, REGARG);
  372. reg[REGARG]++;
  373. curarg = align(curarg, nn->type, Aarg1);
  374. curarg = align(curarg, nn->type, Aarg2);
  375. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  376. }
  377. void
  378. regaalloc(Node *n, Node *nn)
  379. {
  380. curarg = align(curarg, nn->type, Aarg1);
  381. *n = *nn;
  382. n->op = OINDREG;
  383. n->reg = REGSP;
  384. n->xoffset = curarg + SZ_LONG;
  385. n->complex = 0;
  386. n->addable = 20;
  387. curarg = align(curarg, nn->type, Aarg2);
  388. maxargsafe = maxround(maxargsafe, cursafe+curarg);
  389. }
  390. void
  391. regind(Node *n, Node *nn)
  392. {
  393. if(n->op != OREGISTER) {
  394. diag(n, "regind not OREGISTER");
  395. return;
  396. }
  397. n->op = OINDREG;
  398. n->type = nn->type;
  399. }
  400. void
  401. raddr(Node *n, Prog *p)
  402. {
  403. Adr a;
  404. naddr(n, &a);
  405. if(R0ISZERO && a.type == D_CONST && a.offset == 0) {
  406. a.type = D_REG;
  407. a.reg = REGZERO;
  408. }
  409. if(a.type != D_REG && a.type != D_FREG) {
  410. if(n)
  411. diag(n, "bad in raddr: %O", n->op);
  412. else
  413. diag(n, "bad in raddr: <null>");
  414. p->reg = NREG;
  415. } else
  416. p->reg = a.reg;
  417. }
  418. void
  419. naddr(Node *n, Adr *a)
  420. {
  421. int32_t v;
  422. a->type = D_NONE;
  423. if(n == Z)
  424. return;
  425. switch(n->op) {
  426. default:
  427. bad:
  428. diag(n, "bad in naddr: %O", n->op);
  429. break;
  430. case OREGISTER:
  431. a->type = D_REG;
  432. a->sym = S;
  433. a->reg = n->reg;
  434. if(a->reg >= NREG) {
  435. a->type = D_FREG;
  436. a->reg -= NREG;
  437. }
  438. break;
  439. case OIND:
  440. naddr(n->left, a);
  441. a->offset += n->xoffset; /* little hack for reglcgenv */
  442. if(a->type == D_REG) {
  443. a->type = D_OREG;
  444. break;
  445. }
  446. if(a->type == D_CONST) {
  447. a->type = D_OREG;
  448. break;
  449. }
  450. goto bad;
  451. case OINDREG:
  452. a->type = D_OREG;
  453. a->sym = S;
  454. a->offset = n->xoffset;
  455. a->reg = n->reg;
  456. break;
  457. case ONAME:
  458. a->etype = n->etype;
  459. a->type = D_OREG;
  460. a->name = D_STATIC;
  461. a->sym = n->sym;
  462. a->offset = n->xoffset;
  463. if(n->class == CSTATIC)
  464. break;
  465. if(n->class == CEXTERN || n->class == CGLOBL) {
  466. a->name = D_EXTERN;
  467. break;
  468. }
  469. if(n->class == CAUTO) {
  470. a->name = D_AUTO;
  471. break;
  472. }
  473. if(n->class == CPARAM) {
  474. a->name = D_PARAM;
  475. break;
  476. }
  477. goto bad;
  478. case OCONST:
  479. a->sym = S;
  480. a->reg = NREG;
  481. if(typefd[n->type->etype]) {
  482. a->type = D_FCONST;
  483. a->dval = n->fconst;
  484. } else {
  485. a->type = D_CONST;
  486. a->offset = n->vconst;
  487. }
  488. break;
  489. case OADDR:
  490. naddr(n->left, a);
  491. if(a->type == D_OREG) {
  492. a->type = D_CONST;
  493. break;
  494. }
  495. goto bad;
  496. case OADD:
  497. if(n->left->op == OCONST) {
  498. naddr(n->left, a);
  499. v = a->offset;
  500. naddr(n->right, a);
  501. } else {
  502. naddr(n->right, a);
  503. v = a->offset;
  504. naddr(n->left, a);
  505. }
  506. a->offset += v;
  507. break;
  508. }
  509. }
  510. void
  511. gloadhi(Node *f, Node *t, int c)
  512. {
  513. Type *ot;
  514. if(f->op == OCONST){
  515. f = nodconst((int32_t)(f->vconst>>32));
  516. if(c==1 && sconst(f) || c==2 && uconst(f)){
  517. if(t->op == OREGISTER)
  518. regfree(t);
  519. *t = *f;
  520. return;
  521. }
  522. }
  523. if(f->op == OREGPAIR) {
  524. gmove(f->left, t);
  525. return;
  526. }
  527. ot = f->type;
  528. f->type = types[TLONG];
  529. gmove(f, t);
  530. f->type = ot;
  531. }
  532. void
  533. gloadlo(Node *f, Node *t, int c)
  534. {
  535. Type *ot;
  536. if(f->op == OCONST){
  537. f = nodconst((int32_t)f->vconst);
  538. if(c && uconst(f)){
  539. if(t->op == OREGISTER)
  540. regfree(t);
  541. *t = *f;
  542. return;
  543. }
  544. }
  545. if(f->op == OREGPAIR) {
  546. gmove(f->right, t);
  547. return;
  548. }
  549. ot = f->type;
  550. f->type = types[TLONG];
  551. f->xoffset += SZ_LONG;
  552. if(0){
  553. prtree(f, "gloadlo f"); prtree(t, "gloadlo t");
  554. }
  555. gmove(f, t);
  556. f->xoffset -= SZ_LONG;
  557. f->type = ot;
  558. }
  559. void
  560. fop(int as, int f1, int f2, Node *t)
  561. {
  562. Node nod1, nod2, nod3;
  563. nodreg(&nod1, t, NREG+f1);
  564. nodreg(&nod2, t, NREG+f2);
  565. regalloc(&nod3, t, t);
  566. gopcode(as, &nod1, &nod2, &nod3);
  567. gmove(&nod3, t);
  568. regfree(&nod3);
  569. }
  570. void
  571. gmove(Node *f, Node *t)
  572. {
  573. int ft, tt, a;
  574. Node nod, fxc0, fxc1, fxc2, fxrat;
  575. Prog *p1;
  576. double d;
  577. ft = f->type->etype;
  578. tt = t->type->etype;
  579. if(ft == TDOUBLE && f->op == OCONST) {
  580. d = f->fconst;
  581. if(d == 0.0) {
  582. a = FREGZERO;
  583. goto ffreg;
  584. }
  585. if(d == 0.5) {
  586. a = FREGHALF;
  587. goto ffreg;
  588. }
  589. if(d == 1.0) {
  590. a = FREGONE;
  591. goto ffreg;
  592. }
  593. if(d == 2.0) {
  594. a = FREGTWO;
  595. goto ffreg;
  596. }
  597. if(d == -.5) {
  598. fop(OSUB, FREGHALF, FREGZERO, t);
  599. return;
  600. }
  601. if(d == -1.0) {
  602. fop(OSUB, FREGONE, FREGZERO, t);
  603. return;
  604. }
  605. if(d == -2.0) {
  606. fop(OSUB, FREGTWO, FREGZERO, t);
  607. return;
  608. }
  609. if(d == 1.5) {
  610. fop(OADD, FREGONE, FREGHALF, t);
  611. return;
  612. }
  613. if(d == 2.5) {
  614. fop(OADD, FREGTWO, FREGHALF, t);
  615. return;
  616. }
  617. if(d == 3.0) {
  618. fop(OADD, FREGTWO, FREGONE, t);
  619. return;
  620. }
  621. }
  622. if(ft == TFLOAT && f->op == OCONST) {
  623. d = f->fconst;
  624. if(d == 0) {
  625. a = FREGZERO;
  626. ffreg:
  627. nodreg(&nod, f, NREG+a);
  628. gmove(&nod, t);
  629. return;
  630. }
  631. }
  632. if((ft == TVLONG || ft == TUVLONG) && f->op == OCONST && t->op == OREGPAIR) {
  633. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  634. gmove(nod32const(f->vconst>>32), t->left);
  635. else
  636. gmove(nod32const(f->vconst), t->left);
  637. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  638. gmove(nod32const(f->vconst), t->right);
  639. else
  640. gmove(nod32const(f->vconst>>32), t->right);
  641. return;
  642. }
  643. /*
  644. * a load --
  645. * put it into a register then
  646. * worry what to do with it.
  647. */
  648. if(f->op == ONAME || f->op == OINDREG || f->op == OIND) {
  649. switch(ft) {
  650. default:
  651. a = AMOVW;
  652. break;
  653. case TFLOAT:
  654. a = AFMOVS;
  655. break;
  656. case TDOUBLE:
  657. a = AFMOVD;
  658. break;
  659. case TCHAR:
  660. a = AMOVB;
  661. break;
  662. case TUCHAR:
  663. a = AMOVBZ;
  664. break;
  665. case TSHORT:
  666. a = AMOVH;
  667. break;
  668. case TUSHORT:
  669. a = AMOVHZ;
  670. break;
  671. }
  672. if(typev[ft]) {
  673. if(typev[tt]) {
  674. regalloc(&nod, f, t);
  675. /* low order first, because its value will be used first */
  676. f->xoffset += SZ_LONG;
  677. gins(AMOVW, f, nod.right);
  678. f->xoffset -= SZ_LONG;
  679. gins(AMOVW, f, nod.left);
  680. } else {
  681. /* assumed not float or double */
  682. regalloc(&nod, &regnode, t);
  683. f->xoffset += SZ_LONG;
  684. gins(AMOVW, f, &nod);
  685. f->xoffset -= SZ_LONG;
  686. }
  687. } else {
  688. regalloc(&nod, f, t);
  689. gins(a, f, &nod);
  690. }
  691. gmove(&nod, t);
  692. regfree(&nod);
  693. return;
  694. }
  695. /*
  696. * a store --
  697. * put it into a register then
  698. * store it.
  699. */
  700. if(t->op == ONAME || t->op == OINDREG || t->op == OIND) {
  701. switch(tt) {
  702. default:
  703. a = AMOVW;
  704. break;
  705. case TUCHAR:
  706. a = AMOVBZ;
  707. break;
  708. case TCHAR:
  709. a = AMOVB;
  710. break;
  711. case TUSHORT:
  712. a = AMOVHZ;
  713. break;
  714. case TSHORT:
  715. a = AMOVH;
  716. break;
  717. case TFLOAT:
  718. a = AFMOVS;
  719. break;
  720. case TDOUBLE:
  721. a = AFMOVD;
  722. break;
  723. }
  724. if(R0ISZERO && !typefd[ft] && vconst(f) == 0) {
  725. gins(a, f, t);
  726. if(typev[tt]) {
  727. t->xoffset += SZ_LONG;
  728. gins(a, f, t);
  729. t->xoffset -= SZ_LONG;
  730. }
  731. return;
  732. }
  733. if(ft == tt)
  734. regalloc(&nod, t, f);
  735. else
  736. regalloc(&nod, t, Z);
  737. gmove(f, &nod);
  738. if(typev[tt]) {
  739. t->xoffset += SZ_LONG;
  740. gins(a, nod.right, t);
  741. t->xoffset -= SZ_LONG;
  742. gins(a, nod.left, t);
  743. } else
  744. gins(a, &nod, t);
  745. regfree(&nod);
  746. return;
  747. }
  748. /*
  749. * type x type cross table
  750. */
  751. a = AGOK;
  752. switch(ft) {
  753. case TDOUBLE:
  754. case TFLOAT:
  755. switch(tt) {
  756. case TDOUBLE:
  757. a = AFMOVD;
  758. if(ft == TFLOAT)
  759. a = AFMOVS; /* AFMOVSD */
  760. break;
  761. case TFLOAT:
  762. a = AFRSP;
  763. if(ft == TFLOAT)
  764. a = AFMOVS;
  765. break;
  766. case TINT:
  767. case TUINT:
  768. case TLONG:
  769. case TULONG:
  770. case TIND:
  771. case TSHORT:
  772. case TUSHORT:
  773. case TCHAR:
  774. case TUCHAR:
  775. /* BUG: not right for unsigned long */
  776. regalloc(&nod, f, Z); /* should be type float */
  777. regsalloc(&fxrat, &fconstnode);
  778. gins(AFCTIWZ, f, &nod);
  779. gins(AFMOVD, &nod, &fxrat);
  780. regfree(&nod);
  781. fxrat.type = nodrat->type;
  782. fxrat.etype = nodrat->etype;
  783. fxrat.xoffset += 4;
  784. gins(AMOVW, &fxrat, t);
  785. gmove(t, t);
  786. return;
  787. }
  788. break;
  789. case TINT:
  790. case TUINT:
  791. case TLONG:
  792. case TULONG:
  793. case TIND:
  794. switch(tt) {
  795. case TDOUBLE:
  796. case TFLOAT:
  797. goto fxtofl;
  798. case TINT:
  799. case TUINT:
  800. case TLONG:
  801. case TULONG:
  802. case TIND:
  803. case TSHORT:
  804. case TUSHORT:
  805. case TCHAR:
  806. case TUCHAR:
  807. a = AMOVW;
  808. break;
  809. }
  810. break;
  811. case TSHORT:
  812. switch(tt) {
  813. case TDOUBLE:
  814. case TFLOAT:
  815. goto fxtofl;
  816. case TINT:
  817. case TUINT:
  818. case TLONG:
  819. case TULONG:
  820. case TIND:
  821. a = AMOVH;
  822. break;
  823. case TSHORT:
  824. case TUSHORT:
  825. case TCHAR:
  826. case TUCHAR:
  827. a = AMOVW;
  828. break;
  829. }
  830. break;
  831. case TUSHORT:
  832. switch(tt) {
  833. case TDOUBLE:
  834. case TFLOAT:
  835. goto fxtofl;
  836. case TINT:
  837. case TUINT:
  838. case TLONG:
  839. case TULONG:
  840. case TIND:
  841. a = AMOVHZ;
  842. break;
  843. case TSHORT:
  844. case TUSHORT:
  845. case TCHAR:
  846. case TUCHAR:
  847. a = AMOVW;
  848. break;
  849. }
  850. break;
  851. case TCHAR:
  852. switch(tt) {
  853. case TDOUBLE:
  854. case TFLOAT:
  855. goto fxtofl;
  856. case TINT:
  857. case TUINT:
  858. case TLONG:
  859. case TULONG:
  860. case TIND:
  861. case TSHORT:
  862. case TUSHORT:
  863. a = AMOVB;
  864. break;
  865. case TCHAR:
  866. case TUCHAR:
  867. a = AMOVW;
  868. break;
  869. }
  870. break;
  871. case TUCHAR:
  872. switch(tt) {
  873. case TDOUBLE:
  874. case TFLOAT:
  875. fxtofl:
  876. /*
  877. * rat[0] = 0x43300000; rat[1] = f^0x80000000;
  878. * t = *(double*)rat - FREGCVI;
  879. * is-unsigned(t) => if(t<0) t += 2^32;
  880. * could be streamlined for int-to-float
  881. */
  882. regalloc(&fxc0, f, Z);
  883. regalloc(&fxc2, f, Z);
  884. regsalloc(&fxrat, &fconstnode); /* should be type float */
  885. gins(AMOVW, nodconst(0x43300000L), &fxc0);
  886. gins(AMOVW, f, &fxc2);
  887. gins(AMOVW, &fxc0, &fxrat);
  888. gins(AXOR, nodconst(0x80000000L), &fxc2);
  889. fxc1 = fxrat;
  890. fxc1.type = nodrat->type;
  891. fxc1.etype = nodrat->etype;
  892. fxc1.xoffset += SZ_LONG;
  893. gins(AMOVW, &fxc2, &fxc1);
  894. regfree(&fxc2);
  895. regfree(&fxc0);
  896. regalloc(&nod, t, t); /* should be type float */
  897. gins(AFMOVD, &fxrat, &nod);
  898. nodreg(&fxc1, t, NREG+FREGCVI);
  899. gins(AFSUB, &fxc1, &nod);
  900. a = AFMOVD;
  901. if(tt == TFLOAT)
  902. a = AFRSP;
  903. gins(a, &nod, t);
  904. regfree(&nod);
  905. if(ft == TULONG) {
  906. regalloc(&nod, t, Z);
  907. if(tt == TFLOAT) {
  908. gins(AFCMPU, t, Z);
  909. p->to.type = D_FREG;
  910. p->to.reg = FREGZERO;
  911. gins(ABGE, Z, Z);
  912. p1 = p;
  913. gins(AFMOVS, nodfconst(4294967296.), &nod);
  914. gins(AFADDS, &nod, t);
  915. } else {
  916. gins(AFCMPU, t, Z);
  917. p->to.type = D_FREG;
  918. p->to.reg = FREGZERO;
  919. gins(ABGE, Z, Z);
  920. p1 = p;
  921. gins(AFMOVD, nodfconst(4294967296.), &nod);
  922. gins(AFADD, &nod, t);
  923. }
  924. patch(p1, pc);
  925. regfree(&nod);
  926. }
  927. return;
  928. case TINT:
  929. case TUINT:
  930. case TLONG:
  931. case TULONG:
  932. case TIND:
  933. case TSHORT:
  934. case TUSHORT:
  935. a = AMOVBZ;
  936. break;
  937. case TCHAR:
  938. case TUCHAR:
  939. a = AMOVW;
  940. break;
  941. }
  942. break;
  943. case TVLONG:
  944. case TUVLONG:
  945. switch(tt) {
  946. case TVLONG:
  947. case TUVLONG:
  948. a = AMOVW;
  949. break;
  950. }
  951. break;
  952. }
  953. if(a == AGOK)
  954. diag(Z, "bad opcode in gmove %T -> %T", f->type, t->type);
  955. if(a == AMOVW || a == AFMOVS || a == AFMOVD)
  956. if(samaddr(f, t))
  957. return;
  958. if(typev[ft]) {
  959. if(f->op != OREGPAIR || t->op != OREGPAIR)
  960. diag(Z, "bad vlong in gmove (%O->%O)", f->op, t->op);
  961. gins(a, f->left, t->left);
  962. gins(a, f->right, t->right);
  963. } else
  964. gins(a, f, t);
  965. }
  966. void
  967. gins(int a, Node *f, Node *t)
  968. {
  969. nextpc();
  970. p->as = a;
  971. if(f != Z)
  972. naddr(f, &p->from);
  973. if(t != Z)
  974. naddr(t, &p->to);
  975. if(debug['g'])
  976. print("%P\n", p);
  977. }
  978. void
  979. gins3(int a, Node *f1, Node *f2, Node *t)
  980. {
  981. Adr ta;
  982. nextpc();
  983. p->as = a;
  984. if(f1 != Z)
  985. naddr(f1, &p->from);
  986. if(f2 != Z && (f2->op != OREGISTER || !samaddr(f2, t))) {
  987. ta = zprog.from; /* TO DO */
  988. naddr(f2, &ta);
  989. p->reg = ta.reg;
  990. if(ta.type == D_CONST && ta.offset == 0) {
  991. if(R0ISZERO)
  992. p->reg = REGZERO;
  993. else
  994. diag(Z, "REGZERO in gins3 %A", a);
  995. }else if(ta.type == D_CONST)
  996. p->from3 = ta;
  997. }
  998. if(t != Z)
  999. naddr(t, &p->to);
  1000. if(debug['g'])
  1001. print("%P\n", p);
  1002. }
  1003. void
  1004. gins4(int a, Node *f1, Node *f2, Node *f3, Node *t)
  1005. {
  1006. Adr ta;
  1007. nextpc();
  1008. p->as = a;
  1009. naddr(f1, &p->from);
  1010. if(f2->op != OREGISTER && (f2->op != OCONST || vconst(f2) != 0))
  1011. diag(f2, "invalid gins4");
  1012. naddr(f2, &ta);
  1013. p->reg = ta.reg;
  1014. if(ta.type == D_CONST && ta.offset == 0)
  1015. p->reg = REGZERO;
  1016. naddr(f3, &p->from3);
  1017. naddr(t, &p->to);
  1018. if(debug['g'])
  1019. print("%P\n", p);
  1020. }
  1021. void
  1022. gopcode(int o, Node *f1, Node *f2, Node *t)
  1023. {
  1024. int a, et, uns;
  1025. if(o == OAS) {
  1026. gmove(f1, t);
  1027. return;
  1028. }
  1029. et = TLONG;
  1030. if(f1 != Z && f1->type != T) {
  1031. if(f1->op == OCONST && t != Z && t->type != T)
  1032. et = t->type->etype;
  1033. else
  1034. et = f1->type->etype;
  1035. }
  1036. if((typev[et] || t->type != T && typev[t->type->etype]) && o != OFUNC) {
  1037. gopcode64(o, f1, f2, t);
  1038. return;
  1039. }
  1040. uns = 0;
  1041. a = AGOK;
  1042. switch(o) {
  1043. case OASADD:
  1044. case OADD:
  1045. a = AADD;
  1046. if(et == TFLOAT)
  1047. a = AFADDS;
  1048. else
  1049. if(et == TDOUBLE)
  1050. a = AFADD;
  1051. break;
  1052. case OASSUB:
  1053. case OSUB:
  1054. a = ASUB;
  1055. if(et == TFLOAT)
  1056. a = AFSUBS;
  1057. else
  1058. if(et == TDOUBLE)
  1059. a = AFSUB;
  1060. break;
  1061. case OASOR:
  1062. case OOR:
  1063. a = AOR;
  1064. break;
  1065. case OASAND:
  1066. case OAND:
  1067. a = AAND;
  1068. if(f1->op == OCONST)
  1069. a = AANDCC;
  1070. break;
  1071. case OASXOR:
  1072. case OXOR:
  1073. a = AXOR;
  1074. break;
  1075. case OASLSHR:
  1076. case OLSHR:
  1077. a = ASRW;
  1078. break;
  1079. case OASASHR:
  1080. case OASHR:
  1081. a = ASRAW;
  1082. break;
  1083. case OASASHL:
  1084. case OASHL:
  1085. a = ASLW;
  1086. break;
  1087. case OFUNC:
  1088. a = ABL;
  1089. break;
  1090. case OASLMUL:
  1091. case OLMUL:
  1092. case OASMUL:
  1093. case OMUL:
  1094. if(et == TFLOAT) {
  1095. a = AFMULS;
  1096. break;
  1097. } else
  1098. if(et == TDOUBLE) {
  1099. a = AFMUL;
  1100. break;
  1101. }
  1102. a = AMULLW;
  1103. break;
  1104. case OASDIV:
  1105. case ODIV:
  1106. if(et == TFLOAT) {
  1107. a = AFDIVS;
  1108. break;
  1109. } else
  1110. if(et == TDOUBLE) {
  1111. a = AFDIV;
  1112. break;
  1113. }
  1114. a = ADIVW;
  1115. break;
  1116. case OASMOD:
  1117. case OMOD:
  1118. a = AREM;
  1119. break;
  1120. case OASLMOD:
  1121. case OLMOD:
  1122. a = AREMU;
  1123. break;
  1124. case OASLDIV:
  1125. case OLDIV:
  1126. a = ADIVWU;
  1127. break;
  1128. case OCOM:
  1129. a = ANOR;
  1130. break;
  1131. case ONEG:
  1132. a = ANEG;
  1133. if(et == TFLOAT || et == TDOUBLE)
  1134. a = AFNEG;
  1135. break;
  1136. case OEQ:
  1137. a = ABEQ;
  1138. if(t->op == OCONST && t->vconst >= (1<<15))
  1139. goto cmpu;
  1140. goto cmp;
  1141. case ONE:
  1142. a = ABNE;
  1143. if(t->op == OCONST && t->vconst >= (1<<15))
  1144. goto cmpu;
  1145. goto cmp;
  1146. case OLT:
  1147. a = ABLT;
  1148. goto cmp;
  1149. case OLE:
  1150. a = ABLE;
  1151. goto cmp;
  1152. case OGE:
  1153. a = ABGE;
  1154. goto cmp;
  1155. case OGT:
  1156. a = ABGT;
  1157. goto cmp;
  1158. case OLO:
  1159. a = ABLT;
  1160. goto cmpu;
  1161. case OLS:
  1162. a = ABLE;
  1163. goto cmpu;
  1164. case OHS:
  1165. a = ABGE;
  1166. goto cmpu;
  1167. case OHI:
  1168. a = ABGT;
  1169. goto cmpu;
  1170. cmpu:
  1171. uns = 1;
  1172. cmp:
  1173. nextpc();
  1174. p->as = uns? ACMPU: ACMP;
  1175. if(et == TFLOAT)
  1176. p->as = AFCMPU;
  1177. else
  1178. if(et == TDOUBLE)
  1179. p->as = AFCMPU;
  1180. if(f1 != Z)
  1181. naddr(f1, &p->from);
  1182. if(t != Z)
  1183. naddr(t, &p->to);
  1184. if(f1 == Z || t == Z || f2 != Z)
  1185. diag(Z, "bad cmp in gopcode %O", o);
  1186. if(debug['g'])
  1187. print("%P\n", p);
  1188. f1 = Z;
  1189. f2 = Z;
  1190. t = Z;
  1191. break;
  1192. }
  1193. if(a == AGOK)
  1194. diag(Z, "bad in gopcode %O", o);
  1195. gins3(a, f1, f2, t);
  1196. }
  1197. static void
  1198. gopcode64(int o, Node *f1, Node *f2, Node *t)
  1199. {
  1200. int a1, a2;
  1201. Node nod, nod1, nod2, sh;
  1202. uint32_t m;
  1203. Prog *p1;
  1204. if(t->op != OREGPAIR || f2 != Z && f2->op != OREGPAIR) {
  1205. diag(Z, "bad f2/dest in gopcode64 %O", o);
  1206. return;
  1207. }
  1208. if(f1->op != OCONST &&
  1209. (typev[f1->type->etype] && f1->op != OREGPAIR || !typev[f1->type->etype] && f1->op != OREGISTER)) {
  1210. diag(Z, "bad f1[%O] in gopcode64 %O", f1->op, o);
  1211. return;
  1212. }
  1213. /* a1 for low-order, a2 for high-order */
  1214. a1 = AGOK;
  1215. a2 = AGOK;
  1216. switch(o) {
  1217. case OASADD:
  1218. case OADD:
  1219. if(f1->op == OCONST && sconst(f1)) {
  1220. if(f2 == Z)
  1221. f2 = t;
  1222. gins3(AADDC, f1, f2->right, t->right);
  1223. if((f1->vconst>>32) == 0)
  1224. gins(AADDZE, f2->left, t->left);
  1225. else if((f1->vconst>>32) == -1)
  1226. gins(AADDME, f2->left, t->left);
  1227. else
  1228. diag(t, "odd vlong ADD: %lld", f1->vconst);
  1229. return;
  1230. }
  1231. a1 = AADDC;
  1232. a2 = AADDE;
  1233. break;
  1234. case OASSUB:
  1235. case OSUB:
  1236. a1 = ASUBC;
  1237. a2 = ASUBE;
  1238. break;
  1239. case OASOR:
  1240. case OOR:
  1241. if(f1->op == OCONST) {
  1242. gori64(AOR, f1, f2, t);
  1243. return;
  1244. }
  1245. a1 = a2 = AOR;
  1246. break;
  1247. case OASAND:
  1248. case OAND:
  1249. if(f1->op == OCONST) {
  1250. gandi64(AANDCC, f1, f2, t);
  1251. return;
  1252. }
  1253. a1 = a2 = AAND;
  1254. break;
  1255. case OASXOR:
  1256. case OXOR:
  1257. if(f1->op == OCONST) {
  1258. gori64(AXOR, f1, f2, t);
  1259. return;
  1260. }
  1261. a1 = a2 = AXOR;
  1262. break;
  1263. case OASLSHR:
  1264. case OLSHR:
  1265. if(f2 == Z)
  1266. f2 = t;
  1267. if(f1->op == OCONST) {
  1268. if(f1->vconst >= 32) {
  1269. if(f1->vconst == 32)
  1270. gmove(f2->left, t->right);
  1271. else if(f1->vconst < 64)
  1272. gins3(ASRW, nodconst(f1->vconst-32), f2->left, t->right);
  1273. else
  1274. gmove(nodconst(0), t->right);
  1275. gmove(nodconst(0), t->left);
  1276. return;
  1277. }
  1278. if(f1->vconst <= 0) {
  1279. if(f2 != t)
  1280. gmove(f2, t);
  1281. return;
  1282. }
  1283. sh = *nodconst(32 - f1->vconst);
  1284. m = 0xFFFFFFFFUL >> f1->vconst;
  1285. gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
  1286. gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
  1287. gins4(ARLWNM, &sh, f2->left, nodconst(m), t->left);
  1288. return;
  1289. }
  1290. regalloc(&nod, &regnode, Z);
  1291. gins3(ASUBC, f1, nodconst(32), &nod);
  1292. gins3(ASRW, f1, f2->right, t->right);
  1293. regalloc(&nod1, &regnode, Z);
  1294. gins3(ASLW, &nod, f2->left, &nod1);
  1295. gins(AOR, &nod1, t->right);
  1296. gins3(AADD, nodconst(-32), f1, &nod);
  1297. gins3(ASRW, &nod, f2->left, &nod1);
  1298. gins(AOR, &nod1, t->right);
  1299. gins3(ASRW, f1, f2->left, t->left);
  1300. regfree(&nod);
  1301. regfree(&nod1);
  1302. return;
  1303. case OASASHR:
  1304. case OASHR:
  1305. if(f2 == Z)
  1306. f2 = t;
  1307. if(f1->op == OCONST) {
  1308. if(f1->vconst >= 32) {
  1309. if(f1->vconst == 32)
  1310. gmove(f2->left, t->right);
  1311. else if(f1->vconst < 64)
  1312. gins3(ASRAW, nodconst(f1->vconst-32), f2->left, t->right);
  1313. gins3(ASRAW, nodconst(31), f2->left, t->left);
  1314. if(f1->vconst >= 64) {
  1315. gmove(t->left, t->right);
  1316. return;
  1317. }
  1318. return;
  1319. }
  1320. if(f1->vconst <= 0) {
  1321. if(f2 != t)
  1322. gmove(f2, t);
  1323. return;
  1324. }
  1325. sh = *nodconst(32 - f1->vconst);
  1326. m = 0xFFFFFFFFUL >> f1->vconst;
  1327. gins4(ARLWNM, &sh, f2->right, nodconst(m), t->right);
  1328. gins4(ARLWMI, &sh, f2->left, nodconst(~m), t->right);
  1329. gins3(ASRAW, &sh, f2->left, t->left);
  1330. return;
  1331. }
  1332. regalloc(&nod, &regnode, Z);
  1333. gins3(ASUBC, f1, nodconst(32), &nod);
  1334. gins3(ASRW, f1, f2->right, t->right);
  1335. regalloc(&nod1, &regnode, Z);
  1336. gins3(ASLW, &nod, f2->left, &nod1);
  1337. gins(AOR, &nod1, t->right);
  1338. gins3(AADDCCC, nodconst(-32), f1, &nod);
  1339. gins3(ASRAW, &nod, f2->left, &nod1);
  1340. gins(ABLE, Z, Z);
  1341. p1 = p;
  1342. gins(AMOVW, &nod1, t->right);
  1343. patch(p1, pc);
  1344. gins3(ASRAW, f1, f2->left, t->left);
  1345. regfree(&nod);
  1346. regfree(&nod1);
  1347. return;
  1348. case OASASHL:
  1349. case OASHL:
  1350. if(f2 == Z)
  1351. f2 = t;
  1352. if(f1->op == OCONST) {
  1353. if(f1->vconst >= 32) {
  1354. if(f1->vconst == 32)
  1355. gmove(f2->right, t->left);
  1356. else if(f1->vconst >= 64)
  1357. gmove(nodconst(0), t->left);
  1358. else
  1359. gins3(ASLW, nodconst(f1->vconst-32), f2->right, t->left);
  1360. gmove(nodconst(0), t->right);
  1361. return;
  1362. }
  1363. if(f1->vconst <= 0) {
  1364. if(f2 != t)
  1365. gmove(f2, t);
  1366. return;
  1367. }
  1368. m = 0xFFFFFFFFUL << f1->vconst;
  1369. gins4(ARLWNM, f1, f2->left, nodconst(m), t->left);
  1370. gins4(ARLWMI, f1, f2->right, nodconst(~m), t->left);
  1371. gins4(ARLWNM, f1, f2->right, nodconst(m), t->right);
  1372. return;
  1373. }
  1374. regalloc(&nod, &regnode, Z);
  1375. gins3(ASUBC, f1, nodconst(32), &nod);
  1376. gins3(ASLW, f1, f2->left, t->left);
  1377. regalloc(&nod1, &regnode, Z);
  1378. gins3(ASRW, &nod, f2->right, &nod1);
  1379. gins(AOR, &nod1, t->left);
  1380. gins3(AADD, nodconst(-32), f1, &nod);
  1381. gins3(ASLW, &nod, f2->right, &nod1);
  1382. gins(AOR, &nod1, t->left);
  1383. gins3(ASLW, f1, f2->right, t->right);
  1384. regfree(&nod);
  1385. regfree(&nod1);
  1386. return;
  1387. case OASLMUL:
  1388. case OLMUL:
  1389. case OASMUL:
  1390. case OMUL:
  1391. if(f2 == Z)
  1392. f2 = t;
  1393. regalloc(&nod, &regnode, Z);
  1394. gins3(AMULLW, f1->right, f2->right, &nod); /* lo(f2.low*f1.low) */
  1395. regalloc(&nod1, &regnode, Z);
  1396. gins3(AMULHWU, f1->right, f2->right, &nod1); /* hi(f2.low*f1.low) */
  1397. regalloc(&nod2, &regnode, Z);
  1398. gins3(AMULLW, f2->right, f1->left, &nod2); /* lo(f2.low*f1.high) */
  1399. gins(AADD, &nod2, &nod1);
  1400. gins3(AMULLW, f1->right, f2->left, &nod2); /* lo(f2.high*f1.low) */
  1401. gins(AADD, &nod2, &nod1);
  1402. regfree(&nod2);
  1403. gmove(&nod, t->right);
  1404. gmove(&nod1, t->left);
  1405. regfree(&nod);
  1406. regfree(&nod1);
  1407. return;
  1408. case OCOM:
  1409. a1 = a2 = ANOR;
  1410. break;
  1411. case ONEG:
  1412. gins3(ASUBC, t->right, nodconst(0), t->right);
  1413. gins(ASUBZE, t->left, t->left);
  1414. return;
  1415. }
  1416. if(a1 == AGOK || a2 == AGOK)
  1417. diag(Z, "bad in gopcode64 %O", o);
  1418. if(f1->op == OCONST) {
  1419. if(f2 != Z & f2 != t)
  1420. diag(Z, "bad const in gopcode64 %O", o);
  1421. gins(a1, nod32const(f1->vconst), t->right);
  1422. gins(a2, nod32const(f1->vconst>>32), t->left);
  1423. } else {
  1424. if(f2 != Z && f2 != t) {
  1425. gins3(a1, f1->right, f2->right, t->right);
  1426. gins3(a2, f1->left, f2->left, t->left);
  1427. } else {
  1428. gins(a1, f1->right, t->right);
  1429. gins(a2, f1->left, t->left);
  1430. }
  1431. }
  1432. }
  1433. samaddr(Node *f, Node *t)
  1434. {
  1435. if(f->op != t->op)
  1436. return 0;
  1437. switch(f->op) {
  1438. case OREGISTER:
  1439. if(f->reg != t->reg)
  1440. break;
  1441. return 1;
  1442. case OREGPAIR:
  1443. return samaddr(f->left, t->left) && samaddr(f->right, t->right);
  1444. }
  1445. return 0;
  1446. }
  1447. static void
  1448. gori64(int a, Node *f1, Node *f2, Node *t)
  1449. {
  1450. uint32_t lo, hi;
  1451. if(f2 == Z)
  1452. f2 = t;
  1453. lo = f1->vconst & MASK(32);
  1454. hi = (f1->vconst >> 32) & MASK(32);
  1455. if(lo & 0xFFFF)
  1456. gins3(a, nodconst(lo & 0xFFFF), f2->right, t->right);
  1457. if((lo >> 16) != 0)
  1458. gins3(a, nodconst(lo & 0xFFFF0000UL), f2->right, t->right);
  1459. if(hi & 0xFFFF)
  1460. gins3(a, nodconst(hi & 0xFFFF), f2->left, t->left);
  1461. if((hi >> 16) != 0)
  1462. gins3(a, nodconst(hi & 0xFFFF0000UL), f2->left, t->left);
  1463. }
  1464. static void
  1465. gandi64(int a, Node *f1, Node *f2, Node *t)
  1466. {
  1467. uint32_t lo, hi;
  1468. if(f2 == Z)
  1469. f2 = t;
  1470. lo = f1->vconst & MASK(32);
  1471. hi = (f1->vconst >> 32) & MASK(32);
  1472. if(lo == 0)
  1473. gins(AMOVW, nodconst(0), t->right);
  1474. else
  1475. gins3(a, nodconst(lo), f2->right, t->right);
  1476. if(hi == 0)
  1477. gins(AMOVW, nodconst(0), t->left);
  1478. else
  1479. gins3(a, nodconst(hi), f2->left, t->left);
  1480. }
  1481. void
  1482. gbranch(int o)
  1483. {
  1484. int a;
  1485. a = AGOK;
  1486. switch(o) {
  1487. case ORETURN:
  1488. a = ARETURN;
  1489. break;
  1490. case OGOTO:
  1491. a = ABR;
  1492. break;
  1493. }
  1494. nextpc();
  1495. if(a == AGOK) {
  1496. diag(Z, "bad in gbranch %O", o);
  1497. nextpc();
  1498. }
  1499. p->as = a;
  1500. }
  1501. void
  1502. patch(Prog *op, int32_t pc)
  1503. {
  1504. op->to.offset = pc;
  1505. op->to.type = D_BRANCH;
  1506. }
  1507. void
  1508. gpseudo(int a, Sym *s, Node *n)
  1509. {
  1510. nextpc();
  1511. p->as = a;
  1512. p->from.type = D_OREG;
  1513. p->from.sym = s;
  1514. if(a == ATEXT)
  1515. p->reg = (profileflg ? 0 : NOPROF);
  1516. p->from.name = D_EXTERN;
  1517. if(s->class == CSTATIC)
  1518. p->from.name = D_STATIC;
  1519. naddr(n, &p->to);
  1520. if(a == ADATA || a == AGLOBL)
  1521. pc--;
  1522. }
  1523. int
  1524. sval(int32_t v)
  1525. {
  1526. if(v >= -(1<<15) && v < (1<<15))
  1527. return 1;
  1528. return 0;
  1529. }
  1530. int
  1531. sconst(Node *n)
  1532. {
  1533. int64_t vv;
  1534. if(n->op == OCONST) {
  1535. if(!typefd[n->type->etype]) {
  1536. vv = n->vconst;
  1537. if(vv >= -(((int64_t)1)<<15) && vv < (((int64_t)1)<<15))
  1538. return 1;
  1539. }
  1540. }
  1541. return 0;
  1542. }
  1543. int
  1544. uconst(Node *n)
  1545. {
  1546. int64_t vv;
  1547. if(n->op == OCONST) {
  1548. if(!typefd[n->type->etype]) {
  1549. vv = n->vconst;
  1550. if(vv >= 0 && vv < (((int64_t)1)<<16))
  1551. return 1;
  1552. }
  1553. }
  1554. return 0;
  1555. }
  1556. int32_t
  1557. exreg(Type *t)
  1558. {
  1559. int32_t o;
  1560. if(typechlp[t->etype]) {
  1561. if(exregoffset <= 3)
  1562. return 0;
  1563. o = exregoffset;
  1564. exregoffset--;
  1565. return o;
  1566. }
  1567. if(typefd[t->etype]) {
  1568. if(exfregoffset <= 16)
  1569. return 0;
  1570. o = exfregoffset + NREG;
  1571. exfregoffset--;
  1572. return o;
  1573. }
  1574. return 0;
  1575. }
  1576. schar ewidth[NTYPE] =
  1577. {
  1578. -1, /* [TXXX] */
  1579. SZ_CHAR, /* [TCHAR] */
  1580. SZ_CHAR, /* [TUCHAR] */
  1581. SZ_SHORT, /* [TSHORT] */
  1582. SZ_SHORT, /* [TUSHORT] */
  1583. SZ_INT, /* [TINT] */
  1584. SZ_INT, /* [TUINT] */
  1585. SZ_LONG, /* [TLONG] */
  1586. SZ_LONG, /* [TULONG] */
  1587. SZ_VLONG, /* [TVLONG] */
  1588. SZ_VLONG, /* [TUVLONG] */
  1589. SZ_FLOAT, /* [TFLOAT] */
  1590. SZ_DOUBLE, /* [TDOUBLE] */
  1591. SZ_IND, /* [TIND] */
  1592. 0, /* [TFUNC] */
  1593. -1, /* [TARRAY] */
  1594. 0, /* [TVOID] */
  1595. -1, /* [TSTRUCT] */
  1596. -1, /* [TUNION] */
  1597. SZ_INT, /* [TENUM] */
  1598. };
  1599. int32_t ncast[NTYPE] =
  1600. {
  1601. 0, /* [TXXX] */
  1602. BCHAR|BUCHAR, /* [TCHAR] */
  1603. BCHAR|BUCHAR, /* [TUCHAR] */
  1604. BSHORT|BUSHORT, /* [TSHORT] */
  1605. BSHORT|BUSHORT, /* [TUSHORT] */
  1606. BINT|BUINT|BLONG|BULONG|BIND, /* [TINT] */
  1607. BINT|BUINT|BLONG|BULONG|BIND, /* [TUINT] */
  1608. BINT|BUINT|BLONG|BULONG|BIND, /* [TLONG] */
  1609. BINT|BUINT|BLONG|BULONG|BIND, /* [TULONG] */
  1610. BVLONG|BUVLONG, /* [TVLONG] */
  1611. BVLONG|BUVLONG, /* [TUVLONG] */
  1612. BFLOAT, /* [TFLOAT] */
  1613. BDOUBLE, /* [TDOUBLE] */
  1614. BLONG|BULONG|BIND, /* [TIND] */
  1615. 0, /* [TFUNC] */
  1616. 0, /* [TARRAY] */
  1617. 0, /* [TVOID] */
  1618. BSTRUCT, /* [TSTRUCT] */
  1619. BUNION, /* [TUNION] */
  1620. 0, /* [TENUM] */
  1621. };