cgen.c 31 KB

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