cgen.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468
  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 void cmpv(Node*, int, Node*);
  11. static void testv(Node*, int);
  12. static void cgen64(Node*, Node*);
  13. static int isvconstable(int, int64_t);
  14. void
  15. cgen(Node *n, Node *nn)
  16. {
  17. Node *l, *r;
  18. Prog *p1;
  19. Node nod, nod1, nod2, nod3, nod4;
  20. int o;
  21. int32_t v, curs;
  22. if(debug['g']) {
  23. prtree(nn, "cgen lhs");
  24. prtree(n, "cgen");
  25. }
  26. if(n == Z || n->type == T)
  27. return;
  28. if(typesu[n->type->etype]) {
  29. sugen(n, nn, n->type->width);
  30. return;
  31. }
  32. if(typev[n->type->etype]) {
  33. switch(n->op) {
  34. case OCONST:
  35. case OFUNC:
  36. cgen64(n, nn);
  37. return;
  38. }
  39. }
  40. l = n->left;
  41. r = n->right;
  42. o = n->op;
  43. if(n->addable >= INDEXED) {
  44. if(nn == Z) {
  45. switch(o) {
  46. default:
  47. nullwarn(Z, Z);
  48. break;
  49. case OINDEX:
  50. nullwarn(l, r);
  51. break;
  52. }
  53. return;
  54. }
  55. gmove(n, nn);
  56. return;
  57. }
  58. curs = cursafe;
  59. if(n->complex >= FNX)
  60. if(l->complex >= FNX)
  61. if(r != Z && r->complex >= FNX)
  62. switch(o) {
  63. default:
  64. if(!typev[r->type->etype]) {
  65. regret(&nod, r);
  66. cgen(r, &nod);
  67. regsalloc(&nod1, r);
  68. gmove(&nod, &nod1);
  69. regfree(&nod);
  70. } else {
  71. regsalloc(&nod1, r);
  72. cgen(r, &nod1);
  73. }
  74. nod = *n;
  75. nod.right = &nod1;
  76. cgen(&nod, nn);
  77. return;
  78. case OFUNC:
  79. case OCOMMA:
  80. case OANDAND:
  81. case OOROR:
  82. case OCOND:
  83. case ODOT:
  84. break;
  85. }
  86. switch(o) {
  87. default:
  88. diag(n, "unknown op in cgen: %O", o);
  89. break;
  90. case ONEG:
  91. case OCOM:
  92. if(nn == Z) {
  93. nullwarn(l, Z);
  94. break;
  95. }
  96. regalloc(&nod, l, nn);
  97. cgen(l, &nod);
  98. gopcode(o, &nod, Z, &nod);
  99. gmove(&nod, nn);
  100. regfree(&nod);
  101. break;
  102. case OAS:
  103. if(l->op == OBIT)
  104. goto bitas;
  105. if(l->addable >= INDEXED) {
  106. if(nn != Z || r->addable < INDEXED) {
  107. regalloc(&nod, r, nn);
  108. cgen(r, &nod);
  109. gmove(&nod, l);
  110. regfree(&nod);
  111. } else
  112. gmove(r, l);
  113. break;
  114. }
  115. if(l->complex >= r->complex) {
  116. reglcgen(&nod1, l, Z);
  117. if(r->addable >= INDEXED) {
  118. gmove(r, &nod1);
  119. if(nn != Z)
  120. gmove(r, nn);
  121. regfree(&nod1);
  122. break;
  123. }
  124. regalloc(&nod, r, nn);
  125. cgen(r, &nod);
  126. } else {
  127. regalloc(&nod, r, nn);
  128. cgen(r, &nod);
  129. reglcgen(&nod1, l, Z);
  130. }
  131. gmove(&nod, &nod1);
  132. regfree(&nod);
  133. regfree(&nod1);
  134. break;
  135. bitas:
  136. n = l->left;
  137. regalloc(&nod, r, nn);
  138. if(l->complex >= r->complex) {
  139. reglcgen(&nod1, n, Z);
  140. cgen(r, &nod);
  141. } else {
  142. cgen(r, &nod);
  143. reglcgen(&nod1, n, Z);
  144. }
  145. regalloc(&nod2, n, Z);
  146. gopcode(OAS, &nod1, Z, &nod2);
  147. bitstore(l, &nod, &nod1, &nod2, nn);
  148. break;
  149. case OBIT:
  150. if(nn == Z) {
  151. nullwarn(l, Z);
  152. break;
  153. }
  154. bitload(n, &nod, Z, Z, nn);
  155. gopcode(OAS, &nod, Z, nn);
  156. regfree(&nod);
  157. break;
  158. case OXOR:
  159. if(nn != Z)
  160. if(r->op == OCONST && r->vconst == -1){
  161. regalloc(&nod, l, nn);
  162. cgen(l, &nod);
  163. gopcode(OCOM, &nod, Z, &nod);
  164. gmove(&nod, nn);
  165. regfree(&nod);
  166. break;
  167. }
  168. case OADD:
  169. case OSUB:
  170. case OAND:
  171. case OOR:
  172. case OLSHR:
  173. case OASHL:
  174. case OASHR:
  175. /*
  176. * immediate operands
  177. */
  178. if(nn != Z && r->op == OCONST && !typefd[n->type->etype] &&
  179. (!typev[n->type->etype] || isvconstable(o, r->vconst))) {
  180. regalloc(&nod, l, nn);
  181. cgen(l, &nod);
  182. if(o == OAND || r->vconst != 0)
  183. gopcode(o, r, Z, &nod);
  184. gmove(&nod, nn);
  185. regfree(&nod);
  186. break;
  187. }
  188. case OMUL:
  189. case OLMUL:
  190. case OLDIV:
  191. case OLMOD:
  192. case ODIV:
  193. case OMOD:
  194. if(nn == Z) {
  195. nullwarn(l, r);
  196. break;
  197. }
  198. if((o == OMUL || o == OLMUL) && !typev[n->type->etype]) {
  199. if(mulcon(n, nn))
  200. break;
  201. if(debug['M'])
  202. print("%L multiply\n", n->lineno);
  203. }
  204. if(l->complex >= r->complex) {
  205. regalloc(&nod, l, nn);
  206. cgen(l, &nod);
  207. if(o != OMUL || typev[n->type->etype] || !sconst(r)) {
  208. regalloc(&nod1, r, Z);
  209. cgen(r, &nod1);
  210. gopcode(o, &nod1, Z, &nod);
  211. regfree(&nod1);
  212. } else
  213. gopcode(o, r, Z, &nod);
  214. } else {
  215. regalloc(&nod1, r, nn);
  216. cgen(r, &nod1);
  217. regalloc(&nod, l, Z);
  218. cgen(l, &nod);
  219. gopcode(o, &nod1, Z, &nod);
  220. regfree(&nod1);
  221. }
  222. gopcode(OAS, &nod, Z, nn);
  223. regfree(&nod);
  224. break;
  225. case OASLSHR:
  226. case OASASHL:
  227. case OASASHR:
  228. case OASAND:
  229. case OASADD:
  230. case OASSUB:
  231. case OASXOR:
  232. case OASOR:
  233. if(l->op == OBIT)
  234. goto asbitop;
  235. if(r->op == OCONST && !typefd[r->type->etype] && !typefd[n->type->etype] &&
  236. (!typev[n->type->etype] || isvconstable(o, r->vconst))) {
  237. if(l->addable < INDEXED)
  238. reglcgen(&nod2, l, Z);
  239. else
  240. nod2 = *l;
  241. regalloc(&nod, l, nn);
  242. gopcode(OAS, &nod2, Z, &nod);
  243. gopcode(o, r, Z, &nod);
  244. gopcode(OAS, &nod, Z, &nod2);
  245. regfree(&nod);
  246. if(l->addable < INDEXED)
  247. regfree(&nod2);
  248. break;
  249. }
  250. case OASLMUL:
  251. case OASLDIV:
  252. case OASLMOD:
  253. case OASMUL:
  254. case OASDIV:
  255. case OASMOD:
  256. if(l->op == OBIT)
  257. goto asbitop;
  258. if(l->complex >= r->complex) {
  259. if(l->addable < INDEXED)
  260. reglcgen(&nod2, l, Z);
  261. else
  262. nod2 = *l;
  263. regalloc(&nod, r, Z);
  264. cgen(r, &nod);
  265. } else {
  266. regalloc(&nod, r, Z);
  267. cgen(r, &nod);
  268. if(l->addable < INDEXED)
  269. reglcgen(&nod2, l, Z);
  270. else
  271. nod2 = *l;
  272. }
  273. regalloc(&nod1, n, nn);
  274. gopcode(OAS, &nod2, Z, &nod1);
  275. gopcode(o, &nod, Z, &nod1);
  276. gopcode(OAS, &nod1, Z, &nod2);
  277. if(nn != Z)
  278. gopcode(OAS, &nod1, Z, nn);
  279. regfree(&nod);
  280. regfree(&nod1);
  281. if(l->addable < INDEXED)
  282. regfree(&nod2);
  283. break;
  284. asbitop:
  285. regalloc(&nod4, n, nn);
  286. regalloc(&nod3, r, Z);
  287. if(l->complex >= r->complex) {
  288. bitload(l, &nod, &nod1, &nod2, &nod4);
  289. cgen(r, &nod3);
  290. } else {
  291. cgen(r, &nod3);
  292. bitload(l, &nod, &nod1, &nod2, &nod4);
  293. }
  294. gmove(&nod, &nod4);
  295. gopcode(n->op, &nod3, Z, &nod4);
  296. regfree(&nod3);
  297. gmove(&nod4, &nod);
  298. regfree(&nod4);
  299. bitstore(l, &nod, &nod1, &nod2, nn);
  300. break;
  301. case OADDR:
  302. if(nn == Z) {
  303. nullwarn(l, Z);
  304. break;
  305. }
  306. lcgen(l, nn);
  307. break;
  308. case OFUNC:
  309. if(l->complex >= FNX) {
  310. if(l->op != OIND)
  311. diag(n, "bad function call");
  312. regret(&nod, l->left);
  313. cgen(l->left, &nod);
  314. regsalloc(&nod1, l->left);
  315. gopcode(OAS, &nod, Z, &nod1);
  316. regfree(&nod);
  317. nod = *n;
  318. nod.left = &nod2;
  319. nod2 = *l;
  320. nod2.left = &nod1;
  321. nod2.complex = 1;
  322. cgen(&nod, nn);
  323. return;
  324. }
  325. o = reg[REGARG];
  326. gargs(r, &nod, &nod1);
  327. if(l->addable < INDEXED) {
  328. reglcgen(&nod, l, Z);
  329. gopcode(OFUNC, Z, Z, &nod);
  330. regfree(&nod);
  331. } else
  332. gopcode(OFUNC, Z, Z, l);
  333. if(REGARG)
  334. if(o != reg[REGARG])
  335. reg[REGARG]--;
  336. if(nn != Z) {
  337. regret(&nod, n);
  338. gopcode(OAS, &nod, Z, nn);
  339. regfree(&nod);
  340. }
  341. break;
  342. case OIND:
  343. if(nn == Z) {
  344. cgen(l, nn);
  345. break;
  346. }
  347. regialloc(&nod, n, nn);
  348. r = l;
  349. while(r->op == OADD)
  350. r = r->right;
  351. if(sconst(r)) {
  352. v = r->vconst;
  353. r->vconst = 0;
  354. cgen(l, &nod);
  355. nod.xoffset += v;
  356. r->vconst = v;
  357. } else
  358. cgen(l, &nod);
  359. regind(&nod, n);
  360. gmove(&nod, nn);
  361. regfree(&nod);
  362. break;
  363. case OEQ:
  364. case ONE:
  365. case OLE:
  366. case OLT:
  367. case OGE:
  368. case OGT:
  369. case OLO:
  370. case OLS:
  371. case OHI:
  372. case OHS:
  373. if(nn == Z) {
  374. nullwarn(l, r);
  375. break;
  376. }
  377. boolgen(n, 1, nn);
  378. break;
  379. case OANDAND:
  380. case OOROR:
  381. boolgen(n, 1, nn);
  382. if(nn == Z)
  383. patch(p, pc);
  384. break;
  385. case ONOT:
  386. if(nn == Z) {
  387. nullwarn(l, Z);
  388. break;
  389. }
  390. boolgen(n, 1, nn);
  391. break;
  392. case OCOMMA:
  393. cgen(l, Z);
  394. cgen(r, nn);
  395. break;
  396. case OCAST:
  397. if(nn == Z) {
  398. nullwarn(l, Z);
  399. break;
  400. }
  401. /*
  402. * convert from types l->n->nn
  403. */
  404. if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
  405. /* both null, gen l->nn */
  406. cgen(l, nn);
  407. break;
  408. }
  409. if(typev[l->type->etype] || typev[n->type->etype]) {
  410. cgen64(n, nn);
  411. break;
  412. }
  413. regalloc(&nod, l, nn);
  414. cgen(l, &nod);
  415. regalloc(&nod1, n, &nod);
  416. gmove(&nod, &nod1);
  417. gmove(&nod1, nn);
  418. regfree(&nod1);
  419. regfree(&nod);
  420. break;
  421. case ODOT:
  422. sugen(l, nodrat, l->type->width);
  423. if(nn != Z) {
  424. warn(n, "non-interruptable temporary");
  425. nod = *nodrat;
  426. if(!r || r->op != OCONST) {
  427. diag(n, "DOT and no offset");
  428. break;
  429. }
  430. nod.xoffset += (int32_t)r->vconst;
  431. nod.type = n->type;
  432. cgen(&nod, nn);
  433. }
  434. break;
  435. case OCOND:
  436. bcgen(l, 1);
  437. p1 = p;
  438. cgen(r->left, nn);
  439. gbranch(OGOTO);
  440. patch(p1, pc);
  441. p1 = p;
  442. cgen(r->right, nn);
  443. patch(p1, pc);
  444. break;
  445. case OPOSTINC:
  446. case OPOSTDEC:
  447. v = 1;
  448. if(l->type->etype == TIND)
  449. v = l->type->link->width;
  450. if(o == OPOSTDEC)
  451. v = -v;
  452. if(l->op == OBIT)
  453. goto bitinc;
  454. if(nn == Z)
  455. goto pre;
  456. if(l->addable < INDEXED)
  457. reglcgen(&nod2, l, Z);
  458. else
  459. nod2 = *l;
  460. regalloc(&nod, l, nn);
  461. gopcode(OAS, &nod2, Z, &nod);
  462. regalloc(&nod1, l, Z);
  463. if(typefd[l->type->etype]) {
  464. regalloc(&nod3, l, Z);
  465. if(v < 0) {
  466. gopcode(OAS, nodfconst(-v), Z, &nod3);
  467. gopcode(OSUB, &nod3, &nod, &nod1);
  468. } else {
  469. gopcode(OAS, nodfconst(v), Z, &nod3);
  470. gopcode(OADD, &nod3, &nod, &nod1);
  471. }
  472. regfree(&nod3);
  473. } else
  474. gopcode(OADD, nodconst(v), &nod, &nod1);
  475. gopcode(OAS, &nod1, Z, &nod2);
  476. regfree(&nod);
  477. regfree(&nod1);
  478. if(l->addable < INDEXED)
  479. regfree(&nod2);
  480. break;
  481. case OPREINC:
  482. case OPREDEC:
  483. v = 1;
  484. if(l->type->etype == TIND)
  485. v = l->type->link->width;
  486. if(o == OPREDEC)
  487. v = -v;
  488. if(l->op == OBIT)
  489. goto bitinc;
  490. pre:
  491. if(l->addable < INDEXED)
  492. reglcgen(&nod2, l, Z);
  493. else
  494. nod2 = *l;
  495. regalloc(&nod, l, nn);
  496. gopcode(OAS, &nod2, Z, &nod);
  497. if(typefd[l->type->etype]) {
  498. regalloc(&nod3, l, Z);
  499. if(v < 0) {
  500. gopcode(OAS, nodfconst(-v), Z, &nod3);
  501. gopcode(OSUB, &nod3, Z, &nod);
  502. } else {
  503. gopcode(OAS, nodfconst(v), Z, &nod3);
  504. gopcode(OADD, &nod3, Z, &nod);
  505. }
  506. regfree(&nod3);
  507. } else
  508. gopcode(OADD, nodconst(v), Z, &nod);
  509. gopcode(OAS, &nod, Z, &nod2);
  510. if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
  511. gins(ANOP, l, Z);
  512. regfree(&nod);
  513. if(l->addable < INDEXED)
  514. regfree(&nod2);
  515. break;
  516. bitinc:
  517. if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
  518. bitload(l, &nod, &nod1, &nod2, Z);
  519. gopcode(OAS, &nod, Z, nn);
  520. gopcode(OADD, nodconst(v), Z, &nod);
  521. bitstore(l, &nod, &nod1, &nod2, Z);
  522. break;
  523. }
  524. bitload(l, &nod, &nod1, &nod2, nn);
  525. gopcode(OADD, nodconst(v), Z, &nod);
  526. bitstore(l, &nod, &nod1, &nod2, nn);
  527. break;
  528. }
  529. cursafe = curs;
  530. }
  531. void
  532. reglcgen(Node *t, Node *n, Node *nn)
  533. {
  534. Node *r;
  535. int32_t v;
  536. regialloc(t, n, nn);
  537. if(n->op == OIND) {
  538. r = n->left;
  539. while(r->op == OADD)
  540. r = r->right;
  541. if(sconst(r)) {
  542. v = r->vconst;
  543. r->vconst = 0;
  544. lcgen(n, t);
  545. t->xoffset += v;
  546. r->vconst = v;
  547. regind(t, n);
  548. return;
  549. }
  550. }
  551. lcgen(n, t);
  552. regind(t, n);
  553. }
  554. void
  555. lcgen(Node *n, Node *nn)
  556. {
  557. Prog *p1;
  558. Node nod;
  559. if(debug['g']) {
  560. prtree(nn, "lcgen lhs");
  561. prtree(n, "lcgen");
  562. }
  563. if(n == Z || n->type == T)
  564. return;
  565. if(nn == Z) {
  566. nn = &nod;
  567. regalloc(&nod, n, Z);
  568. }
  569. switch(n->op) {
  570. default:
  571. if(n->addable < INDEXED) {
  572. diag(n, "unknown op in lcgen: %O", n->op);
  573. break;
  574. }
  575. nod = *n;
  576. nod.op = OADDR;
  577. nod.left = n;
  578. nod.right = Z;
  579. nod.type = types[TIND];
  580. gopcode(OAS, &nod, Z, nn);
  581. break;
  582. case OCOMMA:
  583. cgen(n->left, n->left);
  584. lcgen(n->right, nn);
  585. break;
  586. case OIND:
  587. cgen(n->left, nn);
  588. break;
  589. case OCOND:
  590. bcgen(n->left, 1);
  591. p1 = p;
  592. lcgen(n->right->left, nn);
  593. gbranch(OGOTO);
  594. patch(p1, pc);
  595. p1 = p;
  596. lcgen(n->right->right, nn);
  597. patch(p1, pc);
  598. break;
  599. }
  600. }
  601. void
  602. bcgen(Node *n, int true)
  603. {
  604. if(n->type == T)
  605. gbranch(OGOTO);
  606. else
  607. boolgen(n, true, Z);
  608. }
  609. void
  610. boolgen(Node *n, int true, Node *nn)
  611. {
  612. int o, uns;
  613. Prog *p1, *p2;
  614. Node *l, *r, nod, nod1;
  615. int32_t curs;
  616. if(debug['g']) {
  617. prtree(nn, "boolgen lhs");
  618. prtree(n, "boolgen");
  619. }
  620. uns = 0;
  621. curs = cursafe;
  622. l = n->left;
  623. r = n->right;
  624. switch(n->op) {
  625. default:
  626. if(n->op == OCONST) {
  627. o = vconst(n);
  628. if(!true)
  629. o = !o;
  630. gbranch(OGOTO);
  631. if(o) {
  632. p1 = p;
  633. gbranch(OGOTO);
  634. patch(p1, pc);
  635. }
  636. goto com;
  637. }
  638. if(typev[n->type->etype]) {
  639. testv(n, true);
  640. goto com;
  641. }
  642. regalloc(&nod, n, nn);
  643. cgen(n, &nod);
  644. o = ONE;
  645. if(true)
  646. o = comrel[relindex(o)];
  647. if(typefd[n->type->etype]) {
  648. nodreg(&nod1, n, NREG+FREGZERO);
  649. gopcode(o, &nod, Z, &nod1);
  650. } else
  651. gopcode(o, &nod, Z, nodconst(0));
  652. regfree(&nod);
  653. goto com;
  654. case OCOMMA:
  655. cgen(l, Z);
  656. boolgen(r, true, nn);
  657. break;
  658. case ONOT:
  659. boolgen(l, !true, nn);
  660. break;
  661. case OCOND:
  662. bcgen(l, 1);
  663. p1 = p;
  664. bcgen(r->left, true);
  665. p2 = p;
  666. gbranch(OGOTO);
  667. patch(p1, pc);
  668. p1 = p;
  669. bcgen(r->right, !true);
  670. patch(p2, pc);
  671. p2 = p;
  672. gbranch(OGOTO);
  673. patch(p1, pc);
  674. patch(p2, pc);
  675. goto com;
  676. case OANDAND:
  677. if(!true)
  678. goto caseor;
  679. caseand:
  680. bcgen(l, true);
  681. p1 = p;
  682. bcgen(r, !true);
  683. p2 = p;
  684. patch(p1, pc);
  685. gbranch(OGOTO);
  686. patch(p2, pc);
  687. goto com;
  688. case OOROR:
  689. if(!true)
  690. goto caseand;
  691. caseor:
  692. bcgen(l, !true);
  693. p1 = p;
  694. bcgen(r, !true);
  695. p2 = p;
  696. gbranch(OGOTO);
  697. patch(p1, pc);
  698. patch(p2, pc);
  699. goto com;
  700. case OHI:
  701. case OHS:
  702. case OLO:
  703. case OLS:
  704. uns = 1;
  705. /* fall through */
  706. case OEQ:
  707. case ONE:
  708. case OLE:
  709. case OLT:
  710. case OGE:
  711. case OGT:
  712. if(typev[l->type->etype]){
  713. cmpv(n, true, Z);
  714. goto com;
  715. }
  716. o = n->op;
  717. if(true)
  718. o = comrel[relindex(o)];
  719. if(l->complex >= FNX && r->complex >= FNX) {
  720. regret(&nod, r);
  721. cgen(r, &nod);
  722. regsalloc(&nod1, r);
  723. gopcode(OAS, &nod, Z, &nod1);
  724. regfree(&nod);
  725. nod = *n;
  726. nod.right = &nod1;
  727. boolgen(&nod, true, nn);
  728. break;
  729. }
  730. if(!uns && sconst(r) || (uns || o == OEQ || o == ONE) && uconst(r)) {
  731. regalloc(&nod, l, nn);
  732. cgen(l, &nod);
  733. gopcode(o, &nod, Z, r);
  734. regfree(&nod);
  735. goto com;
  736. }
  737. if(l->complex >= r->complex) {
  738. regalloc(&nod1, l, nn);
  739. cgen(l, &nod1);
  740. regalloc(&nod, r, Z);
  741. cgen(r, &nod);
  742. } else {
  743. regalloc(&nod, r, nn);
  744. cgen(r, &nod);
  745. regalloc(&nod1, l, Z);
  746. cgen(l, &nod1);
  747. }
  748. gopcode(o, &nod1, Z, &nod);
  749. regfree(&nod);
  750. regfree(&nod1);
  751. com:
  752. if(nn != Z) {
  753. p1 = p;
  754. gopcode(OAS, nodconst(1L), Z, nn);
  755. gbranch(OGOTO);
  756. p2 = p;
  757. patch(p1, pc);
  758. gopcode(OAS, nodconst(0L), Z, nn);
  759. patch(p2, pc);
  760. }
  761. break;
  762. }
  763. cursafe = curs;
  764. }
  765. void
  766. sugen(Node *n, Node *nn, int32_t w)
  767. {
  768. Prog *p1;
  769. Node nod0, nod1, nod2, nod3, nod4, *l, *r;
  770. Type *t;
  771. int32_t pc1;
  772. int i, m, c;
  773. if(n == Z || n->type == T)
  774. return;
  775. if(nn == nodrat)
  776. if(w > nrathole)
  777. nrathole = w;
  778. if(debug['g']) {
  779. prtree(nn, "sugen lhs");
  780. prtree(n, "sugen");
  781. }
  782. if(typev[n->type->etype]) {
  783. diag(n, "old vlong sugen: %O", n->op);
  784. return;
  785. }
  786. switch(n->op) {
  787. case OIND:
  788. if(nn == Z) {
  789. nullwarn(n->left, Z);
  790. break;
  791. }
  792. default:
  793. goto copy;
  794. case ODOT:
  795. l = n->left;
  796. sugen(l, nodrat, l->type->width);
  797. if(nn != Z) {
  798. warn(n, "non-interruptable temporary");
  799. nod1 = *nodrat;
  800. r = n->right;
  801. if(!r || r->op != OCONST) {
  802. diag(n, "DOT and no offset");
  803. break;
  804. }
  805. nod1.xoffset += (int32_t)r->vconst;
  806. nod1.type = n->type;
  807. sugen(&nod1, nn, w);
  808. }
  809. break;
  810. case OSTRUCT:
  811. /*
  812. * rewrite so lhs has no side effects
  813. */
  814. if(nn != Z && side(nn)) {
  815. nod1 = *n;
  816. nod1.type = typ(TIND, n->type);
  817. regalloc(&nod2, &nod1, Z);
  818. lcgen(nn, &nod2);
  819. regsalloc(&nod0, &nod1);
  820. gopcode(OAS, &nod2, Z, &nod0);
  821. regfree(&nod2);
  822. nod1 = *n;
  823. nod1.op = OIND;
  824. nod1.left = &nod0;
  825. nod1.right = Z;
  826. nod1.complex = 1;
  827. sugen(n, &nod1, w);
  828. return;
  829. }
  830. r = n->left;
  831. for(t = n->type->link; t != T; t = t->down) {
  832. l = r;
  833. if(r->op == OLIST) {
  834. l = r->left;
  835. r = r->right;
  836. }
  837. if(nn == Z) {
  838. cgen(l, nn);
  839. continue;
  840. }
  841. /*
  842. * hand craft *(&nn + o) = l
  843. */
  844. nod0 = znode;
  845. nod0.op = OAS;
  846. nod0.type = t;
  847. nod0.left = &nod1;
  848. nod0.right = l;
  849. nod1 = znode;
  850. nod1.op = OIND;
  851. nod1.type = t;
  852. nod1.left = &nod2;
  853. nod2 = znode;
  854. nod2.op = OADD;
  855. nod2.type = typ(TIND, t);
  856. nod2.left = &nod3;
  857. nod2.right = &nod4;
  858. nod3 = znode;
  859. nod3.op = OADDR;
  860. nod3.type = nod2.type;
  861. nod3.left = nn;
  862. nod4 = znode;
  863. nod4.op = OCONST;
  864. nod4.type = nod2.type;
  865. nod4.vconst = t->offset;
  866. ccom(&nod0);
  867. acom(&nod0);
  868. xcom(&nod0);
  869. nod0.addable = 0;
  870. /* prtree(&nod0, "hand craft"); /* */
  871. cgen(&nod0, Z);
  872. }
  873. break;
  874. case OAS:
  875. if(nn == Z) {
  876. if(n->addable < INDEXED)
  877. sugen(n->right, n->left, w);
  878. break;
  879. }
  880. /* BOTCH -- functions can clobber rathole */
  881. sugen(n->right, nodrat, w);
  882. warn(n, "non-interruptable temporary");
  883. sugen(nodrat, n->left, w);
  884. sugen(nodrat, nn, w);
  885. break;
  886. case OFUNC:
  887. /* this transformation should probably be done earlier */
  888. if(nn == Z) {
  889. sugen(n, nodrat, w);
  890. break;
  891. }
  892. if(nn->op != OIND) {
  893. nn = new1(OADDR, nn, Z);
  894. nn->type = types[TIND];
  895. nn->addable = 0;
  896. } else
  897. nn = nn->left;
  898. n = new(OFUNC, n->left, new(OLIST, nn, n->right));
  899. n->complex = FNX;
  900. n->type = types[TVOID];
  901. n->left->type = types[TVOID];
  902. cgen(n, Z);
  903. break;
  904. case OCOND:
  905. bcgen(n->left, 1);
  906. p1 = p;
  907. sugen(n->right->left, nn, w);
  908. gbranch(OGOTO);
  909. patch(p1, pc);
  910. p1 = p;
  911. sugen(n->right->right, nn, w);
  912. patch(p1, pc);
  913. break;
  914. case OCOMMA:
  915. cgen(n->left, Z);
  916. sugen(n->right, nn, w);
  917. break;
  918. }
  919. return;
  920. copy:
  921. if(nn == Z)
  922. return;
  923. if(n->complex >= FNX && nn->complex >= FNX) {
  924. t = nn->type;
  925. nn->type = types[TLONG];
  926. regialloc(&nod1, nn, Z);
  927. lcgen(nn, &nod1);
  928. regsalloc(&nod2, nn);
  929. nn->type = t;
  930. gmove(&nod1, &nod2);
  931. regfree(&nod1);
  932. nod2.type = typ(TIND, t);
  933. nod1 = nod2;
  934. nod1.op = OIND;
  935. nod1.left = &nod2;
  936. nod1.right = Z;
  937. nod1.complex = 1;
  938. nod1.type = t;
  939. sugen(n, &nod1, w);
  940. return;
  941. }
  942. if(n->complex > nn->complex) {
  943. t = n->type;
  944. n->type = types[TLONG];
  945. reglcgen(&nod1, n, Z);
  946. n->type = t;
  947. t = nn->type;
  948. nn->type = types[TLONG];
  949. reglcgen(&nod2, nn, Z);
  950. nn->type = t;
  951. } else {
  952. t = nn->type;
  953. nn->type = types[TLONG];
  954. reglcgen(&nod2, nn, Z);
  955. nn->type = t;
  956. t = n->type;
  957. n->type = types[TLONG];
  958. reglcgen(&nod1, n, Z);
  959. n->type = t;
  960. }
  961. w /= SZ_LONG;
  962. if(w <= 5) {
  963. layout(&nod1, &nod2, w, 0, Z);
  964. goto out;
  965. }
  966. /*
  967. * minimize space for unrolling loop
  968. * 3,4,5 times. (6 or more is never minimum)
  969. * if small structure, try 2 also.
  970. */
  971. c = 0; /* set */
  972. m = 100;
  973. i = 3;
  974. if(w <= 15)
  975. i = 2;
  976. for(; i<=5; i++)
  977. if(i + w%i <= m) {
  978. c = i;
  979. m = c + w%c;
  980. }
  981. regalloc(&nod3, &regnode, Z);
  982. layout(&nod1, &nod2, w%c, w/c, &nod3);
  983. pc1 = pc;
  984. layout(&nod1, &nod2, c, 0, Z);
  985. gopcode(OSUB, nodconst(1L), Z, &nod3);
  986. nod1.op = OREGISTER;
  987. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
  988. nod2.op = OREGISTER;
  989. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
  990. gopcode(OGT, &nod3, Z, nodconst(0));
  991. patch(p, pc1);
  992. regfree(&nod3);
  993. out:
  994. regfree(&nod1);
  995. regfree(&nod2);
  996. }
  997. void
  998. layout(Node *f, Node *t, int c, int cv, Node *cn)
  999. {
  1000. Node t1, t2;
  1001. while(c > 3) {
  1002. layout(f, t, 2, 0, Z);
  1003. c -= 2;
  1004. }
  1005. regalloc(&t1, &regnode, Z);
  1006. regalloc(&t2, &regnode, Z);
  1007. if(c > 0) {
  1008. gopcode(OAS, f, Z, &t1);
  1009. f->xoffset += SZ_LONG;
  1010. }
  1011. if(cn != Z)
  1012. gopcode(OAS, nodconst(cv), Z, cn);
  1013. if(c > 1) {
  1014. gopcode(OAS, f, Z, &t2);
  1015. f->xoffset += SZ_LONG;
  1016. }
  1017. if(c > 0) {
  1018. gopcode(OAS, &t1, Z, t);
  1019. t->xoffset += SZ_LONG;
  1020. }
  1021. if(c > 2) {
  1022. gopcode(OAS, f, Z, &t1);
  1023. f->xoffset += SZ_LONG;
  1024. }
  1025. if(c > 1) {
  1026. gopcode(OAS, &t2, Z, t);
  1027. t->xoffset += SZ_LONG;
  1028. }
  1029. if(c > 2) {
  1030. gopcode(OAS, &t1, Z, t);
  1031. t->xoffset += SZ_LONG;
  1032. }
  1033. regfree(&t1);
  1034. regfree(&t2);
  1035. }
  1036. /*
  1037. * is the vlong's value directly addressible?
  1038. */
  1039. int
  1040. isvdirect(Node *n)
  1041. {
  1042. return n->op == ONAME || n->op == OCONST || n->op == OINDREG;
  1043. }
  1044. /*
  1045. * can the constant be used with given vlong op?
  1046. */
  1047. static int
  1048. isvconstable(int o, int64_t v)
  1049. {
  1050. switch(o) {
  1051. case OADD:
  1052. case OASADD:
  1053. /* there isn't an immediate form for ADDE/SUBE, but there are special ADDME/ADDZE etc */
  1054. return v == 0 || v == -1;
  1055. case OAND:
  1056. case OOR:
  1057. case OXOR:
  1058. case OLSHR:
  1059. case OASHL:
  1060. case OASHR:
  1061. case OASLSHR:
  1062. case OASASHL:
  1063. case OASASHR:
  1064. return 1;
  1065. }
  1066. return 0;
  1067. }
  1068. /*
  1069. * most 64-bit operations: cgen into a register pair, then operate.
  1070. * 64-bit comparisons are handled a little differently because the two underlying
  1071. * comparisons can be compiled separately, since the calculations don't interact.
  1072. */
  1073. static void
  1074. vcgen(Node *n, Node *o, int *f)
  1075. {
  1076. *f = 0;
  1077. if(!isvdirect(n)) {
  1078. if(n->complex >= FNX) {
  1079. regsalloc(o, n);
  1080. cgen(n, o);
  1081. return;
  1082. }
  1083. *f = 1;
  1084. if(n->addable < INDEXED && n->op != OIND && n->op != OINDEX) {
  1085. regalloc(o, n, Z);
  1086. cgen(n, o);
  1087. } else
  1088. reglcgen(o, n, Z);
  1089. } else
  1090. *o = *n;
  1091. }
  1092. static int
  1093. isuns(int op)
  1094. {
  1095. switch(op){
  1096. case OLO:
  1097. case OLS:
  1098. case OHI:
  1099. case OHS:
  1100. return 1;
  1101. default:
  1102. return 0;
  1103. }
  1104. }
  1105. static void
  1106. gcmpv(Node *l, Node *r, void (*mov)(Node*, Node*, int), int op)
  1107. {
  1108. Node vl, vr;
  1109. regalloc(&vl, &regnode, Z);
  1110. mov(l, &vl, 0);
  1111. regalloc(&vr, &regnode, Z);
  1112. mov(r, &vr, 1+isuns(op));
  1113. gopcode(op, &vl, Z, &vr);
  1114. if(vl.op == OREGISTER)
  1115. regfree(&vl);
  1116. if(vr.op == OREGISTER)
  1117. regfree(&vr);
  1118. }
  1119. static void
  1120. brcondv(Node *l, Node *r, int chi, int clo)
  1121. {
  1122. Prog *p1, *p2, *p3, *p4;
  1123. gcmpv(l, r, gloadhi, chi);
  1124. p1 = p;
  1125. gins(ABNE, Z, Z);
  1126. p2 = p;
  1127. gcmpv(l, r, gloadlo, clo);
  1128. p3 = p;
  1129. gbranch(OGOTO);
  1130. p4 = p;
  1131. patch(p1, pc);
  1132. patch(p3, pc);
  1133. gbranch(OGOTO);
  1134. patch(p2, pc);
  1135. patch(p4, pc);
  1136. }
  1137. static void
  1138. testv(Node *n, int true)
  1139. {
  1140. Node nod;
  1141. nod = znode;
  1142. nod.op = ONE;
  1143. nod.left = n;
  1144. nod.right = new1(0, Z, Z);
  1145. *nod.right = *nodconst(0);
  1146. nod.right->type = n->type;
  1147. nod.type = types[TLONG];
  1148. cmpv(&nod, true, Z);
  1149. }
  1150. /*
  1151. * comparison for vlong does high and low order parts separately,
  1152. * which saves loading the latter if the high order comparison suffices
  1153. */
  1154. static void
  1155. cmpv(Node *n, int true, Node *nn)
  1156. {
  1157. Node *l, *r, nod, nod1;
  1158. int o, f1, f2;
  1159. Prog *p1, *p2;
  1160. int32_t curs;
  1161. if(debug['g']) {
  1162. if(nn != nil)
  1163. prtree(nn, "cmpv lhs");
  1164. prtree(n, "cmpv");
  1165. }
  1166. curs = cursafe;
  1167. l = n->left;
  1168. r = n->right;
  1169. if(l->complex >= FNX && r->complex >= FNX) {
  1170. regsalloc(&nod1, r);
  1171. cgen(r, &nod1);
  1172. nod = *n;
  1173. nod.right = &nod1;
  1174. cmpv(&nod, true, nn);
  1175. cursafe = curs;
  1176. return;
  1177. }
  1178. if(l->complex >= r->complex) {
  1179. vcgen(l, &nod1, &f1);
  1180. vcgen(r, &nod, &f2);
  1181. } else {
  1182. vcgen(r, &nod, &f2);
  1183. vcgen(l, &nod1, &f1);
  1184. }
  1185. nod.type = types[TLONG];
  1186. nod1.type = types[TLONG];
  1187. o = n->op;
  1188. if(true)
  1189. o = comrel[relindex(o)];
  1190. switch(o){
  1191. case OEQ:
  1192. gcmpv(&nod1, &nod, gloadhi, ONE);
  1193. p1 = p;
  1194. gcmpv(&nod1, &nod, gloadlo, ONE);
  1195. p2 = p;
  1196. gbranch(OGOTO);
  1197. patch(p1, pc);
  1198. patch(p2, pc);
  1199. break;
  1200. case ONE:
  1201. gcmpv(&nod1, &nod, gloadhi, ONE);
  1202. p1 = p;
  1203. gcmpv(&nod1, &nod, gloadlo, OEQ);
  1204. p2 = p;
  1205. patch(p1, pc);
  1206. gbranch(OGOTO);
  1207. patch(p2, pc);
  1208. break;
  1209. case OLE:
  1210. brcondv(&nod1, &nod, OLT, OLS);
  1211. break;
  1212. case OGT:
  1213. brcondv(&nod1, &nod, OGT, OHI);
  1214. break;
  1215. case OLS:
  1216. brcondv(&nod1, &nod, OLO, OLS);
  1217. break;
  1218. case OHI:
  1219. brcondv(&nod1, &nod, OHI, OHI);
  1220. break;
  1221. case OLT:
  1222. brcondv(&nod1, &nod, OLT, OLO);
  1223. break;
  1224. case OGE:
  1225. brcondv(&nod1, &nod, OGT, OHS);
  1226. break;
  1227. case OLO:
  1228. brcondv(&nod1, &nod, OLO, OLO);
  1229. break;
  1230. case OHS:
  1231. brcondv(&nod1, &nod, OHI, OHS);
  1232. break;
  1233. default:
  1234. diag(n, "bad cmpv");
  1235. return;
  1236. }
  1237. if(f1)
  1238. regfree(&nod1);
  1239. if(f2)
  1240. regfree(&nod);
  1241. cursafe = curs;
  1242. }
  1243. static void
  1244. cgen64(Node *n, Node *nn)
  1245. {
  1246. Node *l, *r, *d;
  1247. Node nod, nod1;
  1248. int32_t curs;
  1249. Type *t;
  1250. int o, m;
  1251. curs = cursafe;
  1252. l = n->left;
  1253. r = n->right;
  1254. o = n->op;
  1255. switch(o) {
  1256. case OCONST:
  1257. if(nn == Z) {
  1258. nullwarn(n->left, Z);
  1259. break;
  1260. }
  1261. if(nn->op != OREGPAIR) {
  1262. //prtree(n, "cgen64 const");
  1263. t = nn->type;
  1264. nn->type = types[TLONG];
  1265. reglcgen(&nod1, nn, Z);
  1266. nn->type = t;
  1267. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  1268. gmove(nod32const(n->vconst>>32), &nod1);
  1269. else
  1270. gmove(nod32const(n->vconst), &nod1);
  1271. nod1.xoffset += SZ_LONG;
  1272. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  1273. gmove(nod32const(n->vconst), &nod1);
  1274. else
  1275. gmove(nod32const(n->vconst>>32), &nod1);
  1276. regfree(&nod1);
  1277. } else
  1278. gmove(n, nn);
  1279. break;
  1280. case OCAST:
  1281. /*
  1282. * convert from types l->n->nn
  1283. */
  1284. if(typev[l->type->etype]){
  1285. /* vlong to non-vlong */
  1286. if(!isvdirect(l)) {
  1287. if(l->addable < INDEXED && l->op != OIND && l->op != OINDEX) {
  1288. regalloc(&nod, l, l);
  1289. cgen(l, &nod);
  1290. regalloc(&nod1, n, nn);
  1291. gmove(nod.right, &nod1);
  1292. } else {
  1293. reglcgen(&nod, l, Z);
  1294. regalloc(&nod1, n, nn);
  1295. gloadlo(&nod, &nod1, 0); /* TO DO: not correct for typefd */
  1296. }
  1297. regfree(&nod);
  1298. } else {
  1299. regalloc(&nod1, n, nn);
  1300. gloadlo(l, &nod1, 0); /* TO DO: not correct for typefd */
  1301. }
  1302. }else{
  1303. /* non-vlong to vlong */
  1304. regalloc(&nod, l, Z);
  1305. cgen(l, &nod);
  1306. regalloc(&nod1, n, nn);
  1307. gmove(&nod, nod1.right);
  1308. if(typeu[l->type->etype])
  1309. gmove(nodconst(0), nod1.left);
  1310. else
  1311. gopcode(OASHR, nodconst(31), nod1.right, nod1.left);
  1312. regfree(&nod);
  1313. }
  1314. gmove(&nod1, nn);
  1315. regfree(&nod1);
  1316. break;
  1317. case OFUNC:
  1318. /* this transformation should probably be done earlier */
  1319. if(nn == Z) {
  1320. regsalloc(&nod1, n);
  1321. nn = &nod1;
  1322. }
  1323. m = 0;
  1324. if(nn->op != OIND) {
  1325. if(nn->op == OREGPAIR) {
  1326. m = 1;
  1327. regsalloc(&nod1, nn);
  1328. d = &nod1;
  1329. }else
  1330. d = nn;
  1331. d = new1(OADDR, d, Z);
  1332. d->type = types[TIND];
  1333. d->addable = 0;
  1334. } else
  1335. d = nn->left;
  1336. n = new(OFUNC, l, new(OLIST, d, r));
  1337. n->complex = FNX;
  1338. n->type = types[TVOID];
  1339. n->left->type = types[TVOID];
  1340. cgen(n, Z);
  1341. if(m)
  1342. gmove(&nod1, nn);
  1343. break;
  1344. default:
  1345. diag(n, "bad cgen64 %O", o);
  1346. break;
  1347. }
  1348. cursafe = curs;
  1349. }