cgen.c 34 KB

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