cgen.c 32 KB

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