cgen.c 34 KB

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