cgen.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861
  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. /* ,x/^(print|prtree)\(/i/\/\/ */
  11. void
  12. cgen(Node *n, Node *nn)
  13. {
  14. Node *l, *r, *t;
  15. Prog *p1;
  16. Node nod, nod1, nod2, nod3, nod4;
  17. int o, hardleft;
  18. int32_t v, curs;
  19. int64_t c;
  20. if(debug['g']) {
  21. prtree(nn, "cgen lhs");
  22. prtree(n, "cgen");
  23. }
  24. if(n == Z || n->type == T)
  25. return;
  26. if(typesuv[n->type->etype]) {
  27. sugen(n, nn, n->type->width);
  28. return;
  29. }
  30. l = n->left;
  31. r = n->right;
  32. o = n->op;
  33. // Go's version does the following, but it's the wrong place: doesn't allow assignment
  34. // if(o == OEXREG || nn != Z && nn->op == OEXREG) {
  35. // gmove(n, nn);
  36. // return;
  37. // }
  38. if(n->addable >= INDEXED) {
  39. if(nn == Z) {
  40. switch(o) {
  41. default:
  42. nullwarn(Z, Z);
  43. break;
  44. case OINDEX:
  45. nullwarn(l, r);
  46. break;
  47. }
  48. return;
  49. }
  50. gmove(n, nn);
  51. return;
  52. }
  53. curs = cursafe;
  54. if(l->complex >= FNX)
  55. if(r != Z && r->complex >= FNX)
  56. switch(o) {
  57. default:
  58. if(cond(o) && typesuv[l->type->etype])
  59. break;
  60. regret(&nod, r);
  61. cgen(r, &nod);
  62. regsalloc(&nod1, r);
  63. gmove(&nod, &nod1);
  64. regfree(&nod);
  65. nod = *n;
  66. nod.right = &nod1;
  67. cgen(&nod, nn);
  68. return;
  69. case OFUNC:
  70. case OCOMMA:
  71. case OANDAND:
  72. case OOROR:
  73. case OCOND:
  74. case ODOT:
  75. break;
  76. }
  77. hardleft = l->addable < INDEXED || l->complex >= FNX;
  78. switch(o) {
  79. default:
  80. diag(n, "unknown op in cgen: %O", o);
  81. break;
  82. case ONEG:
  83. case OCOM:
  84. if(nn == Z) {
  85. nullwarn(l, Z);
  86. break;
  87. }
  88. regalloc(&nod, l, nn);
  89. cgen(l, &nod);
  90. gopcode(o, n->type, Z, &nod);
  91. gmove(&nod, nn);
  92. regfree(&nod);
  93. break;
  94. case OAS:
  95. if(typefd[n->type->etype]) {
  96. cgen(r, &fregnode0);
  97. if(nn != Z)
  98. gins(AFMOVD, &fregnode0, &fregnode0);
  99. if(l->addable < INDEXED) {
  100. reglcgen(&nod, l, Z);
  101. gmove(&fregnode0, &nod);
  102. regfree(&nod);
  103. } else
  104. gmove(&fregnode0, l);
  105. if(nn != Z)
  106. gmove(&fregnode0, nn);
  107. return;
  108. }
  109. if(l->op == OBIT)
  110. goto bitas;
  111. if(!hardleft) {
  112. if(nn != Z || r->addable < INDEXED) {
  113. if(r->complex >= FNX && nn == Z)
  114. regret(&nod, r);
  115. else
  116. regalloc(&nod, r, nn);
  117. cgen(r, &nod);
  118. gmove(&nod, l);
  119. if(nn != Z)
  120. gmove(&nod, nn);
  121. regfree(&nod);
  122. } else
  123. gmove(r, l);
  124. break;
  125. }
  126. if(l->complex >= r->complex) {
  127. if(l->op == OINDEX && r->op == OCONST) {
  128. gmove(r, l);
  129. break;
  130. }
  131. reglcgen(&nod1, l, Z);
  132. if(r->addable >= INDEXED) {
  133. gmove(r, &nod1);
  134. if(nn != Z)
  135. gmove(r, nn);
  136. regfree(&nod1);
  137. break;
  138. }
  139. regalloc(&nod, r, nn);
  140. cgen(r, &nod);
  141. } else {
  142. regalloc(&nod, r, nn);
  143. cgen(r, &nod);
  144. reglcgen(&nod1, l, Z);
  145. }
  146. gmove(&nod, &nod1);
  147. regfree(&nod);
  148. regfree(&nod1);
  149. break;
  150. bitas:
  151. n = l->left;
  152. regalloc(&nod, r, nn);
  153. if(l->complex >= r->complex) {
  154. reglcgen(&nod1, n, Z);
  155. cgen(r, &nod);
  156. } else {
  157. cgen(r, &nod);
  158. reglcgen(&nod1, n, Z);
  159. }
  160. regalloc(&nod2, n, Z);
  161. gmove(&nod1, &nod2);
  162. bitstore(l, &nod, &nod1, &nod2, nn);
  163. break;
  164. case OBIT:
  165. if(nn == Z) {
  166. nullwarn(l, Z);
  167. break;
  168. }
  169. bitload(n, &nod, Z, Z, nn);
  170. gmove(&nod, nn);
  171. regfree(&nod);
  172. break;
  173. case OLSHR:
  174. case OASHL:
  175. case OASHR:
  176. if(nn == Z) {
  177. nullwarn(l, r);
  178. break;
  179. }
  180. if(r->op == OCONST) {
  181. if(r->vconst == 0) {
  182. cgen(l, nn);
  183. break;
  184. }
  185. regalloc(&nod, l, nn);
  186. cgen(l, &nod);
  187. if(o == OASHL && r->vconst == 1)
  188. gopcode(OADD, n->type, &nod, &nod);
  189. else
  190. gopcode(o, n->type, r, &nod);
  191. gmove(&nod, nn);
  192. regfree(&nod);
  193. break;
  194. }
  195. /*
  196. * get nod to be D_CX
  197. */
  198. if(nodreg(&nod, nn, D_CX)) {
  199. regsalloc(&nod1, n);
  200. gmove(&nod, &nod1);
  201. cgen(n, &nod); /* probably a bug */
  202. gmove(&nod, nn);
  203. gmove(&nod1, &nod);
  204. break;
  205. }
  206. reg[D_CX]++;
  207. if(nn->op == OREGISTER && nn->reg == D_CX)
  208. regalloc(&nod1, l, Z);
  209. else
  210. regalloc(&nod1, l, nn);
  211. if(r->complex >= l->complex) {
  212. cgen(r, &nod);
  213. cgen(l, &nod1);
  214. } else {
  215. cgen(l, &nod1);
  216. cgen(r, &nod);
  217. }
  218. gopcode(o, n->type, &nod, &nod1);
  219. gmove(&nod1, nn);
  220. regfree(&nod);
  221. regfree(&nod1);
  222. break;
  223. case OADD:
  224. case OSUB:
  225. case OOR:
  226. case OXOR:
  227. case OAND:
  228. if(nn == Z) {
  229. nullwarn(l, r);
  230. break;
  231. }
  232. if(typefd[n->type->etype])
  233. goto fop;
  234. if(r->op == OCONST) {
  235. if(r->vconst == 0 && o != OAND) {
  236. cgen(l, nn);
  237. break;
  238. }
  239. }
  240. if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
  241. && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
  242. c = l->right->vconst;
  243. if(c > 0 && c <= 3 && nareg(1) >= 4) {
  244. if(l->left->complex >= r->complex) {
  245. regalloc(&nod, l->left, nn);
  246. cgen(l->left, &nod);
  247. if(r->addable < INDEXED) {
  248. regalloc(&nod1, r, Z);
  249. cgen(r, &nod1);
  250. genmuladd(&nod, &nod, 1 << c, &nod1);
  251. regfree(&nod1);
  252. }
  253. else
  254. genmuladd(&nod, &nod, 1 << c, r);
  255. }
  256. else {
  257. regalloc(&nod, r, nn);
  258. cgen(r, &nod);
  259. regalloc(&nod1, l->left, Z);
  260. cgen(l->left, &nod1);
  261. genmuladd(&nod, &nod1, 1 << c, &nod);
  262. regfree(&nod1);
  263. }
  264. gmove(&nod, nn);
  265. regfree(&nod);
  266. break;
  267. }
  268. }
  269. if(r->addable >= INDEXED) {
  270. regalloc(&nod, l, nn);
  271. cgen(l, &nod);
  272. gopcode(o, n->type, r, &nod);
  273. gmove(&nod, nn);
  274. regfree(&nod);
  275. break;
  276. }
  277. if(l->complex >= r->complex) {
  278. regalloc(&nod, l, nn);
  279. cgen(l, &nod);
  280. regalloc(&nod1, r, Z);
  281. cgen(r, &nod1);
  282. gopcode(o, n->type, &nod1, &nod);
  283. } else {
  284. regalloc(&nod1, r, nn);
  285. cgen(r, &nod1);
  286. regalloc(&nod, l, Z);
  287. cgen(l, &nod);
  288. gopcode(o, n->type, &nod1, &nod);
  289. }
  290. gmove(&nod, nn);
  291. regfree(&nod);
  292. regfree(&nod1);
  293. break;
  294. case OLMOD:
  295. case OMOD:
  296. case OLMUL:
  297. case OLDIV:
  298. case OMUL:
  299. case ODIV:
  300. if(nn == Z) {
  301. nullwarn(l, r);
  302. break;
  303. }
  304. if(typefd[n->type->etype])
  305. goto fop;
  306. if(r->op == OCONST) {
  307. SET(v);
  308. switch(o) {
  309. case ODIV:
  310. case OMOD:
  311. c = r->vconst;
  312. if(c < 0)
  313. c = -c;
  314. v = log2(c);
  315. if(v < 0)
  316. break;
  317. /* fall thru */
  318. case OMUL:
  319. case OLMUL:
  320. regalloc(&nod, l, nn);
  321. cgen(l, &nod);
  322. switch(o) {
  323. case OMUL:
  324. case OLMUL:
  325. mulgen(n->type, r, &nod);
  326. break;
  327. case ODIV:
  328. sdiv2(r->vconst, v, l, &nod);
  329. break;
  330. case OMOD:
  331. smod2(r->vconst, v, l, &nod);
  332. break;
  333. }
  334. gmove(&nod, nn);
  335. regfree(&nod);
  336. goto done;
  337. case OLDIV:
  338. c = r->vconst;
  339. if((c & 0x80000000) == 0)
  340. break;
  341. regalloc(&nod1, l, Z);
  342. cgen(l, &nod1);
  343. regalloc(&nod, l, nn);
  344. zeroregm(&nod);
  345. gins(ACMPL, &nod1, nodconst(c));
  346. gins(ASBBL, nodconst(-1), &nod);
  347. regfree(&nod1);
  348. gmove(&nod, nn);
  349. regfree(&nod);
  350. goto done;
  351. }
  352. }
  353. if(o == OMUL) {
  354. if(l->addable >= INDEXED) {
  355. t = l;
  356. l = r;
  357. r = t;
  358. goto imula;
  359. }
  360. else if(r->addable >= INDEXED) {
  361. imula:
  362. /* should favour AX */
  363. regalloc(&nod, l, nn);
  364. cgen(l, &nod);
  365. gopcode(OMUL, n->type, r, &nod);
  366. }
  367. else {
  368. /* should favour AX */
  369. regalloc(&nod, l, nn);
  370. cgen(l, &nod);
  371. regalloc(&nod1, r, Z);
  372. cgen(r, &nod1);
  373. gopcode(OMUL, n->type, &nod1, &nod);
  374. regfree(&nod1);
  375. }
  376. gmove(&nod, nn);
  377. regfree(&nod);
  378. goto done;
  379. }
  380. /*
  381. * get nod to be D_AX
  382. * get nod1 to be D_DX
  383. */
  384. if(nodreg(&nod, nn, D_AX)) {
  385. regsalloc(&nod2, n);
  386. gmove(&nod, &nod2);
  387. v = reg[D_AX];
  388. reg[D_AX] = 0;
  389. if(isreg(l, D_AX)) {
  390. nod3 = *n;
  391. nod3.left = &nod2;
  392. cgen(&nod3, nn);
  393. } else
  394. if(isreg(r, D_AX)) {
  395. nod3 = *n;
  396. nod3.right = &nod2;
  397. cgen(&nod3, nn);
  398. } else
  399. cgen(n, nn);
  400. gmove(&nod2, &nod);
  401. reg[D_AX] = v;
  402. break;
  403. }
  404. if(nodreg(&nod1, nn, D_DX)) {
  405. regsalloc(&nod2, n);
  406. gmove(&nod1, &nod2);
  407. v = reg[D_DX];
  408. reg[D_DX] = 0;
  409. if(isreg(l, D_DX)) {
  410. nod3 = *n;
  411. nod3.left = &nod2;
  412. cgen(&nod3, nn);
  413. } else
  414. if(isreg(r, D_DX)) {
  415. nod3 = *n;
  416. nod3.right = &nod2;
  417. cgen(&nod3, nn);
  418. } else
  419. cgen(n, nn);
  420. gmove(&nod2, &nod1);
  421. reg[D_DX] = v;
  422. break;
  423. }
  424. reg[D_AX]++;
  425. if(r->op == OCONST) {
  426. switch(o) {
  427. case ODIV:
  428. reg[D_DX]++;
  429. if(l->addable < INDEXED) {
  430. regalloc(&nod2, l, Z);
  431. cgen(l, &nod2);
  432. l = &nod2;
  433. }
  434. sdivgen(l, r, &nod, &nod1);
  435. gmove(&nod1, nn);
  436. if(l == &nod2)
  437. regfree(l);
  438. goto freeaxdx;
  439. case OLDIV:
  440. reg[D_DX]++;
  441. if(l->addable < INDEXED) {
  442. regalloc(&nod2, l, Z);
  443. cgen(l, &nod2);
  444. l = &nod2;
  445. }
  446. udivgen(l, r, &nod, &nod1);
  447. gmove(&nod1, nn);
  448. if(l == &nod2)
  449. regfree(l);
  450. goto freeaxdx;
  451. }
  452. }
  453. if(l->complex >= r->complex) {
  454. cgen(l, &nod);
  455. reg[D_DX]++;
  456. if(o == ODIV || o == OMOD)
  457. gins(ACDQ, Z, Z);
  458. if(o == OLDIV || o == OLMOD)
  459. zeroregm(&nod1);
  460. if(r->addable < INDEXED || r->op == OCONST) {
  461. regsalloc(&nod3, r);
  462. cgen(r, &nod3);
  463. gopcode(o, n->type, &nod3, Z);
  464. } else
  465. gopcode(o, n->type, r, Z);
  466. } else {
  467. regsalloc(&nod3, r);
  468. cgen(r, &nod3);
  469. cgen(l, &nod);
  470. reg[D_DX]++;
  471. if(o == ODIV || o == OMOD)
  472. gins(ACDQ, Z, Z);
  473. if(o == OLDIV || o == OLMOD)
  474. zeroregm(&nod1);
  475. gopcode(o, n->type, &nod3, Z);
  476. }
  477. if(o == OMOD || o == OLMOD)
  478. gmove(&nod1, nn);
  479. else
  480. gmove(&nod, nn);
  481. freeaxdx:
  482. regfree(&nod);
  483. regfree(&nod1);
  484. break;
  485. case OASLSHR:
  486. case OASASHL:
  487. case OASASHR:
  488. if(r->op == OCONST)
  489. goto asand;
  490. if(l->op == OBIT)
  491. goto asbitop;
  492. if(typefd[n->type->etype])
  493. goto asfop;
  494. /*
  495. * get nod to be D_CX
  496. */
  497. if(nodreg(&nod, nn, D_CX)) {
  498. regsalloc(&nod1, n);
  499. gmove(&nod, &nod1);
  500. cgen(n, &nod);
  501. if(nn != Z)
  502. gmove(&nod, nn);
  503. gmove(&nod1, &nod);
  504. break;
  505. }
  506. reg[D_CX]++;
  507. if(r->complex >= l->complex) {
  508. cgen(r, &nod);
  509. if(hardleft)
  510. reglcgen(&nod1, l, Z);
  511. else
  512. nod1 = *l;
  513. } else {
  514. if(hardleft)
  515. reglcgen(&nod1, l, Z);
  516. else
  517. nod1 = *l;
  518. cgen(r, &nod);
  519. }
  520. gopcode(o, l->type, &nod, &nod1);
  521. regfree(&nod);
  522. if(nn != Z)
  523. gmove(&nod1, nn);
  524. if(hardleft)
  525. regfree(&nod1);
  526. break;
  527. case OASAND:
  528. case OASADD:
  529. case OASSUB:
  530. case OASXOR:
  531. case OASOR:
  532. asand:
  533. if(l->op == OBIT)
  534. goto asbitop;
  535. if(typefd[n->type->etype]||typefd[r->type->etype])
  536. goto asfop;
  537. if(l->complex >= r->complex) {
  538. if(hardleft)
  539. reglcgen(&nod, l, Z);
  540. else
  541. nod = *l;
  542. if(r->op != OCONST) {
  543. regalloc(&nod1, r, nn);
  544. cgen(r, &nod1);
  545. gopcode(o, l->type, &nod1, &nod);
  546. regfree(&nod1);
  547. } else
  548. gopcode(o, l->type, r, &nod);
  549. } else {
  550. regalloc(&nod1, r, nn);
  551. cgen(r, &nod1);
  552. if(hardleft)
  553. reglcgen(&nod, l, Z);
  554. else
  555. nod = *l;
  556. gopcode(o, l->type, &nod1, &nod);
  557. regfree(&nod1);
  558. }
  559. if(nn != Z)
  560. gmove(&nod, nn);
  561. if(hardleft)
  562. regfree(&nod);
  563. break;
  564. case OASLMUL:
  565. case OASLDIV:
  566. case OASLMOD:
  567. case OASMUL:
  568. case OASDIV:
  569. case OASMOD:
  570. if(l->op == OBIT)
  571. goto asbitop;
  572. if(typefd[n->type->etype]||typefd[r->type->etype])
  573. goto asfop;
  574. if(r->op == OCONST) {
  575. SET(v);
  576. switch(o) {
  577. case OASDIV:
  578. case OASMOD:
  579. c = r->vconst;
  580. if(c < 0)
  581. c = -c;
  582. v = log2(c);
  583. if(v < 0)
  584. break;
  585. /* fall thru */
  586. case OASMUL:
  587. case OASLMUL:
  588. if(hardleft)
  589. reglcgen(&nod2, l, Z);
  590. else
  591. nod2 = *l;
  592. regalloc(&nod, l, nn);
  593. cgen(&nod2, &nod);
  594. switch(o) {
  595. case OASMUL:
  596. case OASLMUL:
  597. mulgen(n->type, r, &nod);
  598. break;
  599. case OASDIV:
  600. sdiv2(r->vconst, v, l, &nod);
  601. break;
  602. case OASMOD:
  603. smod2(r->vconst, v, l, &nod);
  604. break;
  605. }
  606. havev:
  607. gmove(&nod, &nod2);
  608. if(nn != Z)
  609. gmove(&nod, nn);
  610. if(hardleft)
  611. regfree(&nod2);
  612. regfree(&nod);
  613. goto done;
  614. case OASLDIV:
  615. c = r->vconst;
  616. if((c & 0x80000000) == 0)
  617. break;
  618. if(hardleft)
  619. reglcgen(&nod2, l, Z);
  620. else
  621. nod2 = *l;
  622. regalloc(&nod1, l, nn);
  623. cgen(&nod2, &nod1);
  624. regalloc(&nod, l, nn);
  625. zeroregm(&nod);
  626. gins(ACMPL, &nod1, nodconst(c));
  627. gins(ASBBL, nodconst(-1), &nod);
  628. regfree(&nod1);
  629. goto havev;
  630. }
  631. }
  632. if(o == OASMUL) {
  633. /* should favour AX */
  634. regalloc(&nod, l, nn);
  635. if(r->complex >= FNX) {
  636. regalloc(&nod1, r, Z);
  637. cgen(r, &nod1);
  638. r = &nod1;
  639. }
  640. if(hardleft)
  641. reglcgen(&nod2, l, Z);
  642. else
  643. nod2 = *l;
  644. cgen(&nod2, &nod);
  645. if(r->addable < INDEXED) {
  646. if(r->complex < FNX) {
  647. regalloc(&nod1, r, Z);
  648. cgen(r, &nod1);
  649. }
  650. gopcode(OASMUL, n->type, &nod1, &nod);
  651. regfree(&nod1);
  652. }
  653. else
  654. gopcode(OASMUL, n->type, r, &nod);
  655. if(r == &nod1)
  656. regfree(r);
  657. gmove(&nod, &nod2);
  658. if(nn != Z)
  659. gmove(&nod, nn);
  660. regfree(&nod);
  661. if(hardleft)
  662. regfree(&nod2);
  663. goto done;
  664. }
  665. /*
  666. * get nod to be D_AX
  667. * get nod1 to be D_DX
  668. */
  669. if(nodreg(&nod, nn, D_AX)) {
  670. regsalloc(&nod2, n);
  671. gmove(&nod, &nod2);
  672. v = reg[D_AX];
  673. reg[D_AX] = 0;
  674. if(isreg(l, D_AX)) {
  675. nod3 = *n;
  676. nod3.left = &nod2;
  677. cgen(&nod3, nn);
  678. } else
  679. if(isreg(r, D_AX)) {
  680. nod3 = *n;
  681. nod3.right = &nod2;
  682. cgen(&nod3, nn);
  683. } else
  684. cgen(n, nn);
  685. gmove(&nod2, &nod);
  686. reg[D_AX] = v;
  687. break;
  688. }
  689. if(nodreg(&nod1, nn, D_DX)) {
  690. regsalloc(&nod2, n);
  691. gmove(&nod1, &nod2);
  692. v = reg[D_DX];
  693. reg[D_DX] = 0;
  694. if(isreg(l, D_DX)) {
  695. nod3 = *n;
  696. nod3.left = &nod2;
  697. cgen(&nod3, nn);
  698. } else
  699. if(isreg(r, D_DX)) {
  700. nod3 = *n;
  701. nod3.right = &nod2;
  702. cgen(&nod3, nn);
  703. } else
  704. cgen(n, nn);
  705. gmove(&nod2, &nod1);
  706. reg[D_DX] = v;
  707. break;
  708. }
  709. reg[D_AX]++;
  710. reg[D_DX]++;
  711. if(l->complex >= r->complex) {
  712. if(hardleft)
  713. reglcgen(&nod2, l, Z);
  714. else
  715. nod2 = *l;
  716. cgen(&nod2, &nod);
  717. if(r->op == OCONST) {
  718. switch(o) {
  719. case OASDIV:
  720. sdivgen(&nod2, r, &nod, &nod1);
  721. goto divdone;
  722. case OASLDIV:
  723. udivgen(&nod2, r, &nod, &nod1);
  724. divdone:
  725. gmove(&nod1, &nod2);
  726. if(nn != Z)
  727. gmove(&nod1, nn);
  728. goto freelxaxdx;
  729. }
  730. }
  731. if(o == OASDIV || o == OASMOD)
  732. gins(ACDQ, Z, Z);
  733. if(o == OASLDIV || o == OASLMOD)
  734. zeroregm(&nod1);
  735. if(r->addable < INDEXED || r->op == OCONST ||
  736. !typeil[r->type->etype]) {
  737. regalloc(&nod3, r, Z);
  738. cgen(r, &nod3);
  739. gopcode(o, l->type, &nod3, Z);
  740. regfree(&nod3);
  741. } else
  742. gopcode(o, n->type, r, Z);
  743. } else {
  744. regalloc(&nod3, r, Z);
  745. cgen(r, &nod3);
  746. if(hardleft)
  747. reglcgen(&nod2, l, Z);
  748. else
  749. nod2 = *l;
  750. cgen(&nod2, &nod);
  751. if(o == OASDIV || o == OASMOD)
  752. gins(ACDQ, Z, Z);
  753. if(o == OASLDIV || o == OASLMOD)
  754. zeroregm(&nod1);
  755. gopcode(o, l->type, &nod3, Z);
  756. regfree(&nod3);
  757. }
  758. if(o == OASMOD || o == OASLMOD) {
  759. gmove(&nod1, &nod2);
  760. if(nn != Z)
  761. gmove(&nod1, nn);
  762. } else {
  763. gmove(&nod, &nod2);
  764. if(nn != Z)
  765. gmove(&nod, nn);
  766. }
  767. freelxaxdx:
  768. if(hardleft)
  769. regfree(&nod2);
  770. regfree(&nod);
  771. regfree(&nod1);
  772. break;
  773. fop:
  774. if(l->complex >= r->complex) {
  775. cgen(l, &fregnode0);
  776. if(r->addable < INDEXED) {
  777. cgen(r, &fregnode0);
  778. fgopcode(o, &fregnode0, &fregnode1, 1, 0);
  779. } else
  780. fgopcode(o, r, &fregnode0, 0, 0);
  781. } else {
  782. cgen(r, &fregnode0);
  783. if(l->addable < INDEXED) {
  784. cgen(l, &fregnode0);
  785. fgopcode(o, &fregnode0, &fregnode1, 1, 1);
  786. } else
  787. fgopcode(o, l, &fregnode0, 0, 1);
  788. }
  789. gmove(&fregnode0, nn);
  790. break;
  791. asfop:
  792. if(l->complex >= r->complex) {
  793. if(hardleft)
  794. reglcgen(&nod, l, Z);
  795. else
  796. nod = *l;
  797. cgen(r, &fregnode0);
  798. } else {
  799. cgen(r, &fregnode0);
  800. if(hardleft)
  801. reglcgen(&nod, l, Z);
  802. else
  803. nod = *l;
  804. }
  805. if(!typefd[l->type->etype]) {
  806. gmove(&nod, &fregnode0);
  807. fgopcode(o, &fregnode0, &fregnode1, 1, 1);
  808. } else
  809. fgopcode(o, &nod, &fregnode0, 0, 1);
  810. if(nn != Z)
  811. gins(AFMOVD, &fregnode0, &fregnode0);
  812. gmove(&fregnode0, &nod);
  813. if(nn != Z)
  814. gmove(&fregnode0, nn);
  815. if(hardleft)
  816. regfree(&nod);
  817. break;
  818. asbitop:
  819. regalloc(&nod4, n, nn);
  820. if(l->complex >= r->complex) {
  821. bitload(l, &nod, &nod1, &nod2, &nod4);
  822. regalloc(&nod3, r, Z);
  823. cgen(r, &nod3);
  824. } else {
  825. regalloc(&nod3, r, Z);
  826. cgen(r, &nod3);
  827. bitload(l, &nod, &nod1, &nod2, &nod4);
  828. }
  829. gmove(&nod, &nod4);
  830. if(typefd[nod3.type->etype])
  831. fgopcode(o, &fregnode0, &fregnode1, 1, 1);
  832. else {
  833. Node onod;
  834. /* incredible grot ... */
  835. onod = nod3;
  836. onod.op = o;
  837. onod.complex = 2;
  838. onod.addable = 0;
  839. onod.type = tfield;
  840. onod.left = &nod4;
  841. onod.right = &nod3;
  842. cgen(&onod, Z);
  843. }
  844. regfree(&nod3);
  845. gmove(&nod4, &nod);
  846. regfree(&nod4);
  847. bitstore(l, &nod, &nod1, &nod2, nn);
  848. break;
  849. case OADDR:
  850. if(nn == Z) {
  851. nullwarn(l, Z);
  852. break;
  853. }
  854. lcgen(l, nn);
  855. break;
  856. case OFUNC:
  857. l = uncomma(l);
  858. if(l->complex >= FNX) {
  859. if(l->op != OIND)
  860. diag(n, "bad function call");
  861. regret(&nod, l->left);
  862. cgen(l->left, &nod);
  863. regsalloc(&nod1, l->left);
  864. gmove(&nod, &nod1);
  865. regfree(&nod);
  866. nod = *n;
  867. nod.left = &nod2;
  868. nod2 = *l;
  869. nod2.left = &nod1;
  870. nod2.complex = 1;
  871. cgen(&nod, nn);
  872. return;
  873. }
  874. gargs(r, &nod, &nod1);
  875. if(l->addable < INDEXED) {
  876. reglcgen(&nod, l, nn);
  877. nod.op = OREGISTER;
  878. gopcode(OFUNC, n->type, Z, &nod);
  879. regfree(&nod);
  880. } else
  881. gopcode(OFUNC, n->type, Z, l);
  882. if(REGARG>=0 && reg[REGARG])
  883. reg[REGARG]--;
  884. if(nn != Z) {
  885. regret(&nod, n);
  886. gmove(&nod, nn);
  887. regfree(&nod);
  888. } else
  889. if(typefd[n->type->etype])
  890. gins(AFMOVDP, &fregnode0, &fregnode0);
  891. break;
  892. case OIND:
  893. if(nn == Z) {
  894. nullwarn(l, Z);
  895. break;
  896. }
  897. regialloc(&nod, n, nn);
  898. r = l;
  899. while(r->op == OADD)
  900. r = r->right;
  901. if(sconst(r)) {
  902. v = r->vconst;
  903. r->vconst = 0;
  904. cgen(l, &nod);
  905. nod.xoffset += v;
  906. r->vconst = v;
  907. } else
  908. cgen(l, &nod);
  909. regind(&nod, n);
  910. gmove(&nod, nn);
  911. regfree(&nod);
  912. break;
  913. case OEQ:
  914. case ONE:
  915. case OLE:
  916. case OLT:
  917. case OGE:
  918. case OGT:
  919. case OLO:
  920. case OLS:
  921. case OHI:
  922. case OHS:
  923. if(nn == Z) {
  924. nullwarn(l, r);
  925. break;
  926. }
  927. boolgen(n, 1, nn);
  928. break;
  929. case OANDAND:
  930. case OOROR:
  931. boolgen(n, 1, nn);
  932. if(nn == Z)
  933. patch(p, pc);
  934. break;
  935. case ONOT:
  936. if(nn == Z) {
  937. nullwarn(l, Z);
  938. break;
  939. }
  940. boolgen(n, 1, nn);
  941. break;
  942. case OCOMMA:
  943. cgen(l, Z);
  944. cgen(r, nn);
  945. break;
  946. case OCAST:
  947. if(nn == Z) {
  948. nullwarn(l, Z);
  949. break;
  950. }
  951. /*
  952. * convert from types l->n->nn
  953. */
  954. if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
  955. /* both null, gen l->nn */
  956. cgen(l, nn);
  957. break;
  958. }
  959. if(typev[l->type->etype]) {
  960. cgen64(n, nn);
  961. break;
  962. }
  963. regalloc(&nod, l, nn);
  964. cgen(l, &nod);
  965. regalloc(&nod1, n, &nod);
  966. gmove(&nod, &nod1);
  967. gmove(&nod1, nn);
  968. regfree(&nod1);
  969. regfree(&nod);
  970. break;
  971. case ODOT:
  972. sugen(l, nodrat, l->type->width);
  973. if(nn == Z)
  974. break;
  975. warn(n, "non-interruptable temporary");
  976. nod = *nodrat;
  977. if(!r || r->op != OCONST) {
  978. diag(n, "DOT and no offset");
  979. break;
  980. }
  981. nod.xoffset += (int32_t)r->vconst;
  982. nod.type = n->type;
  983. cgen(&nod, nn);
  984. break;
  985. case OCOND:
  986. bcgen(l, 1);
  987. p1 = p;
  988. cgen(r->left, nn);
  989. gbranch(OGOTO);
  990. patch(p1, pc);
  991. p1 = p;
  992. cgen(r->right, nn);
  993. patch(p1, pc);
  994. break;
  995. case OPOSTINC:
  996. case OPOSTDEC:
  997. v = 1;
  998. if(l->type->etype == TIND)
  999. v = l->type->link->width;
  1000. if(o == OPOSTDEC)
  1001. v = -v;
  1002. if(l->op == OBIT)
  1003. goto bitinc;
  1004. if(nn == Z)
  1005. goto pre;
  1006. if(hardleft)
  1007. reglcgen(&nod, l, Z);
  1008. else
  1009. nod = *l;
  1010. if(typefd[n->type->etype])
  1011. goto fltinc;
  1012. gmove(&nod, nn);
  1013. gopcode(OADD, n->type, nodconst(v), &nod);
  1014. if(hardleft)
  1015. regfree(&nod);
  1016. break;
  1017. case OPREINC:
  1018. case OPREDEC:
  1019. v = 1;
  1020. if(l->type->etype == TIND)
  1021. v = l->type->link->width;
  1022. if(o == OPREDEC)
  1023. v = -v;
  1024. if(l->op == OBIT)
  1025. goto bitinc;
  1026. pre:
  1027. if(hardleft)
  1028. reglcgen(&nod, l, Z);
  1029. else
  1030. nod = *l;
  1031. if(typefd[n->type->etype])
  1032. goto fltinc;
  1033. gopcode(OADD, n->type, nodconst(v), &nod);
  1034. if(nn != Z)
  1035. gmove(&nod, nn);
  1036. if(hardleft)
  1037. regfree(&nod);
  1038. break;
  1039. fltinc:
  1040. gmove(&nod, &fregnode0);
  1041. if(nn != Z && (o == OPOSTINC || o == OPOSTDEC))
  1042. gins(AFMOVD, &fregnode0, &fregnode0);
  1043. gins(AFLD1, Z, Z);
  1044. if(v < 0)
  1045. fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0);
  1046. else
  1047. fgopcode(OADD, &fregnode0, &fregnode1, 1, 0);
  1048. if(nn != Z && (o == OPREINC || o == OPREDEC))
  1049. gins(AFMOVD, &fregnode0, &fregnode0);
  1050. gmove(&fregnode0, &nod);
  1051. if(hardleft)
  1052. regfree(&nod);
  1053. break;
  1054. bitinc:
  1055. if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
  1056. bitload(l, &nod, &nod1, &nod2, Z);
  1057. gmove(&nod, nn);
  1058. gopcode(OADD, tfield, nodconst(v), &nod);
  1059. bitstore(l, &nod, &nod1, &nod2, Z);
  1060. break;
  1061. }
  1062. bitload(l, &nod, &nod1, &nod2, nn);
  1063. gopcode(OADD, tfield, nodconst(v), &nod);
  1064. bitstore(l, &nod, &nod1, &nod2, nn);
  1065. break;
  1066. }
  1067. done:
  1068. cursafe = curs;
  1069. }
  1070. void
  1071. reglcgen(Node *t, Node *n, Node *nn)
  1072. {
  1073. Node *r;
  1074. int32_t v;
  1075. regialloc(t, n, nn);
  1076. if(n->op == OIND) {
  1077. r = n->left;
  1078. while(r->op == OADD)
  1079. r = r->right;
  1080. if(sconst(r)) {
  1081. v = r->vconst;
  1082. r->vconst = 0;
  1083. lcgen(n, t);
  1084. t->xoffset += v;
  1085. r->vconst = v;
  1086. regind(t, n);
  1087. return;
  1088. }
  1089. }
  1090. lcgen(n, t);
  1091. regind(t, n);
  1092. }
  1093. void
  1094. lcgen(Node *n, Node *nn)
  1095. {
  1096. Prog *p1;
  1097. Node nod;
  1098. if(debug['g']) {
  1099. prtree(nn, "lcgen lhs");
  1100. prtree(n, "lcgen");
  1101. }
  1102. if(n == Z || n->type == T)
  1103. return;
  1104. if(nn == Z) {
  1105. nn = &nod;
  1106. regalloc(&nod, n, Z);
  1107. }
  1108. switch(n->op) {
  1109. default:
  1110. if(n->addable < INDEXED) {
  1111. diag(n, "unknown op in lcgen: %O", n->op);
  1112. break;
  1113. }
  1114. gopcode(OADDR, n->type, n, nn);
  1115. break;
  1116. case OCOMMA:
  1117. cgen(n->left, n->left);
  1118. lcgen(n->right, nn);
  1119. break;
  1120. case OIND:
  1121. cgen(n->left, nn);
  1122. break;
  1123. case OCOND:
  1124. bcgen(n->left, 1);
  1125. p1 = p;
  1126. lcgen(n->right->left, nn);
  1127. gbranch(OGOTO);
  1128. patch(p1, pc);
  1129. p1 = p;
  1130. lcgen(n->right->right, nn);
  1131. patch(p1, pc);
  1132. break;
  1133. }
  1134. }
  1135. void
  1136. bcgen(Node *n, int true)
  1137. {
  1138. if(n->type == T)
  1139. gbranch(OGOTO);
  1140. else
  1141. boolgen(n, true, Z);
  1142. }
  1143. void
  1144. boolgen(Node *n, int true, Node *nn)
  1145. {
  1146. int o;
  1147. Prog *p1, *p2;
  1148. Node *l, *r, nod, nod1;
  1149. int32_t curs;
  1150. if(debug['g']) {
  1151. prtree(nn, "boolgen lhs");
  1152. prtree(n, "boolgen");
  1153. }
  1154. curs = cursafe;
  1155. l = n->left;
  1156. r = n->right;
  1157. switch(n->op) {
  1158. default:
  1159. if(typev[n->type->etype]) {
  1160. testv(n, true);
  1161. goto com;
  1162. }
  1163. o = ONE;
  1164. if(true)
  1165. o = OEQ;
  1166. if(typefd[n->type->etype]) {
  1167. if(n->addable < INDEXED) {
  1168. cgen(n, &fregnode0);
  1169. gins(AFLDZ, Z, Z);
  1170. fgopcode(o, &fregnode0, &fregnode1, 1, 1);
  1171. } else {
  1172. gins(AFLDZ, Z, Z);
  1173. fgopcode(o, n, &fregnode0, 0, 1);
  1174. }
  1175. goto com;
  1176. }
  1177. /* bad, 13 is address of external that becomes constant */
  1178. if(n->addable >= INDEXED && n->addable != 13) {
  1179. gopcode(o, n->type, n, nodconst(0));
  1180. goto com;
  1181. }
  1182. regalloc(&nod, n, nn);
  1183. cgen(n, &nod);
  1184. gopcode(o, n->type, &nod, nodconst(0));
  1185. regfree(&nod);
  1186. goto com;
  1187. case OCONST:
  1188. o = vconst(n);
  1189. if(!true)
  1190. o = !o;
  1191. gbranch(OGOTO);
  1192. if(o) {
  1193. p1 = p;
  1194. gbranch(OGOTO);
  1195. patch(p1, pc);
  1196. }
  1197. goto com;
  1198. case OCOMMA:
  1199. cgen(l, Z);
  1200. boolgen(r, true, nn);
  1201. break;
  1202. case ONOT:
  1203. boolgen(l, !true, nn);
  1204. break;
  1205. case OCOND:
  1206. bcgen(l, 1);
  1207. p1 = p;
  1208. bcgen(r->left, true);
  1209. p2 = p;
  1210. gbranch(OGOTO);
  1211. patch(p1, pc);
  1212. p1 = p;
  1213. bcgen(r->right, !true);
  1214. patch(p2, pc);
  1215. p2 = p;
  1216. gbranch(OGOTO);
  1217. patch(p1, pc);
  1218. patch(p2, pc);
  1219. goto com;
  1220. case OANDAND:
  1221. if(!true)
  1222. goto caseor;
  1223. caseand:
  1224. bcgen(l, true);
  1225. p1 = p;
  1226. bcgen(r, !true);
  1227. p2 = p;
  1228. patch(p1, pc);
  1229. gbranch(OGOTO);
  1230. patch(p2, pc);
  1231. goto com;
  1232. case OOROR:
  1233. if(!true)
  1234. goto caseand;
  1235. caseor:
  1236. bcgen(l, !true);
  1237. p1 = p;
  1238. bcgen(r, !true);
  1239. p2 = p;
  1240. gbranch(OGOTO);
  1241. patch(p1, pc);
  1242. patch(p2, pc);
  1243. goto com;
  1244. case OEQ:
  1245. case ONE:
  1246. case OLE:
  1247. case OLT:
  1248. case OGE:
  1249. case OGT:
  1250. case OHI:
  1251. case OHS:
  1252. case OLO:
  1253. case OLS:
  1254. o = n->op;
  1255. if(typev[l->type->etype]) {
  1256. if(!true)
  1257. n->op = comrel[relindex(o)];
  1258. cgen64(n, Z);
  1259. goto com;
  1260. }
  1261. if(true)
  1262. o = comrel[relindex(o)];
  1263. if(l->complex >= FNX && r->complex >= FNX) {
  1264. regret(&nod, r);
  1265. cgen(r, &nod);
  1266. regsalloc(&nod1, r);
  1267. gmove(&nod, &nod1);
  1268. regfree(&nod);
  1269. nod = *n;
  1270. nod.right = &nod1;
  1271. boolgen(&nod, true, nn);
  1272. break;
  1273. }
  1274. if(typefd[l->type->etype]) {
  1275. if(l->complex >= r->complex) {
  1276. cgen(l, &fregnode0);
  1277. if(r->addable < INDEXED) {
  1278. cgen(r, &fregnode0);
  1279. o = invrel[relindex(o)];
  1280. fgopcode(o, &fregnode0, &fregnode1, 1, 1);
  1281. } else
  1282. fgopcode(o, r, &fregnode0, 0, 1);
  1283. } else {
  1284. o = invrel[relindex(o)];
  1285. cgen(r, &fregnode0);
  1286. if(l->addable < INDEXED) {
  1287. cgen(l, &fregnode0);
  1288. o = invrel[relindex(o)];
  1289. fgopcode(o, &fregnode0, &fregnode1, 1, 1);
  1290. } else
  1291. fgopcode(o, l, &fregnode0, 0, 1);
  1292. }
  1293. goto com;
  1294. }
  1295. if(l->op == OCONST) {
  1296. o = invrel[relindex(o)];
  1297. /* bad, 13 is address of external that becomes constant */
  1298. if(r->addable < INDEXED || r->addable == 13) {
  1299. regalloc(&nod, r, nn);
  1300. cgen(r, &nod);
  1301. gopcode(o, l->type, &nod, l);
  1302. regfree(&nod);
  1303. } else
  1304. gopcode(o, l->type, r, l);
  1305. goto com;
  1306. }
  1307. if(l->complex >= r->complex) {
  1308. regalloc(&nod, l, nn);
  1309. cgen(l, &nod);
  1310. if(r->addable < INDEXED) {
  1311. regalloc(&nod1, r, Z);
  1312. cgen(r, &nod1);
  1313. gopcode(o, l->type, &nod, &nod1);
  1314. regfree(&nod1);
  1315. } else
  1316. gopcode(o, l->type, &nod, r);
  1317. regfree(&nod);
  1318. goto com;
  1319. }
  1320. regalloc(&nod, r, nn);
  1321. cgen(r, &nod);
  1322. if(l->addable < INDEXED || l->addable == 13) {
  1323. regalloc(&nod1, l, Z);
  1324. cgen(l, &nod1);
  1325. if(typechlp[l->type->etype])
  1326. gopcode(o, types[TINT], &nod1, &nod);
  1327. else
  1328. gopcode(o, l->type, &nod1, &nod);
  1329. regfree(&nod1);
  1330. } else
  1331. gopcode(o, l->type, l, &nod);
  1332. regfree(&nod);
  1333. com:
  1334. if(nn != Z) {
  1335. p1 = p;
  1336. gmove(nodconst(1L), nn);
  1337. gbranch(OGOTO);
  1338. p2 = p;
  1339. patch(p1, pc);
  1340. gmove(nodconst(0L), nn);
  1341. patch(p2, pc);
  1342. }
  1343. break;
  1344. }
  1345. cursafe = curs;
  1346. }
  1347. void
  1348. sugen(Node *n, Node *nn, int32_t w)
  1349. {
  1350. Prog *p1;
  1351. Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r;
  1352. Type *t;
  1353. int c, v, x;
  1354. if(n == Z || n->type == T)
  1355. return;
  1356. if(debug['g']) {
  1357. prtree(nn, "sugen lhs");
  1358. prtree(n, "sugen");
  1359. }
  1360. if(nn == nodrat)
  1361. if(w > nrathole)
  1362. nrathole = w;
  1363. switch(n->op) {
  1364. case OIND:
  1365. if(nn == Z) {
  1366. nullwarn(n->left, Z);
  1367. break;
  1368. }
  1369. default:
  1370. goto copy;
  1371. case OCONST:
  1372. if(n->type && typev[n->type->etype]) {
  1373. if(nn == Z) {
  1374. nullwarn(n->left, Z);
  1375. break;
  1376. }
  1377. if(nn->op == OREGPAIR) {
  1378. loadpair(n, nn);
  1379. break;
  1380. }
  1381. else if(!vaddr(nn, 0)) {
  1382. t = nn->type;
  1383. nn->type = types[TLONG];
  1384. reglcgen(&nod1, nn, Z);
  1385. nn->type = t;
  1386. gmove(lo64(n), &nod1);
  1387. nod1.xoffset += SZ_LONG;
  1388. gmove(hi64(n), &nod1);
  1389. regfree(&nod1);
  1390. }
  1391. else {
  1392. gins(AMOVL, lo64(n), nn);
  1393. nn->xoffset += SZ_LONG;
  1394. gins(AMOVL, hi64(n), nn);
  1395. nn->xoffset -= SZ_LONG;
  1396. break;
  1397. }
  1398. break;
  1399. }
  1400. goto copy;
  1401. case ODOT:
  1402. l = n->left;
  1403. sugen(l, nodrat, l->type->width);
  1404. if(nn == Z)
  1405. break;
  1406. warn(n, "non-interruptable temporary");
  1407. nod1 = *nodrat;
  1408. r = n->right;
  1409. if(!r || r->op != OCONST) {
  1410. diag(n, "DOT and no offset");
  1411. break;
  1412. }
  1413. nod1.xoffset += (int32_t)r->vconst;
  1414. nod1.type = n->type;
  1415. sugen(&nod1, nn, w);
  1416. break;
  1417. case OSTRUCT:
  1418. /*
  1419. * rewrite so lhs has no fn call
  1420. */
  1421. if(nn != Z && side(nn)) {
  1422. nod1 = *n;
  1423. nod1.type = typ(TIND, n->type);
  1424. regret(&nod2, &nod1);
  1425. lcgen(nn, &nod2);
  1426. regsalloc(&nod0, &nod1);
  1427. cgen(&nod2, &nod0);
  1428. regfree(&nod2);
  1429. nod1 = *n;
  1430. nod1.op = OIND;
  1431. nod1.left = &nod0;
  1432. nod1.right = Z;
  1433. nod1.complex = 1;
  1434. sugen(n, &nod1, w);
  1435. return;
  1436. }
  1437. r = n->left;
  1438. for(t = n->type->link; t != T; t = t->down) {
  1439. l = r;
  1440. if(r->op == OLIST) {
  1441. l = r->left;
  1442. r = r->right;
  1443. }
  1444. if(nn == Z) {
  1445. cgen(l, nn);
  1446. continue;
  1447. }
  1448. /*
  1449. * hand craft *(&nn + o) = l
  1450. */
  1451. nod0 = znode;
  1452. nod0.op = OAS;
  1453. nod0.type = t;
  1454. nod0.left = &nod1;
  1455. nod0.right = nil;
  1456. nod1 = znode;
  1457. nod1.op = OIND;
  1458. nod1.type = t;
  1459. nod1.left = &nod2;
  1460. nod2 = znode;
  1461. nod2.op = OADD;
  1462. nod2.type = typ(TIND, t);
  1463. nod2.left = &nod3;
  1464. nod2.right = &nod4;
  1465. nod3 = znode;
  1466. nod3.op = OADDR;
  1467. nod3.type = nod2.type;
  1468. nod3.left = nn;
  1469. nod4 = znode;
  1470. nod4.op = OCONST;
  1471. nod4.type = nod2.type;
  1472. nod4.vconst = t->offset;
  1473. ccom(&nod0);
  1474. acom(&nod0);
  1475. xcom(&nod0);
  1476. nod0.addable = 0;
  1477. nod0.right = l;
  1478. /* prtree(&nod0, "hand craft"); /* */
  1479. cgen(&nod0, Z);
  1480. }
  1481. break;
  1482. case OAS:
  1483. if(nn == Z) {
  1484. if(n->addable < INDEXED)
  1485. sugen(n->right, n->left, w);
  1486. break;
  1487. }
  1488. sugen(n->right, nodrat, w);
  1489. warn(n, "non-interruptable temporary");
  1490. sugen(nodrat, n->left, w);
  1491. sugen(nodrat, nn, w);
  1492. break;
  1493. case OFUNC:
  1494. if(nn == Z) {
  1495. sugen(n, nodrat, w);
  1496. break;
  1497. }
  1498. h = nn;
  1499. if(nn->op == OREGPAIR) {
  1500. regsalloc(&nod1, nn);
  1501. nn = &nod1;
  1502. }
  1503. if(nn->op != OIND) {
  1504. nn = new1(OADDR, nn, Z);
  1505. nn->type = types[TIND];
  1506. nn->addable = 0;
  1507. } else
  1508. nn = nn->left;
  1509. n = new(OFUNC, n->left, new(OLIST, nn, n->right));
  1510. n->type = types[TVOID];
  1511. n->left->type = types[TVOID];
  1512. cgen(n, Z);
  1513. if(h->op == OREGPAIR)
  1514. loadpair(nn->left, h);
  1515. break;
  1516. case OCOND:
  1517. bcgen(n->left, 1);
  1518. p1 = p;
  1519. sugen(n->right->left, nn, w);
  1520. gbranch(OGOTO);
  1521. patch(p1, pc);
  1522. p1 = p;
  1523. sugen(n->right->right, nn, w);
  1524. patch(p1, pc);
  1525. break;
  1526. case OCOMMA:
  1527. cgen(n->left, Z);
  1528. sugen(n->right, nn, w);
  1529. break;
  1530. }
  1531. return;
  1532. copy:
  1533. if(nn == Z) {
  1534. switch(n->op) {
  1535. case OASADD:
  1536. case OASSUB:
  1537. case OASAND:
  1538. case OASOR:
  1539. case OASXOR:
  1540. case OASMUL:
  1541. case OASLMUL:
  1542. case OASASHL:
  1543. case OASASHR:
  1544. case OASLSHR:
  1545. break;
  1546. case OPOSTINC:
  1547. case OPOSTDEC:
  1548. case OPREINC:
  1549. case OPREDEC:
  1550. break;
  1551. default:
  1552. return;
  1553. }
  1554. }
  1555. if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
  1556. t = nn->type;
  1557. nn->type = types[TLONG];
  1558. regialloc(&nod1, nn, Z);
  1559. lcgen(nn, &nod1);
  1560. regsalloc(&nod2, nn);
  1561. nn->type = t;
  1562. gins(AMOVL, &nod1, &nod2);
  1563. regfree(&nod1);
  1564. nod2.type = typ(TIND, t);
  1565. nod1 = nod2;
  1566. nod1.op = OIND;
  1567. nod1.left = &nod2;
  1568. nod1.right = Z;
  1569. nod1.complex = 1;
  1570. nod1.type = t;
  1571. sugen(n, &nod1, w);
  1572. return;
  1573. }
  1574. x = 0;
  1575. v = w == 8;
  1576. if(v) {
  1577. c = cursafe;
  1578. if(n->left != Z && n->left->complex >= FNX
  1579. && n->right != Z && n->right->complex >= FNX) {
  1580. // warn(n, "toughie");
  1581. regsalloc(&nod1, n->right);
  1582. cgen(n->right, &nod1);
  1583. nod2 = *n;
  1584. nod2.right = &nod1;
  1585. cgen(&nod2, nn);
  1586. cursafe = c;
  1587. return;
  1588. }
  1589. if(cgen64(n, nn)) {
  1590. cursafe = c;
  1591. return;
  1592. }
  1593. if(n->op == OCOM) {
  1594. n = n->left;
  1595. x = 1;
  1596. }
  1597. }
  1598. /* botch, need to save in .safe */
  1599. c = 0;
  1600. if(n->complex > nn->complex) {
  1601. t = n->type;
  1602. n->type = types[TLONG];
  1603. if(v) {
  1604. regalloc(&nod0, n, Z);
  1605. if(!vaddr(n, 0)) {
  1606. reglcgen(&nod1, n, Z);
  1607. n->type = t;
  1608. n = &nod1;
  1609. }
  1610. else
  1611. n->type = t;
  1612. }
  1613. else {
  1614. nodreg(&nod1, n, D_SI);
  1615. if(reg[D_SI]) {
  1616. gins(APUSHL, &nod1, Z);
  1617. c |= 1;
  1618. reg[D_SI]++;
  1619. }
  1620. lcgen(n, &nod1);
  1621. n->type = t;
  1622. }
  1623. t = nn->type;
  1624. nn->type = types[TLONG];
  1625. if(v) {
  1626. if(!vaddr(nn, 0)) {
  1627. reglcgen(&nod2, nn, Z);
  1628. nn->type = t;
  1629. nn = &nod2;
  1630. }
  1631. else
  1632. nn->type = t;
  1633. }
  1634. else {
  1635. nodreg(&nod2, nn, D_DI);
  1636. if(reg[D_DI]) {
  1637. gins(APUSHL, &nod2, Z);
  1638. c |= 2;
  1639. reg[D_DI]++;
  1640. }
  1641. lcgen(nn, &nod2);
  1642. nn->type = t;
  1643. }
  1644. } else {
  1645. t = nn->type;
  1646. nn->type = types[TLONG];
  1647. if(v) {
  1648. regalloc(&nod0, nn, Z);
  1649. if(!vaddr(nn, 0)) {
  1650. reglcgen(&nod2, nn, Z);
  1651. nn->type = t;
  1652. nn = &nod2;
  1653. }
  1654. else
  1655. nn->type = t;
  1656. }
  1657. else {
  1658. nodreg(&nod2, nn, D_DI);
  1659. if(reg[D_DI]) {
  1660. gins(APUSHL, &nod2, Z);
  1661. c |= 2;
  1662. reg[D_DI]++;
  1663. }
  1664. lcgen(nn, &nod2);
  1665. nn->type = t;
  1666. }
  1667. t = n->type;
  1668. n->type = types[TLONG];
  1669. if(v) {
  1670. if(!vaddr(n, 0)) {
  1671. reglcgen(&nod1, n, Z);
  1672. n->type = t;
  1673. n = &nod1;
  1674. }
  1675. else
  1676. n->type = t;
  1677. }
  1678. else {
  1679. nodreg(&nod1, n, D_SI);
  1680. if(reg[D_SI]) {
  1681. gins(APUSHL, &nod1, Z);
  1682. c |= 1;
  1683. reg[D_SI]++;
  1684. }
  1685. lcgen(n, &nod1);
  1686. n->type = t;
  1687. }
  1688. }
  1689. if(v) {
  1690. gins(AMOVL, n, &nod0);
  1691. if(x)
  1692. gins(ANOTL, Z, &nod0);
  1693. gins(AMOVL, &nod0, nn);
  1694. n->xoffset += SZ_LONG;
  1695. nn->xoffset += SZ_LONG;
  1696. gins(AMOVL, n, &nod0);
  1697. if(x)
  1698. gins(ANOTL, Z, &nod0);
  1699. gins(AMOVL, &nod0, nn);
  1700. n->xoffset -= SZ_LONG;
  1701. nn->xoffset -= SZ_LONG;
  1702. if(nn == &nod2)
  1703. regfree(&nod2);
  1704. if(n == &nod1)
  1705. regfree(&nod1);
  1706. regfree(&nod0);
  1707. return;
  1708. }
  1709. nodreg(&nod3, n, D_CX);
  1710. if(reg[D_CX]) {
  1711. gins(APUSHL, &nod3, Z);
  1712. c |= 4;
  1713. reg[D_CX]++;
  1714. }
  1715. gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
  1716. gins(ACLD, Z, Z);
  1717. gins(AREP, Z, Z);
  1718. gins(AMOVSL, Z, Z);
  1719. if(w & (SZ_LONG-1)) {
  1720. /* odd length of packed structure */
  1721. gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);
  1722. gins(AREP, Z, Z);
  1723. gins(AMOVSB, Z, Z);
  1724. }
  1725. if(c & 4) {
  1726. gins(APOPL, Z, &nod3);
  1727. reg[D_CX]--;
  1728. }
  1729. if(c & 2) {
  1730. gins(APOPL, Z, &nod2);
  1731. reg[nod2.reg]--;
  1732. }
  1733. if(c & 1) {
  1734. gins(APOPL, Z, &nod1);
  1735. reg[nod1.reg]--;
  1736. }
  1737. }