cgen.c 20 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184
  1. #include "gc.h"
  2. void
  3. cgen(Node *n, Node *nn)
  4. {
  5. Node *l, *r;
  6. Prog *p1;
  7. Node nod, nod1, nod2, nod3, nod4;
  8. int o;
  9. long v, curs;
  10. if(debug['g']) {
  11. prtree(nn, "cgen lhs");
  12. prtree(n, "cgen");
  13. }
  14. if(n == Z || n->type == T)
  15. return;
  16. if(typesuv[n->type->etype]) {
  17. sugen(n, nn, n->type->width);
  18. return;
  19. }
  20. l = n->left;
  21. r = n->right;
  22. o = n->op;
  23. if(n->addable >= INDEXED) {
  24. if(nn == Z) {
  25. switch(o) {
  26. default:
  27. nullwarn(Z, Z);
  28. break;
  29. case OINDEX:
  30. nullwarn(l, r);
  31. break;
  32. }
  33. return;
  34. }
  35. gmove(n, nn);
  36. return;
  37. }
  38. curs = cursafe;
  39. if(n->complex >= FNX)
  40. if(l->complex >= FNX)
  41. if(r != Z && r->complex >= FNX)
  42. switch(o) {
  43. default:
  44. regret(&nod, r);
  45. cgen(r, &nod);
  46. regsalloc(&nod1, r);
  47. gopcode(OAS, &nod, Z, &nod1);
  48. regfree(&nod);
  49. nod = *n;
  50. nod.right = &nod1;
  51. cgen(&nod, nn);
  52. return;
  53. case OFUNC:
  54. case OCOMMA:
  55. case OANDAND:
  56. case OOROR:
  57. case OCOND:
  58. case ODOT:
  59. break;
  60. }
  61. switch(o) {
  62. default:
  63. diag(n, "unknown op in cgen: %O", o);
  64. break;
  65. case OAS:
  66. if(l->op == OBIT)
  67. goto bitas;
  68. if(l->addable >= INDEXED && l->complex < FNX) {
  69. if(nn != Z || r->addable < INDEXED) {
  70. if(r->complex >= FNX && nn == Z)
  71. regret(&nod, r);
  72. else
  73. regalloc(&nod, r, nn);
  74. cgen(r, &nod);
  75. gmove(&nod, l);
  76. if(nn != Z)
  77. gmove(&nod, nn);
  78. regfree(&nod);
  79. } else
  80. gmove(r, l);
  81. break;
  82. }
  83. if(l->complex >= r->complex) {
  84. reglcgen(&nod1, l, Z);
  85. if(r->addable >= INDEXED) {
  86. gmove(r, &nod1);
  87. if(nn != Z)
  88. gmove(r, nn);
  89. regfree(&nod1);
  90. break;
  91. }
  92. regalloc(&nod, r, nn);
  93. cgen(r, &nod);
  94. } else {
  95. regalloc(&nod, r, nn);
  96. cgen(r, &nod);
  97. reglcgen(&nod1, l, Z);
  98. }
  99. gmove(&nod, &nod1);
  100. regfree(&nod);
  101. regfree(&nod1);
  102. break;
  103. bitas:
  104. n = l->left;
  105. regalloc(&nod, r, nn);
  106. if(l->complex >= r->complex) {
  107. reglcgen(&nod1, n, Z);
  108. cgen(r, &nod);
  109. } else {
  110. cgen(r, &nod);
  111. reglcgen(&nod1, n, Z);
  112. }
  113. regalloc(&nod2, n, Z);
  114. gopcode(OAS, &nod1, Z, &nod2);
  115. bitstore(l, &nod, &nod1, &nod2, nn);
  116. break;
  117. case OBIT:
  118. if(nn == Z) {
  119. nullwarn(l, Z);
  120. break;
  121. }
  122. bitload(n, &nod, Z, Z, nn);
  123. gopcode(OAS, &nod, Z, nn);
  124. regfree(&nod);
  125. break;
  126. case OADD:
  127. case OSUB:
  128. case OAND:
  129. case OOR:
  130. case OXOR:
  131. case OLSHR:
  132. case OASHL:
  133. case OASHR:
  134. /*
  135. * immediate operands
  136. */
  137. if(nn != Z)
  138. if(r->op == OCONST)
  139. if(!typefd[n->type->etype]) {
  140. cgen(l, nn);
  141. if(r->vconst == 0)
  142. if(o != OAND)
  143. break;
  144. if(nn != Z)
  145. gopcode(o, r, Z, nn);
  146. break;
  147. }
  148. case OLMUL:
  149. case OLDIV:
  150. case OLMOD:
  151. case OMUL:
  152. case ODIV:
  153. case OMOD:
  154. if(nn == Z) {
  155. nullwarn(l, r);
  156. break;
  157. }
  158. if(o == OMUL || o == OLMUL) {
  159. if(mulcon(n, nn))
  160. break;
  161. }
  162. if(l->complex >= r->complex) {
  163. regalloc(&nod, l, nn);
  164. cgen(l, &nod);
  165. regalloc(&nod1, r, Z);
  166. cgen(r, &nod1);
  167. gopcode(o, &nod1, Z, &nod);
  168. } else {
  169. regalloc(&nod, r, nn);
  170. cgen(r, &nod);
  171. regalloc(&nod1, l, Z);
  172. cgen(l, &nod1);
  173. gopcode(o, &nod, &nod1, &nod);
  174. }
  175. gopcode(OAS, &nod, Z, nn);
  176. regfree(&nod);
  177. regfree(&nod1);
  178. break;
  179. case OASLSHR:
  180. case OASASHL:
  181. case OASASHR:
  182. case OASAND:
  183. case OASADD:
  184. case OASSUB:
  185. case OASXOR:
  186. case OASOR:
  187. if(l->op == OBIT)
  188. goto asbitop;
  189. if(r->op == OCONST)
  190. if(!typefd[r->type->etype])
  191. if(!typefd[n->type->etype]) {
  192. if(l->addable < INDEXED)
  193. reglcgen(&nod2, l, Z);
  194. else
  195. nod2 = *l;
  196. regalloc(&nod, r, nn);
  197. gopcode(OAS, &nod2, Z, &nod);
  198. gopcode(o, r, Z, &nod);
  199. gopcode(OAS, &nod, Z, &nod2);
  200. regfree(&nod);
  201. if(l->addable < INDEXED)
  202. regfree(&nod2);
  203. break;
  204. }
  205. case OASLMUL:
  206. case OASLDIV:
  207. case OASLMOD:
  208. case OASMUL:
  209. case OASDIV:
  210. case OASMOD:
  211. if(l->op == OBIT)
  212. goto asbitop;
  213. if(l->complex >= r->complex) {
  214. if(l->addable < INDEXED)
  215. reglcgen(&nod2, l, Z);
  216. else
  217. nod2 = *l;
  218. regalloc(&nod1, r, Z);
  219. cgen(r, &nod1);
  220. } else {
  221. regalloc(&nod1, r, Z);
  222. cgen(r, &nod1);
  223. if(l->addable < INDEXED)
  224. reglcgen(&nod2, l, Z);
  225. else
  226. nod2 = *l;
  227. }
  228. regalloc(&nod, n, nn);
  229. gmove(&nod2, &nod);
  230. gopcode(o, &nod1, Z, &nod);
  231. gmove(&nod, &nod2);
  232. if(nn != Z)
  233. gopcode(OAS, &nod, Z, nn);
  234. regfree(&nod);
  235. regfree(&nod1);
  236. if(l->addable < INDEXED)
  237. regfree(&nod2);
  238. break;
  239. asbitop:
  240. regalloc(&nod4, n, nn);
  241. if(l->complex >= r->complex) {
  242. bitload(l, &nod, &nod1, &nod2, &nod4);
  243. regalloc(&nod3, r, Z);
  244. cgen(r, &nod3);
  245. } else {
  246. regalloc(&nod3, r, Z);
  247. cgen(r, &nod3);
  248. bitload(l, &nod, &nod1, &nod2, &nod4);
  249. }
  250. gmove(&nod, &nod4);
  251. gopcode(o, &nod3, Z, &nod4);
  252. regfree(&nod3);
  253. gmove(&nod4, &nod);
  254. regfree(&nod4);
  255. bitstore(l, &nod, &nod1, &nod2, nn);
  256. break;
  257. case OADDR:
  258. if(nn == Z) {
  259. nullwarn(l, Z);
  260. break;
  261. }
  262. lcgen(l, nn);
  263. break;
  264. case OFUNC:
  265. if(l->complex >= FNX) {
  266. if(l->op != OIND)
  267. diag(n, "bad function call");
  268. regret(&nod, l->left);
  269. cgen(l->left, &nod);
  270. regsalloc(&nod1, l->left);
  271. gopcode(OAS, &nod, Z, &nod1);
  272. regfree(&nod);
  273. nod = *n;
  274. nod.left = &nod2;
  275. nod2 = *l;
  276. nod2.left = &nod1;
  277. nod2.complex = 1;
  278. cgen(&nod, nn);
  279. return;
  280. }
  281. o = reg[REGARG];
  282. gargs(r, &nod, &nod1);
  283. if(l->addable < INDEXED) {
  284. reglcgen(&nod, l, Z);
  285. gopcode(OFUNC, Z, Z, &nod);
  286. regfree(&nod);
  287. } else
  288. gopcode(OFUNC, Z, Z, l);
  289. if(REGARG)
  290. if(o != reg[REGARG])
  291. reg[REGARG]--;
  292. if(nn != Z) {
  293. regret(&nod, n);
  294. gopcode(OAS, &nod, Z, nn);
  295. regfree(&nod);
  296. }
  297. break;
  298. case OIND:
  299. if(nn == Z) {
  300. nullwarn(l, Z);
  301. break;
  302. }
  303. regialloc(&nod, n, nn);
  304. r = l;
  305. while(r->op == OADD)
  306. r = r->right;
  307. if(sconst(r)) {
  308. v = r->vconst;
  309. r->vconst = 0;
  310. cgen(l, &nod);
  311. nod.xoffset += v;
  312. r->vconst = v;
  313. } else
  314. cgen(l, &nod);
  315. regind(&nod, n);
  316. gopcode(OAS, &nod, Z, nn);
  317. regfree(&nod);
  318. break;
  319. case OEQ:
  320. case ONE:
  321. case OLE:
  322. case OLT:
  323. case OGE:
  324. case OGT:
  325. case OLO:
  326. case OLS:
  327. case OHI:
  328. case OHS:
  329. if(nn == Z) {
  330. nullwarn(l, r);
  331. break;
  332. }
  333. boolgen(n, 1, nn);
  334. break;
  335. case OANDAND:
  336. case OOROR:
  337. boolgen(n, 1, nn);
  338. if(nn == Z)
  339. patch(p, pc);
  340. break;
  341. case ONOT:
  342. if(nn == Z) {
  343. nullwarn(l, Z);
  344. break;
  345. }
  346. boolgen(n, 1, nn);
  347. break;
  348. case OCOMMA:
  349. cgen(l, Z);
  350. cgen(r, nn);
  351. break;
  352. case OCAST:
  353. if(nn == Z) {
  354. nullwarn(l, Z);
  355. break;
  356. }
  357. /*
  358. * convert from types l->n->nn
  359. */
  360. if(nocast(l->type, n->type)) {
  361. if(nocast(n->type, nn->type)) {
  362. cgen(l, nn);
  363. break;
  364. }
  365. }
  366. regalloc(&nod, l, nn);
  367. cgen(l, &nod);
  368. regalloc(&nod1, n, &nod);
  369. gopcode(OAS, &nod, Z, &nod1);
  370. gopcode(OAS, &nod1, Z, nn);
  371. regfree(&nod1);
  372. regfree(&nod);
  373. break;
  374. case ODOT:
  375. sugen(l, nodrat, l->type->width);
  376. if(nn != Z) {
  377. warn(n, "non-interruptable temporary");
  378. nod = *nodrat;
  379. if(!r || r->op != OCONST) {
  380. diag(n, "DOT and no offset");
  381. break;
  382. }
  383. nod.xoffset += (long)r->vconst;
  384. nod.type = n->type;
  385. cgen(&nod, nn);
  386. }
  387. break;
  388. case OCOND:
  389. bcgen(l, 1);
  390. p1 = p;
  391. cgen(r->left, nn);
  392. gbranch(OGOTO);
  393. patch(p1, pc);
  394. p1 = p;
  395. cgen(r->right, nn);
  396. patch(p1, pc);
  397. break;
  398. case OPOSTINC:
  399. case OPOSTDEC:
  400. v = 1;
  401. if(l->type->etype == TIND)
  402. v = l->type->link->width;
  403. if(o == OPOSTDEC)
  404. v = -v;
  405. if(l->op == OBIT)
  406. goto bitinc;
  407. if(nn == Z)
  408. goto pre;
  409. if(l->addable < INDEXED)
  410. reglcgen(&nod2, l, Z);
  411. else
  412. nod2 = *l;
  413. regalloc(&nod, l, nn);
  414. gopcode(OAS, &nod2, Z, &nod);
  415. regalloc(&nod1, l, Z);
  416. if(typefd[l->type->etype]) {
  417. regalloc(&nod3, l, Z);
  418. if(v < 0) {
  419. gopcode(OAS, nodfconst(-v), Z, &nod3);
  420. gopcode(OSUB, &nod3, &nod, &nod1);
  421. } else {
  422. gopcode(OAS, nodfconst(v), Z, &nod3);
  423. gopcode(OADD, &nod3, &nod, &nod1);
  424. }
  425. regfree(&nod3);
  426. } else
  427. gopcode(OADD, nodconst(v), &nod, &nod1);
  428. gopcode(OAS, &nod1, Z, &nod2);
  429. regfree(&nod);
  430. regfree(&nod1);
  431. if(l->addable < INDEXED)
  432. regfree(&nod2);
  433. break;
  434. case OPREINC:
  435. case OPREDEC:
  436. v = 1;
  437. if(l->type->etype == TIND)
  438. v = l->type->link->width;
  439. if(o == OPREDEC)
  440. v = -v;
  441. if(l->op == OBIT)
  442. goto bitinc;
  443. pre:
  444. if(l->addable < INDEXED)
  445. reglcgen(&nod2, l, Z);
  446. else
  447. nod2 = *l;
  448. regalloc(&nod, l, nn);
  449. gopcode(OAS, &nod2, Z, &nod);
  450. if(typefd[l->type->etype]) {
  451. regalloc(&nod3, l, Z);
  452. if(v < 0) {
  453. gopcode(OAS, nodfconst(-v), Z, &nod3);
  454. gopcode(OSUB, &nod3, Z, &nod);
  455. } else {
  456. gopcode(OAS, nodfconst(v), Z, &nod3);
  457. gopcode(OADD, &nod3, Z, &nod);
  458. }
  459. regfree(&nod3);
  460. } else
  461. gopcode(OADD, nodconst(v), Z, &nod);
  462. gopcode(OAS, &nod, Z, &nod2);
  463. regfree(&nod);
  464. if(l->addable < INDEXED)
  465. regfree(&nod2);
  466. break;
  467. bitinc:
  468. if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
  469. bitload(l, &nod, &nod1, &nod2, Z);
  470. gopcode(OAS, &nod, Z, nn);
  471. gopcode(OADD, nodconst(v), Z, &nod);
  472. bitstore(l, &nod, &nod1, &nod2, Z);
  473. break;
  474. }
  475. bitload(l, &nod, &nod1, &nod2, nn);
  476. gopcode(OADD, nodconst(v), Z, &nod);
  477. bitstore(l, &nod, &nod1, &nod2, nn);
  478. break;
  479. }
  480. cursafe = curs;
  481. }
  482. void
  483. reglcgen(Node *t, Node *n, Node *nn)
  484. {
  485. Node *r;
  486. long v;
  487. regialloc(t, n, nn);
  488. if(n->op == OIND) {
  489. r = n->left;
  490. while(r->op == OADD)
  491. r = r->right;
  492. if(sconst(r)) {
  493. v = r->vconst;
  494. r->vconst = 0;
  495. lcgen(n, t);
  496. t->xoffset += v;
  497. r->vconst = v;
  498. regind(t, n);
  499. return;
  500. }
  501. }
  502. lcgen(n, t);
  503. regind(t, n);
  504. }
  505. void
  506. lcgen(Node *n, Node *nn)
  507. {
  508. Prog *p1;
  509. Node nod;
  510. if(debug['g']) {
  511. prtree(nn, "lcgen lhs");
  512. prtree(n, "lcgen");
  513. }
  514. if(n == Z || n->type == T)
  515. return;
  516. if(nn == Z) {
  517. nn = &nod;
  518. regalloc(&nod, n, Z);
  519. }
  520. switch(n->op) {
  521. default:
  522. if(n->addable < INDEXED) {
  523. diag(n, "unknown op in lcgen: %O", n->op);
  524. break;
  525. }
  526. nod = *n;
  527. nod.op = OADDR;
  528. nod.left = n;
  529. nod.right = Z;
  530. nod.type = types[TIND];
  531. gopcode(OAS, &nod, Z, nn);
  532. break;
  533. case OCOMMA:
  534. cgen(n->left, n->left);
  535. lcgen(n->right, nn);
  536. break;
  537. case OIND:
  538. cgen(n->left, nn);
  539. break;
  540. case OCOND:
  541. bcgen(n->left, 1);
  542. p1 = p;
  543. lcgen(n->right->left, nn);
  544. gbranch(OGOTO);
  545. patch(p1, pc);
  546. p1 = p;
  547. lcgen(n->right->right, nn);
  548. patch(p1, pc);
  549. break;
  550. }
  551. }
  552. void
  553. bcgen(Node *n, int true)
  554. {
  555. if(n->type == T)
  556. gbranch(OGOTO);
  557. else
  558. boolgen(n, true, Z);
  559. }
  560. void
  561. boolgen(Node *n, int true, Node *nn)
  562. {
  563. int o;
  564. Prog *p1, *p2;
  565. Node *l, *r, nod, nod1;
  566. long curs;
  567. if(debug['g']) {
  568. prtree(nn, "boolgen lhs");
  569. prtree(n, "boolgen");
  570. }
  571. curs = cursafe;
  572. l = n->left;
  573. r = n->right;
  574. switch(n->op) {
  575. default:
  576. regalloc(&nod, n, nn);
  577. cgen(n, &nod);
  578. if(nn == Z || typefd[n->type->etype]) {
  579. o = ONE;
  580. if(true)
  581. o = comrel[relindex(o)];
  582. if(typefd[n->type->etype]) {
  583. nodreg(&nod1, n, NREG+FREGZERO);
  584. gopcode(o, &nod, &nod1, Z);
  585. } else
  586. gopcode(o, &nod, Z, Z);
  587. regfree(&nod);
  588. goto com;
  589. }
  590. if(true)
  591. gopcode(OCOND, &nod, nodconst(0), &nod);
  592. else
  593. gopcode(OCOND, nodconst(1), &nod, &nod);
  594. gopcode(OAS, &nod, Z, nn);
  595. regfree(&nod);
  596. break;
  597. case OCONST:
  598. o = vconst(n);
  599. if(!true)
  600. o = !o;
  601. gbranch(OGOTO);
  602. if(o) {
  603. p1 = p;
  604. gbranch(OGOTO);
  605. patch(p1, pc);
  606. }
  607. goto com;
  608. case OCOMMA:
  609. cgen(l, Z);
  610. boolgen(r, true, nn);
  611. break;
  612. case ONOT:
  613. boolgen(l, !true, nn);
  614. break;
  615. case OCOND:
  616. bcgen(l, 1);
  617. p1 = p;
  618. bcgen(r->left, true);
  619. p2 = p;
  620. gbranch(OGOTO);
  621. patch(p1, pc);
  622. p1 = p;
  623. bcgen(r->right, !true);
  624. patch(p2, pc);
  625. p2 = p;
  626. gbranch(OGOTO);
  627. patch(p1, pc);
  628. patch(p2, pc);
  629. goto com;
  630. case OANDAND:
  631. if(!true)
  632. goto caseor;
  633. caseand:
  634. bcgen(l, true);
  635. p1 = p;
  636. bcgen(r, !true);
  637. p2 = p;
  638. patch(p1, pc);
  639. gbranch(OGOTO);
  640. patch(p2, pc);
  641. goto com;
  642. case OOROR:
  643. if(!true)
  644. goto caseand;
  645. caseor:
  646. bcgen(l, !true);
  647. p1 = p;
  648. bcgen(r, !true);
  649. p2 = p;
  650. gbranch(OGOTO);
  651. patch(p1, pc);
  652. patch(p2, pc);
  653. goto com;
  654. case OEQ:
  655. case ONE:
  656. case OLE:
  657. case OLT:
  658. case OGE:
  659. case OGT:
  660. case OHI:
  661. case OHS:
  662. case OLO:
  663. case OLS:
  664. o = n->op;
  665. if(true)
  666. o = comrel[relindex(o)];
  667. if(l->complex >= FNX && r->complex >= FNX) {
  668. regret(&nod, r);
  669. cgen(r, &nod);
  670. regsalloc(&nod1, r);
  671. gopcode(OAS, &nod, Z, &nod1);
  672. regfree(&nod);
  673. nod = *n;
  674. nod.right = &nod1;
  675. boolgen(&nod, true, nn);
  676. break;
  677. }
  678. if(nn != Z && !typefd[l->type->etype]) {
  679. if(l->complex >= r->complex) {
  680. regalloc(&nod1, l, nn);
  681. cgen(l, &nod1);
  682. regalloc(&nod, r, Z);
  683. cgen(r, &nod);
  684. } else {
  685. regalloc(&nod, r, nn);
  686. cgen(r, &nod);
  687. regalloc(&nod1, l, Z);
  688. cgen(l, &nod1);
  689. }
  690. switch(o) {
  691. case OEQ:
  692. gopcode(OSUB, &nod1, &nod, &nod);
  693. gopcode(OCOND, &nod, nodconst(0), &nod);
  694. break;
  695. case ONE:
  696. gopcode(OSUB, &nod1, &nod, &nod);
  697. gopcode(OCOND, nodconst(1), &nod, &nod);
  698. break;
  699. case OLE:
  700. gopcode(OCOMMA, &nod1, &nod, &nod);
  701. break;
  702. case OGT:
  703. gopcode(OCOMMA, &nod1, &nod, &nod);
  704. gopcode(OXOR, nodconst(1), &nod, &nod);
  705. break;
  706. case OLT:
  707. gopcode(OCOMMA, &nod, &nod1, &nod);
  708. gopcode(OXOR, nodconst(1), &nod, &nod);
  709. break;
  710. case OGE:
  711. gopcode(OCOMMA, &nod, &nod1, &nod);
  712. break;
  713. case OLS:
  714. gopcode(OCOND, &nod1, &nod, &nod);
  715. break;
  716. case OHI:
  717. gopcode(OCOND, &nod1, &nod, &nod);
  718. gopcode(OXOR, nodconst(1), &nod, &nod);
  719. break;
  720. case OLO:
  721. gopcode(OCOND, &nod, &nod1, &nod);
  722. gopcode(OXOR, nodconst(1), &nod, &nod);
  723. break;
  724. case OHS:
  725. gopcode(OCOND, &nod, &nod1, &nod);
  726. break;
  727. }
  728. gopcode(OAS, &nod, Z, nn);
  729. regfree(&nod);
  730. regfree(&nod1);
  731. break;
  732. }
  733. if(sconst(l)) {
  734. switch(o) {
  735. default:
  736. if(l->vconst != 0)
  737. break;
  738. case OGT:
  739. case OHI:
  740. case OLE:
  741. case OLS:
  742. regalloc(&nod, r, nn);
  743. cgen(r, &nod);
  744. gopcode(o, l, &nod, Z);
  745. regfree(&nod);
  746. goto com;
  747. }
  748. }
  749. if(sconst(r)) {
  750. switch(o) {
  751. default:
  752. if(r->vconst != 0)
  753. break;
  754. case OGE:
  755. case OHS:
  756. case OLT:
  757. case OLO:
  758. regalloc(&nod, l, nn);
  759. cgen(l, &nod);
  760. gopcode(o, &nod, r, Z);
  761. regfree(&nod);
  762. goto com;
  763. }
  764. }
  765. if(l->complex >= r->complex) {
  766. regalloc(&nod1, l, nn);
  767. cgen(l, &nod1);
  768. regalloc(&nod, r, Z);
  769. cgen(r, &nod);
  770. } else {
  771. regalloc(&nod, r, nn);
  772. cgen(r, &nod);
  773. regalloc(&nod1, l, Z);
  774. cgen(l, &nod1);
  775. }
  776. gopcode(o, &nod1, &nod, Z);
  777. regfree(&nod);
  778. regfree(&nod1);
  779. com:
  780. if(nn != Z) {
  781. p1 = p;
  782. gopcode(OAS, nodconst(1), Z, nn);
  783. gbranch(OGOTO);
  784. p2 = p;
  785. patch(p1, pc);
  786. gopcode(OAS, nodconst(0), Z, nn);
  787. patch(p2, pc);
  788. }
  789. break;
  790. }
  791. cursafe = curs;
  792. }
  793. void
  794. sugen(Node *n, Node *nn, long w)
  795. {
  796. Prog *p1;
  797. Node nod0, nod1, nod2, nod3, nod4, *l, *r;
  798. Type *t;
  799. long pc1;
  800. int i, m, c;
  801. if(n == Z || n->type == T)
  802. return;
  803. if(debug['g']) {
  804. prtree(nn, "sugen lhs");
  805. prtree(n, "sugen");
  806. }
  807. if(nn == nodrat)
  808. if(w > nrathole)
  809. nrathole = w;
  810. switch(n->op) {
  811. case OIND:
  812. if(nn == Z) {
  813. nullwarn(n->left, Z);
  814. break;
  815. }
  816. default:
  817. goto copy;
  818. case OCONST:
  819. if(n->type && typev[n->type->etype]) {
  820. if(nn == Z) {
  821. nullwarn(n->left, Z);
  822. break;
  823. }
  824. t = nn->type;
  825. nn->type = types[TLONG];
  826. reglcgen(&nod1, nn, Z);
  827. nn->type = t;
  828. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  829. gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
  830. else
  831. gopcode(OAS, nod32const(n->vconst), Z, &nod1);
  832. nod1.xoffset += SZ_LONG;
  833. if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
  834. gopcode(OAS, nod32const(n->vconst), Z, &nod1);
  835. else
  836. gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
  837. regfree(&nod1);
  838. break;
  839. }
  840. goto copy;
  841. case ODOT:
  842. l = n->left;
  843. sugen(l, nodrat, l->type->width);
  844. if(nn != Z) {
  845. warn(n, "non-interruptable temporary");
  846. nod1 = *nodrat;
  847. r = n->right;
  848. if(!r || r->op != OCONST) {
  849. diag(n, "DOT and no offset");
  850. break;
  851. }
  852. nod1.xoffset += (long)r->vconst;
  853. nod1.type = n->type;
  854. sugen(&nod1, nn, w);
  855. }
  856. break;
  857. case OSTRUCT:
  858. /*
  859. * rewrite so lhs has no fn call
  860. */
  861. if(nn != Z && nn->complex >= FNX) {
  862. nod1 = *n;
  863. nod1.type = typ(TIND, n->type);
  864. regret(&nod2, &nod1);
  865. lcgen(nn, &nod2);
  866. regsalloc(&nod0, &nod1);
  867. gopcode(OAS, &nod2, Z, &nod0);
  868. regfree(&nod2);
  869. nod1 = *n;
  870. nod1.op = OIND;
  871. nod1.left = &nod0;
  872. nod1.right = Z;
  873. nod1.complex = 1;
  874. sugen(n, &nod1, w);
  875. return;
  876. }
  877. r = n->left;
  878. for(t = n->type->link; t != T; t = t->down) {
  879. l = r;
  880. if(r->op == OLIST) {
  881. l = r->left;
  882. r = r->right;
  883. }
  884. if(nn == Z) {
  885. cgen(l, nn);
  886. continue;
  887. }
  888. /*
  889. * hand craft *(&nn + o) = l
  890. */
  891. nod0 = znode;
  892. nod0.op = OAS;
  893. nod0.type = t;
  894. nod0.left = &nod1;
  895. nod0.right = l;
  896. nod1 = znode;
  897. nod1.op = OIND;
  898. nod1.type = t;
  899. nod1.left = &nod2;
  900. nod2 = znode;
  901. nod2.op = OADD;
  902. nod2.type = typ(TIND, t);
  903. nod2.left = &nod3;
  904. nod2.right = &nod4;
  905. nod3 = znode;
  906. nod3.op = OADDR;
  907. nod3.type = nod2.type;
  908. nod3.left = nn;
  909. nod4 = znode;
  910. nod4.op = OCONST;
  911. nod4.type = nod2.type;
  912. nod4.vconst = t->offset;
  913. ccom(&nod0);
  914. acom(&nod0);
  915. xcom(&nod0);
  916. nod0.addable = 0;
  917. cgen(&nod0, Z);
  918. }
  919. break;
  920. case OAS:
  921. if(nn == Z) {
  922. if(n->addable < INDEXED)
  923. sugen(n->right, n->left, w);
  924. break;
  925. }
  926. sugen(n->right, nodrat, w);
  927. warn(n, "non-interruptable temporary");
  928. sugen(nodrat, n->left, w);
  929. sugen(nodrat, nn, w);
  930. break;
  931. case OFUNC:
  932. if(nn == Z) {
  933. sugen(n, nodrat, w);
  934. break;
  935. }
  936. if(nn->op != OIND) {
  937. nn = new1(OADDR, nn, Z);
  938. nn->type = types[TIND];
  939. nn->addable = 0;
  940. } else
  941. nn = nn->left;
  942. n = new(OFUNC, n->left, new(OLIST, nn, n->right));
  943. n->type = types[TVOID];
  944. n->left->type = types[TVOID];
  945. cgen(n, Z);
  946. break;
  947. case OCOND:
  948. bcgen(n->left, 1);
  949. p1 = p;
  950. sugen(n->right->left, nn, w);
  951. gbranch(OGOTO);
  952. patch(p1, pc);
  953. p1 = p;
  954. sugen(n->right->right, nn, w);
  955. patch(p1, pc);
  956. break;
  957. case OCOMMA:
  958. cgen(n->left, Z);
  959. sugen(n->right, nn, w);
  960. break;
  961. }
  962. return;
  963. copy:
  964. if(nn == Z)
  965. return;
  966. if(n->complex >= FNX && nn->complex >= FNX) {
  967. t = nn->type;
  968. nn->type = types[TLONG];
  969. regialloc(&nod1, nn, Z);
  970. lcgen(nn, &nod1);
  971. regsalloc(&nod2, nn);
  972. nn->type = t;
  973. gopcode(OAS, &nod1, Z, &nod2);
  974. regfree(&nod1);
  975. nod2.type = typ(TIND, t);
  976. nod1 = nod2;
  977. nod1.op = OIND;
  978. nod1.left = &nod2;
  979. nod1.right = Z;
  980. nod1.complex = 1;
  981. nod1.type = t;
  982. sugen(n, &nod1, w);
  983. return;
  984. }
  985. if(n->complex > nn->complex) {
  986. t = n->type;
  987. n->type = types[TLONG];
  988. reglcgen(&nod1, n, Z);
  989. n->type = t;
  990. t = nn->type;
  991. nn->type = types[TLONG];
  992. reglcgen(&nod2, nn, Z);
  993. nn->type = t;
  994. } else {
  995. t = nn->type;
  996. nn->type = types[TLONG];
  997. reglcgen(&nod2, nn, Z);
  998. nn->type = t;
  999. t = n->type;
  1000. n->type = types[TLONG];
  1001. reglcgen(&nod1, n, Z);
  1002. n->type = t;
  1003. }
  1004. w /= SZ_LONG;
  1005. if(w <= 5) {
  1006. layout(&nod1, &nod2, w, 0, Z);
  1007. goto out;
  1008. }
  1009. /*
  1010. * minimize space for unrolling loop
  1011. * 3,4,5 times. (6 or more is never minimum)
  1012. * if small structure, try 2 also.
  1013. */
  1014. c = 0; /* set */
  1015. m = 100;
  1016. i = 3;
  1017. if(w <= 15)
  1018. i = 2;
  1019. for(; i<=5; i++)
  1020. if(i + w%i <= m) {
  1021. c = i;
  1022. m = c + w%c;
  1023. }
  1024. regalloc(&nod3, &regnode, Z);
  1025. layout(&nod1, &nod2, w%c, w/c, &nod3);
  1026. pc1 = pc;
  1027. layout(&nod1, &nod2, c, 0, Z);
  1028. gopcode(OSUB, nodconst(1), Z, &nod3);
  1029. nod1.op = OREGISTER;
  1030. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
  1031. nod2.op = OREGISTER;
  1032. gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
  1033. gopcode(OEQ, &nod3, Z, Z);
  1034. p->as = ABGTZ;
  1035. patch(p, pc1);
  1036. regfree(&nod3);
  1037. out:
  1038. regfree(&nod1);
  1039. regfree(&nod2);
  1040. }
  1041. void
  1042. layout(Node *f, Node *t, int c, int cv, Node *cn)
  1043. {
  1044. Node t1, t2;
  1045. while(c > 3) {
  1046. layout(f, t, 2, 0, Z);
  1047. c -= 2;
  1048. }
  1049. regalloc(&t1, &regnode, Z);
  1050. regalloc(&t2, &regnode, Z);
  1051. t1.type = types[TLONG];
  1052. t2.type = types[TLONG];
  1053. if(c > 0) {
  1054. gopcode(OAS, f, Z, &t1);
  1055. f->xoffset += SZ_LONG;
  1056. }
  1057. if(cn != Z)
  1058. gopcode(OAS, nodconst(cv), Z, cn);
  1059. if(c > 1) {
  1060. gopcode(OAS, f, Z, &t2);
  1061. f->xoffset += SZ_LONG;
  1062. }
  1063. if(c > 0) {
  1064. gopcode(OAS, &t1, Z, t);
  1065. t->xoffset += SZ_LONG;
  1066. }
  1067. if(c > 2) {
  1068. gopcode(OAS, f, Z, &t1);
  1069. f->xoffset += SZ_LONG;
  1070. }
  1071. if(c > 1) {
  1072. gopcode(OAS, &t2, Z, t);
  1073. t->xoffset += SZ_LONG;
  1074. }
  1075. if(c > 2) {
  1076. gopcode(OAS, &t1, Z, t);
  1077. t->xoffset += SZ_LONG;
  1078. }
  1079. regfree(&t1);
  1080. regfree(&t2);
  1081. }