com.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510
  1. #include "limbo.h"
  2. static Inst **breaks;
  3. static Inst **conts;
  4. static Decl **labels;
  5. static Node **bcscps;
  6. static int labdep;
  7. static Inst nocont;
  8. static int scp;
  9. static Node *scps[MaxScope];
  10. static int trcom(Node*, Node*, int);
  11. static void
  12. pushscp(Node *n)
  13. {
  14. if (scp >= MaxScope)
  15. fatal("scope too deep");
  16. scps[scp++] = n;
  17. }
  18. static void
  19. popscp(void)
  20. {
  21. scp--;
  22. }
  23. static Node *
  24. curscp(void)
  25. {
  26. if (scp == 0)
  27. return nil;
  28. return scps[scp-1];
  29. }
  30. static void
  31. zeroscopes(Node *stop)
  32. {
  33. int i;
  34. Node *cs;
  35. for (i = scp-1; i >= 0; i--) {
  36. cs = scps[i];
  37. if (cs == stop)
  38. break;
  39. zcom(cs->left, nil);
  40. }
  41. }
  42. static void
  43. zeroallscopes(Node *n, Node **nn)
  44. {
  45. if(n == nil)
  46. return;
  47. for(; n != nil; n = n->right){
  48. switch(n->op){
  49. case Oscope:
  50. zeroallscopes(n->right, nn);
  51. zcom(n->left, nn);
  52. return;
  53. case Olabel:
  54. case Odo:
  55. zeroallscopes(n->right, nn);
  56. return;
  57. case Oif:
  58. case Ofor:
  59. zeroallscopes(n->right->left, nn);
  60. zeroallscopes(n->right->right, nn);
  61. return;
  62. case Oalt:
  63. case Ocase:
  64. case Opick:
  65. case Oexcept:
  66. for(n = n->right; n != nil; n = n->right)
  67. zeroallscopes(n->left->right, nn);
  68. return;
  69. case Oseq:
  70. zeroallscopes(n->left, nn);
  71. break;
  72. case Oexstmt:
  73. zeroallscopes(n->left, nn);
  74. zeroallscopes(n->right, nn);
  75. return;
  76. default:
  77. return;
  78. }
  79. }
  80. }
  81. static Except *excs;
  82. static void
  83. installexc(Node *en, Inst *p1, Inst *p2, Node *zn)
  84. {
  85. int i, ne;
  86. Except *e;
  87. Case *c;
  88. Label *lab;
  89. e = allocmem(sizeof(Except));
  90. e->p1 = p1;
  91. e->p2 = p2;
  92. e->c = en->ty->cse;
  93. e->d = en->left->decl;
  94. e->zn = zn;
  95. e->desc = nil;
  96. e->next = excs;
  97. excs = e;
  98. ne = 0;
  99. c = e->c;
  100. for(i = 0; i < c->nlab; i++){
  101. lab = &c->labs[i];
  102. if(lab->start->ty->kind == Texception)
  103. ne++;
  104. }
  105. e->ne = ne;
  106. }
  107. static int
  108. inlist(Decl *d, Decl *dd)
  109. {
  110. for( ; dd != nil; dd = dd->next)
  111. if(d == dd)
  112. return 1;
  113. return 0;
  114. }
  115. static void
  116. excdesc(void)
  117. {
  118. ulong o, maxo;
  119. Except *e;
  120. Node *n;
  121. Decl *d, *dd, *nd;
  122. for(e = excs; e != nil; e = e->next){
  123. if(e->zn != nil){
  124. /* set up a decl list for gendesc */
  125. dd = nil;
  126. maxo = 0;
  127. for(n = e->zn ; n != nil; n = n->right){
  128. d = n->decl;
  129. d->locals = d->next;
  130. if(!inlist(d, dd)){
  131. d->next = dd;
  132. dd = d;
  133. o = d->offset+d->ty->size;
  134. if(o > maxo)
  135. maxo = o;
  136. }
  137. }
  138. e->desc = gendesc(e->d, align(maxo, MaxAlign), dd);
  139. for(d = dd; d != nil; d = nd){
  140. nd = d->next;
  141. d->next = d->locals;
  142. d->locals = nil;
  143. }
  144. e->zn = nil;
  145. }
  146. }
  147. }
  148. static Except*
  149. reve(Except *e)
  150. {
  151. Except *l, *n;
  152. l = nil;
  153. for( ; e != nil; e = n){
  154. n = e->next;
  155. e->next = l;
  156. l = e;
  157. }
  158. return l;
  159. }
  160. static int
  161. ckinline0(Node *n, Decl *d)
  162. {
  163. Decl *dd;
  164. if(n == nil)
  165. return 1;
  166. if(n->op == Oname){
  167. dd = n->decl;
  168. if(d == dd)
  169. return 0;
  170. if(dd->caninline == 1)
  171. return ckinline0(dd->init->right, d);
  172. return 1;
  173. }
  174. return ckinline0(n->left, d) && ckinline0(n->right, d);
  175. }
  176. static void
  177. ckinline(Decl *d)
  178. {
  179. d->caninline = ckinline0(d->init->right, d);
  180. }
  181. void
  182. modcom(Decl *entry)
  183. {
  184. Decl *globals, *m, *nils, *d, *ldts;
  185. long ninst, ndata, ndesc, nlink, offset, ldtoff;
  186. int ok, i, hints;
  187. Dlist *dl;
  188. if(errors)
  189. return;
  190. if(emitcode || emitstub || emittab != nil){
  191. emit(curscope());
  192. popscope();
  193. return;
  194. }
  195. /*
  196. * scom introduces global variables for case statements
  197. * and unaddressable constants, so it must be done before
  198. * popping the global scope
  199. */
  200. nlabel = 0;
  201. maxstack = MaxTemp;
  202. genstart();
  203. for(i = 0; i < nfns; i++)
  204. if(fns[i]->caninline == 1)
  205. ckinline(fns[i]);
  206. ok = 0;
  207. for(i = 0; i < nfns; i++){
  208. d = fns[i];
  209. if(debug['v']) print("fncom: %s %d %p\n", d->sym->name, d->refs, d);
  210. if(d->refs > 1 && !(d->caninline == 1 && local(d) && d->iface == nil)){
  211. fns[ok++] = d;
  212. fncom(d);
  213. }
  214. }
  215. nfns = ok;
  216. if(blocks != -1)
  217. fatal("blocks not nested correctly");
  218. firstinst = firstinst->next;
  219. if(errors)
  220. return;
  221. globals = popscope();
  222. checkrefs(globals);
  223. if(errors)
  224. return;
  225. globals = vars(globals);
  226. moddataref();
  227. nils = popscope();
  228. m = nil;
  229. for(d = nils; d != nil; d = d->next){
  230. if(debug['n'])
  231. print("nil '%s' ref %d\n", d->sym->name, d->refs);
  232. if(d->refs && m == nil)
  233. m = dupdecl(d);
  234. d->offset = 0;
  235. }
  236. globals = appdecls(m, globals);
  237. globals = namesort(globals);
  238. globals = modglobals(impdecls->d, globals);
  239. vcom(globals);
  240. narrowmods();
  241. ldts = nil;
  242. if(LDT)
  243. globals = resolveldts(globals, &ldts);
  244. offset = idoffsets(globals, 0, IBY2WD);
  245. if(LDT)
  246. ldtoff = idindices(ldts); /* ldtoff = idoffsets(ldts, 0, IBY2WD); */
  247. for(d = nils; d != nil; d = d->next){
  248. if(debug['n'])
  249. print("nil '%s' ref %d\n", d->sym->name, d->refs);
  250. if(d->refs)
  251. d->offset = m->offset;
  252. }
  253. if(debug['g']){
  254. print("globals:\n");
  255. printdecls(globals);
  256. }
  257. ndata = 0;
  258. for(d = globals; d != nil; d = d->next)
  259. ndata++;
  260. ndesc = resolvedesc(impdecls->d, offset, globals);
  261. ninst = resolvepcs(firstinst);
  262. modresolve();
  263. if(impdecls->next != nil)
  264. for(dl = impdecls; dl != nil; dl = dl->next)
  265. resolvemod(dl->d);
  266. nlink = resolvemod(impdecl);
  267. maxstack *= 10;
  268. if(fixss != 0)
  269. maxstack = fixss;
  270. if(debug['s'])
  271. print("%ld instructions\n%ld data elements\n%ld type descriptors\n%ld functions exported\n%ld stack size\n",
  272. ninst, ndata, ndesc, nlink, maxstack);
  273. excs = reve(excs);
  274. if(gendis){
  275. discon(XMAGIC);
  276. hints = 0;
  277. if(mustcompile)
  278. hints |= MUSTCOMPILE;
  279. if(dontcompile)
  280. hints |= DONTCOMPILE;
  281. if(LDT)
  282. hints |= HASLDT;
  283. if(excs != nil)
  284. hints |= HASEXCEPT;
  285. discon(hints); /* runtime hints */
  286. discon(maxstack); /* minimum stack extent size */
  287. discon(ninst);
  288. discon(offset);
  289. discon(ndesc);
  290. discon(nlink);
  291. disentry(entry);
  292. disinst(firstinst);
  293. disdesc(descriptors);
  294. disvar(offset, globals);
  295. dismod(impdecl);
  296. if(LDT)
  297. disldt(ldtoff, ldts);
  298. if(excs != nil)
  299. disexc(excs);
  300. dispath();
  301. }else{
  302. asminst(firstinst);
  303. asmentry(entry);
  304. asmdesc(descriptors);
  305. asmvar(offset, globals);
  306. asmmod(impdecl);
  307. if(LDT)
  308. asmldt(ldtoff, ldts);
  309. if(excs != nil)
  310. asmexc(excs);
  311. asmpath();
  312. }
  313. if(bsym != nil){
  314. sblmod(impdecl);
  315. sblfiles();
  316. sblinst(firstinst, ninst);
  317. sblty(adts, nadts);
  318. sblfn(fns, nfns);
  319. sblvar(globals);
  320. }
  321. firstinst = nil;
  322. lastinst = nil;
  323. excs = nil;
  324. }
  325. void
  326. fncom(Decl *decl)
  327. {
  328. Src src;
  329. Node *n;
  330. Decl *loc, *last;
  331. Inst *in;
  332. int valued;
  333. curfn = decl;
  334. if(ispoly(decl))
  335. addfnptrs(decl, 1);
  336. /*
  337. * pick up the function body and compile it
  338. * this code tries to clean up the parse nodes as fast as possible
  339. * function is Ofunc(name, body)
  340. */
  341. decl->pc = nextinst();
  342. tinit();
  343. labdep = 0;
  344. scp = 0;
  345. breaks = allocmem(maxlabdep * sizeof breaks[0]);
  346. conts = allocmem(maxlabdep * sizeof conts[0]);
  347. labels = allocmem(maxlabdep * sizeof labels[0]);
  348. bcscps = allocmem(maxlabdep * sizeof bcscps[0]);
  349. n = decl->init;
  350. if(decl->caninline == 1)
  351. decl->init = dupn(0, nil, n);
  352. else
  353. decl->init = n->left;
  354. src = n->right->src;
  355. src.start.line = src.stop.line;
  356. src.start.pos = src.stop.pos - 1;
  357. for(n = n->right; n != nil; n = n->right){
  358. if(n->op != Oseq){
  359. if(n->op == Ocall && trcom(n, nil, 1))
  360. break;
  361. scom(n);
  362. break;
  363. }
  364. if(n->left->op == Ocall && trcom(n->left, n->right, 1)){
  365. n = n->right;
  366. if(n == nil || n->op != Oseq)
  367. break;
  368. }
  369. else
  370. scom(n->left);
  371. }
  372. pushblock();
  373. valued = decl->ty->tof != tnone;
  374. in = genrawop(&src, valued? IRAISE: IRET, nil, nil, nil);
  375. popblock();
  376. reach(decl->pc);
  377. if(valued && in->reach)
  378. error(src.start, "no return at end of function %D", decl);
  379. /* decl->endpc = lastinst; */
  380. if(labdep != 0)
  381. fatal("unbalanced label stack");
  382. free(breaks);
  383. free(conts);
  384. free(labels);
  385. free(bcscps);
  386. loc = declsort(appdecls(vars(decl->locals), tdecls()));
  387. decl->offset = idoffsets(loc, decl->offset, MaxAlign);
  388. for(last = decl->ty->ids; last != nil && last->next != nil; last = last->next)
  389. ;
  390. if(last != nil)
  391. last->next = loc;
  392. else
  393. decl->ty->ids = loc;
  394. if(debug['f']){
  395. print("fn: %s\n", decl->sym->name);
  396. printdecls(decl->ty->ids);
  397. }
  398. decl->desc = gendesc(decl, decl->offset, decl->ty->ids);
  399. decl->locals = loc;
  400. excdesc();
  401. if(decl->offset > maxstack)
  402. maxstack = decl->offset;
  403. if(optims)
  404. optim(decl->pc, decl);
  405. if(last != nil)
  406. last->next = nil;
  407. else
  408. decl->ty->ids = nil;
  409. }
  410. /*
  411. * statement compiler
  412. */
  413. void
  414. scom(Node *n)
  415. {
  416. Inst *p, *pp, *p1, *p2, *p3;
  417. Node tret, *left, *zn;
  418. for(; n != nil; n = n->right){
  419. switch(n->op){
  420. case Ocondecl:
  421. case Otypedecl:
  422. case Ovardecl:
  423. case Oimport:
  424. case Oexdecl:
  425. return;
  426. case Ovardecli:
  427. break;
  428. case Oscope:
  429. pushscp(n);
  430. scom(n->right);
  431. popscp();
  432. zcom(n->left, nil);
  433. return;
  434. case Olabel:
  435. scom(n->right);
  436. return;
  437. case Oif:
  438. pushblock();
  439. left = simplify(n->left);
  440. if(left->op == Oconst && left->ty == tint){
  441. if(left->val != 0)
  442. scom(n->right->left);
  443. else
  444. scom(n->right->right);
  445. popblock();
  446. return;
  447. }
  448. sumark(left);
  449. pushblock();
  450. p = bcom(left, 1, nil);
  451. tfreenow();
  452. popblock();
  453. scom(n->right->left);
  454. if(n->right->right != nil){
  455. pp = p;
  456. p = genrawop(&lastinst->src, IJMP, nil, nil, nil);
  457. patch(pp, nextinst());
  458. scom(n->right->right);
  459. }
  460. patch(p, nextinst());
  461. popblock();
  462. return;
  463. case Ofor:
  464. n->left = left = simplify(n->left);
  465. if(left->op == Oconst && left->ty == tint){
  466. if(left->val == 0)
  467. return;
  468. left->op = Onothing;
  469. left->ty = tnone;
  470. left->decl = nil;
  471. }
  472. pp = nextinst();
  473. pushblock();
  474. /* b = pushblock(); */
  475. sumark(left);
  476. p = bcom(left, 1, nil);
  477. tfreenow();
  478. popblock();
  479. if(labdep >= maxlabdep)
  480. fatal("label stack overflow");
  481. breaks[labdep] = nil;
  482. conts[labdep] = nil;
  483. labels[labdep] = n->decl;
  484. bcscps[labdep] = curscp();
  485. labdep++;
  486. scom(n->right->left);
  487. labdep--;
  488. patch(conts[labdep], nextinst());
  489. if(n->right->right != nil){
  490. pushblock();
  491. scom(n->right->right);
  492. popblock();
  493. }
  494. repushblock(lastinst->block); /* was b */
  495. patch(genrawop(&lastinst->src, IJMP, nil, nil, nil), pp); /* for cprof: was &left->src */
  496. popblock();
  497. patch(p, nextinst());
  498. patch(breaks[labdep], nextinst());
  499. return;
  500. case Odo:
  501. pp = nextinst();
  502. if(labdep >= maxlabdep)
  503. fatal("label stack overflow");
  504. breaks[labdep] = nil;
  505. conts[labdep] = nil;
  506. labels[labdep] = n->decl;
  507. bcscps[labdep] = curscp();
  508. labdep++;
  509. scom(n->right);
  510. labdep--;
  511. patch(conts[labdep], nextinst());
  512. left = simplify(n->left);
  513. if(left->op == Onothing
  514. || left->op == Oconst && left->ty == tint){
  515. if(left->op == Onothing || left->val != 0){
  516. pushblock();
  517. p = genrawop(&left->src, IJMP, nil, nil, nil);
  518. popblock();
  519. }else
  520. p = nil;
  521. }else{
  522. pushblock();
  523. p = bcom(sumark(left), 0, nil);
  524. tfreenow();
  525. popblock();
  526. }
  527. patch(p, pp);
  528. patch(breaks[labdep], nextinst());
  529. return;
  530. case Oalt:
  531. case Ocase:
  532. case Opick:
  533. case Oexcept:
  534. /* need push/pop blocks for alt guards */
  535. pushblock();
  536. if(labdep >= maxlabdep)
  537. fatal("label stack overflow");
  538. breaks[labdep] = nil;
  539. conts[labdep] = &nocont;
  540. labels[labdep] = n->decl;
  541. bcscps[labdep] = curscp();
  542. labdep++;
  543. switch(n->op){
  544. case Oalt:
  545. altcom(n);
  546. break;
  547. case Ocase:
  548. case Opick:
  549. casecom(n);
  550. break;
  551. case Oexcept:
  552. excom(n);
  553. break;
  554. }
  555. labdep--;
  556. patch(breaks[labdep], nextinst());
  557. popblock();
  558. return;
  559. case Obreak:
  560. pushblock();
  561. bccom(n, breaks);
  562. popblock();
  563. break;
  564. case Ocont:
  565. pushblock();
  566. bccom(n, conts);
  567. popblock();
  568. break;
  569. case Oseq:
  570. if(n->left->op == Ocall && trcom(n->left, n->right, 0)){
  571. n = n->right;
  572. if(n == nil || n->op != Oseq)
  573. return;
  574. }
  575. else
  576. scom(n->left);
  577. break;
  578. case Oret:
  579. if(n->left != nil && n->left->op == Ocall && trcom(n->left, nil, 1))
  580. return;
  581. pushblock();
  582. if(n->left != nil){
  583. n->left = simplify(n->left);
  584. sumark(n->left);
  585. ecom(&n->left->src, retalloc(&tret, n->left), n->left);
  586. tfreenow();
  587. }
  588. genrawop(&n->src, IRET, nil, nil, nil);
  589. popblock();
  590. return;
  591. case Oexit:
  592. pushblock();
  593. genrawop(&n->src, IEXIT, nil, nil, nil);
  594. popblock();
  595. return;
  596. case Onothing:
  597. return;
  598. case Ofunc:
  599. fatal("Ofunc");
  600. return;
  601. case Oexstmt:
  602. pushblock();
  603. pp = genrawop(&n->right->src, IEXC0, nil, nil, nil); /* marker */
  604. p1 = nextinst();
  605. scom(n->left);
  606. p2 = nextinst();
  607. p3 = genrawop(&n->right->src, IJMP, nil, nil, nil);
  608. p = genrawop(&n->right->src, IEXC, nil, nil, nil); /* marker */
  609. p->d.decl = mkdecl(&n->src, 0, n->right->ty);
  610. zn = nil;
  611. zeroallscopes(n->left, &zn);
  612. scom(n->right);
  613. patch(p3, nextinst());
  614. installexc(n->right, p1, p2, zn);
  615. patch(pp, p);
  616. popblock();
  617. return;
  618. default:
  619. pushblock();
  620. n = simplify(n);
  621. sumark(n);
  622. ecom(&n->src, nil, n);
  623. tfreenow();
  624. popblock();
  625. return;
  626. }
  627. }
  628. }
  629. /*
  630. * compile a break, continue
  631. */
  632. void
  633. bccom(Node *n, Inst **bs)
  634. {
  635. Sym *s;
  636. Inst *p;
  637. int i, ok;
  638. s = nil;
  639. if(n->decl != nil)
  640. s = n->decl->sym;
  641. ok = -1;
  642. for(i = 0; i < labdep; i++){
  643. if(bs[i] == &nocont)
  644. continue;
  645. if(s == nil || labels[i] != nil && labels[i]->sym == s)
  646. ok = i;
  647. }
  648. if(ok < 0){
  649. nerror(n, "no appropriate target for %V", n);
  650. return;
  651. }
  652. zeroscopes(bcscps[ok]);
  653. p = genrawop(&n->src, IJMP, nil, nil, nil);
  654. p->branch = bs[ok];
  655. bs[ok] = p;
  656. }
  657. static int
  658. dogoto(Case *c)
  659. {
  660. int i, j, k, n, r, q, v;
  661. Label *l, *nl;
  662. Src *src;
  663. l = c->labs;
  664. n = c->nlab;
  665. if(n == 0)
  666. return 0;
  667. r = l[n-1].stop->val - l[0].start->val+1;
  668. if(r >= 3 && r <= 3*n){
  669. if(r != n){
  670. /* remove ranges, fill in gaps */
  671. c->nlab = r;
  672. nl = c->labs = allocmem(r*sizeof(*nl));
  673. k = 0;
  674. v = l[0].start->val-1;
  675. for(i = 0; i < n; i++){
  676. /* p = l[i].start->val; */
  677. q = l[i].stop->val;
  678. src = &l[i].start->src;
  679. for(j = v+1; j <= q; j++){
  680. nl[k] = l[i];
  681. nl[k].start = nl[k].stop = mkconst(src, j);
  682. k++;
  683. }
  684. v = q;
  685. }
  686. if(k != r)
  687. fatal("bad case expansion");
  688. }
  689. l = c->labs;
  690. for(i = 0; i < r; i++)
  691. l[i].inst = nil;
  692. return 1;
  693. }
  694. return 0;
  695. }
  696. static void
  697. fillrange(Case *c, Node *nn, Inst *in)
  698. {
  699. int i, j, n, p, q;
  700. Label *l;
  701. l = c->labs;
  702. n = c->nlab;
  703. p = nn->left->val;
  704. q = nn->right->val;
  705. for(i = 0; i < n; i++)
  706. if(l[i].start->val == p)
  707. break;
  708. if(i == n)
  709. fatal("fillrange fails");
  710. for(j = p; j <= q; j++)
  711. l[i++].inst = in;
  712. }
  713. static int
  714. nconstqual(Node *s1)
  715. {
  716. Node *s2;
  717. int n;
  718. n = 0;
  719. for(; s1 != nil; s1 = s1->right){
  720. for(s2 = s1->left->left; s2 != nil; s2 = s2->right)
  721. if(s2->left->op == Oconst)
  722. n++;
  723. }
  724. return n;
  725. }
  726. void
  727. casecom(Node *cn)
  728. {
  729. Src *src;
  730. Case *c;
  731. Decl *d;
  732. Type *ctype;
  733. Inst *j, *jmps, *wild, *k, *j1, *j2;
  734. Node *n, *p, *left, tmp, nto, tmpc;
  735. Label *labs;
  736. char buf[32];
  737. int i, nlab, op, needwild, igoto;
  738. c = cn->ty->cse;
  739. needwild = cn->op != Opick || nconstqual(cn->right) != cn->left->right->ty->tof->decl->tag;
  740. igoto = cn->left->ty == tint && dogoto(c);
  741. j1 = j2 = nil;
  742. /*
  743. * generate global which has case labels
  744. */
  745. if(igoto){
  746. seprint(buf, buf+sizeof(buf), ".g%d", nlabel++);
  747. cn->ty->kind = Tgoto;
  748. }
  749. else
  750. seprint(buf, buf+sizeof(buf), ".c%d", nlabel++);
  751. d = mkids(&cn->src, enter(buf, 0), cn->ty, nil);
  752. d->init = mkdeclname(&cn->src, d);
  753. nto.addable = Rmreg;
  754. nto.left = nil;
  755. nto.right = nil;
  756. nto.op = Oname;
  757. nto.ty = d->ty;
  758. nto.decl = d;
  759. tmp.decl = tmpc.decl = nil;
  760. left = cn->left;
  761. left = simplify(left);
  762. cn->left = left;
  763. sumark(left);
  764. if(debug['c'])
  765. print("case %n\n", left);
  766. ctype = cn->left->ty;
  767. if(left->addable >= Rcant){
  768. if(cn->op == Opick){
  769. ecom(&left->src, nil, left);
  770. tfreenow();
  771. left = mkunary(Oind, dupn(1, &left->src, left->left));
  772. left->ty = tint;
  773. sumark(left);
  774. ctype = tint;
  775. }else{
  776. left = eacom(left, &tmp, nil);
  777. tfreenow();
  778. }
  779. }
  780. labs = c->labs;
  781. nlab = c->nlab;
  782. if(igoto){
  783. if(labs[0].start->val != 0){
  784. talloc(&tmpc, left->ty, nil);
  785. if(left->addable == Radr || left->addable == Rmadr){
  786. genrawop(&left->src, IMOVW, left, nil, &tmpc);
  787. left = &tmpc;
  788. }
  789. genrawop(&left->src, ISUBW, sumark(labs[0].start), left, &tmpc);
  790. left = &tmpc;
  791. }
  792. if(needwild){
  793. j1 = genrawop(&left->src, IBLTW, left, sumark(mkconst(&left->src, 0)), nil);
  794. j2 = genrawop(&left->src, IBGTW, left, sumark(mkconst(&left->src, labs[nlab-1].start->val-labs[0].start->val)), nil);
  795. }
  796. j = nextinst();
  797. genrawop(&left->src, IGOTO, left, nil, &nto);
  798. j->d.reg = IBY2WD;
  799. }
  800. else{
  801. op = ICASE;
  802. if(ctype == tbig)
  803. op = ICASEL;
  804. else if(ctype == tstring)
  805. op = ICASEC;
  806. genrawop(&left->src, op, left, nil, &nto);
  807. }
  808. tfree(&tmp);
  809. tfree(&tmpc);
  810. jmps = nil;
  811. wild = nil;
  812. for(n = cn->right; n != nil; n = n->right){
  813. j = nextinst();
  814. for(p = n->left->left; p != nil; p = p->right){
  815. if(debug['c'])
  816. print("case qualifier %n\n", p->left);
  817. switch(p->left->op){
  818. case Oconst:
  819. labs[findlab(ctype, p->left, labs, nlab)].inst = j;
  820. break;
  821. case Orange:
  822. labs[findlab(ctype, p->left->left, labs, nlab)].inst = j;
  823. if(igoto)
  824. fillrange(c, p->left, j);
  825. break;
  826. case Owild:
  827. if(needwild)
  828. wild = j;
  829. /*
  830. else
  831. nwarn(p->left, "default case redundant");
  832. */
  833. break;
  834. }
  835. }
  836. if(debug['c'])
  837. print("case body for %V: %n\n", n->left->left, n->left->right);
  838. k = nextinst();
  839. scom(n->left->right);
  840. src = &lastinst->src;
  841. // if(n->left->right == nil || n->left->right->op == Onothing)
  842. if(k == nextinst())
  843. src = &n->left->left->src;
  844. j = genrawop(src, IJMP, nil, nil, nil);
  845. j->branch = jmps;
  846. jmps = j;
  847. }
  848. patch(jmps, nextinst());
  849. if(wild == nil && needwild)
  850. wild = nextinst();
  851. if(igoto){
  852. if(needwild){
  853. patch(j1, wild);
  854. patch(j2, wild);
  855. }
  856. for(i = 0; i < nlab; i++)
  857. if(labs[i].inst == nil)
  858. labs[i].inst = wild;
  859. }
  860. c->iwild = wild;
  861. d->ty->cse = c;
  862. usetype(d->ty);
  863. installids(Dglobal, d);
  864. }
  865. void
  866. altcom(Node *nalt)
  867. {
  868. Src altsrc;
  869. Case *c;
  870. Decl *d;
  871. Type *talt;
  872. Node *n, *p, *left, tab, slot, off, add, which, nto, adr;
  873. Node **comm, *op, *tmps;
  874. Inst *j, *tj, *jmps, *me, *wild;
  875. Label *labs;
  876. char buf[32];
  877. int i, is, ir, nlab, nsnd, altop, isptr;
  878. Inst *pp;
  879. talt = nalt->ty;
  880. c = talt->cse;
  881. nlab = c->nlab;
  882. nsnd = c->nsnd;
  883. comm = allocmem(nlab * sizeof *comm);
  884. labs = allocmem(nlab * sizeof *labs);
  885. tmps = allocmem(nlab * sizeof *tmps);
  886. c->labs = labs;
  887. /*
  888. * built the type of the alt channel table
  889. * note that we lie to the garbage collector
  890. * if we know that another reference exists for the channel
  891. */
  892. is = 0;
  893. ir = nsnd;
  894. i = 0;
  895. for(n = nalt->left; n != nil; n = n->right){
  896. for(p = n->left->right->left; p != nil; p = p->right){
  897. left = simplify(p->left);
  898. p->left = left;
  899. if(left->op == Owild)
  900. continue;
  901. comm[i] = hascomm(left);
  902. left = comm[i]->left;
  903. sumark(left);
  904. isptr = left->addable >= Rcant;
  905. if(comm[i]->op == Osnd)
  906. labs[is++].isptr = isptr;
  907. else
  908. labs[ir++].isptr = isptr;
  909. i++;
  910. }
  911. }
  912. talloc(&which, tint, nil);
  913. talloc(&tab, talt, nil);
  914. /*
  915. * build the node for the address of each channel,
  916. * the values to send, and the storage fro values received
  917. */
  918. off = znode;
  919. off.op = Oconst;
  920. off.ty = tint;
  921. off.addable = Rconst;
  922. adr = znode;
  923. adr.op = Oadr;
  924. adr.left = &tab;
  925. adr.ty = tint;
  926. add = znode;
  927. add.op = Oadd;
  928. add.left = &adr;
  929. add.right = &off;
  930. add.ty = tint;
  931. slot = znode;
  932. slot.op = Oind;
  933. slot.left = &add;
  934. sumark(&slot);
  935. /*
  936. * compile the sending and receiving channels and values
  937. */
  938. is = 2*IBY2WD;
  939. ir = is + nsnd*2*IBY2WD;
  940. i = 0;
  941. for(n = nalt->left; n != nil; n = n->right){
  942. for(p = n->left->right->left; p != nil; p = p->right){
  943. if(p->left->op == Owild)
  944. continue;
  945. /*
  946. * gen channel
  947. */
  948. op = comm[i];
  949. if(op->op == Osnd){
  950. off.val = is;
  951. is += 2*IBY2WD;
  952. }else{
  953. off.val = ir;
  954. ir += 2*IBY2WD;
  955. }
  956. left = op->left;
  957. /*
  958. * this sleaze is lying to the garbage collector
  959. */
  960. if(left->addable < Rcant)
  961. genmove(&left->src, Mas, tint, left, &slot);
  962. else{
  963. slot.ty = left->ty;
  964. ecom(&left->src, &slot, left);
  965. tfreenow();
  966. slot.ty = nil;
  967. }
  968. /*
  969. * gen value
  970. */
  971. off.val += IBY2WD;
  972. tmps[i].decl = nil;
  973. p->left = rewritecomm(p->left, comm[i], &tmps[i], &slot);
  974. i++;
  975. }
  976. }
  977. /*
  978. * stuff the number of send & receive channels into the table
  979. */
  980. altsrc = nalt->src;
  981. altsrc.stop.pos += 3;
  982. off.val = 0;
  983. genmove(&altsrc, Mas, tint, sumark(mkconst(&altsrc, nsnd)), &slot);
  984. off.val += IBY2WD;
  985. genmove(&altsrc, Mas, tint, sumark(mkconst(&altsrc, nlab-nsnd)), &slot);
  986. off.val += IBY2WD;
  987. altop = IALT;
  988. if(c->wild != nil)
  989. altop = INBALT;
  990. pp = genrawop(&altsrc, altop, &tab, nil, &which);
  991. pp->m.offset = talt->size; /* for optimizer */
  992. seprint(buf, buf+sizeof(buf), ".g%d", nlabel++);
  993. d = mkids(&nalt->src, enter(buf, 0), mktype(&nalt->src.start, &nalt->src.stop, Tgoto, nil, nil), nil);
  994. d->ty->cse = c;
  995. d->init = mkdeclname(&nalt->src, d);
  996. nto.addable = Rmreg;
  997. nto.left = nil;
  998. nto.right = nil;
  999. nto.op = Oname;
  1000. nto.decl = d;
  1001. nto.ty = d->ty;
  1002. me = nextinst();
  1003. genrawop(&altsrc, IGOTO, &which, nil, &nto);
  1004. me->d.reg = IBY2WD; /* skip the number of cases field */
  1005. tfree(&tab);
  1006. tfree(&which);
  1007. /*
  1008. * compile the guard expressions and bodies
  1009. */
  1010. i = 0;
  1011. is = 0;
  1012. ir = nsnd;
  1013. jmps = nil;
  1014. wild = nil;
  1015. for(n = nalt->left; n != nil; n = n->right){
  1016. j = nil;
  1017. for(p = n->left->right->left; p != nil; p = p->right){
  1018. tj = nextinst();
  1019. if(p->left->op == Owild){
  1020. wild = nextinst();
  1021. }else{
  1022. if(comm[i]->op == Osnd)
  1023. labs[is++].inst = tj;
  1024. else{
  1025. labs[ir++].inst = tj;
  1026. tacquire(&tmps[i]);
  1027. }
  1028. sumark(p->left);
  1029. if(debug['a'])
  1030. print("alt guard %n\n", p->left);
  1031. ecom(&p->left->src, nil, p->left);
  1032. tfree(&tmps[i]);
  1033. tfreenow();
  1034. i++;
  1035. }
  1036. if(p->right != nil){
  1037. tj = genrawop(&lastinst->src, IJMP, nil, nil, nil);
  1038. tj->branch = j;
  1039. j = tj;
  1040. }
  1041. }
  1042. patch(j, nextinst());
  1043. if(debug['a'])
  1044. print("alt body %n\n", n->left->right);
  1045. scom(n->left);
  1046. j = genrawop(&lastinst->src, IJMP, nil, nil, nil);
  1047. j->branch = jmps;
  1048. jmps = j;
  1049. }
  1050. patch(jmps, nextinst());
  1051. free(comm);
  1052. c->iwild = wild;
  1053. usetype(d->ty);
  1054. installids(Dglobal, d);
  1055. }
  1056. void
  1057. excom(Node *en)
  1058. {
  1059. Src *src;
  1060. Decl *ed;
  1061. Type *qt;
  1062. Case *c;
  1063. Inst *j, *jmps, *wild, *k;
  1064. Node *n, *p;
  1065. Label *labs;
  1066. int nlab;
  1067. ed = en->left->decl;
  1068. ed->ty = rtexception;
  1069. c = en->ty->cse;
  1070. labs = c->labs;
  1071. nlab = c->nlab;
  1072. jmps = nil;
  1073. wild = nil;
  1074. for(n = en->right; n != nil; n = n->right){
  1075. qt = nil;
  1076. j = nextinst();
  1077. for(p = n->left->left; p != nil; p = p->right){
  1078. switch(p->left->op){
  1079. case Oconst:
  1080. labs[findlab(texception, p->left, labs, nlab)].inst = j;
  1081. break;
  1082. case Owild:
  1083. wild = j;
  1084. break;
  1085. }
  1086. if(qt == nil)
  1087. qt = p->left->ty;
  1088. else if(!tequal(qt, p->left->ty))
  1089. qt = texception;
  1090. }
  1091. if(qt != nil)
  1092. ed->ty = qt;
  1093. k = nextinst();
  1094. scom(n->left->right);
  1095. src = &lastinst->src;
  1096. if(k == nextinst())
  1097. src = &n->left->left->src;
  1098. j = genrawop(src, IJMP, nil, nil, nil);
  1099. j->branch = jmps;
  1100. jmps = j;
  1101. }
  1102. ed->ty = rtexception;
  1103. patch(jmps, nextinst());
  1104. c->iwild = wild;
  1105. }
  1106. /*
  1107. * rewrite the communication operand
  1108. * allocate any temps needed for holding value to send or receive
  1109. */
  1110. Node*
  1111. rewritecomm(Node *n, Node *comm, Node *tmp, Node *slot)
  1112. {
  1113. Node *adr;
  1114. Inst *p;
  1115. if(n == nil)
  1116. return nil;
  1117. adr = nil;
  1118. if(n == comm){
  1119. if(comm->op == Osnd && sumark(n->right)->addable < Rcant)
  1120. adr = n->right;
  1121. else{
  1122. adr = talloc(tmp, n->ty, nil);
  1123. tmp->src = n->src;
  1124. if(comm->op == Osnd){
  1125. ecom(&n->right->src, tmp, n->right);
  1126. tfreenow();
  1127. }
  1128. else
  1129. trelease(tmp);
  1130. }
  1131. }
  1132. if(n->right == comm && n->op == Oas && comm->op == Orcv
  1133. && sumark(n->left)->addable < Rcant && (n->left->op != Oname || n->left->decl != nildecl))
  1134. adr = n->left;
  1135. if(adr != nil){
  1136. p = genrawop(&comm->left->src, ILEA, adr, nil, slot);
  1137. p->m.offset = adr->ty->size; /* for optimizer */
  1138. if(comm->op == Osnd)
  1139. p->m.reg = 1; /* for optimizer */
  1140. return adr;
  1141. }
  1142. n->left = rewritecomm(n->left, comm, tmp, slot);
  1143. n->right = rewritecomm(n->right, comm, tmp, slot);
  1144. return n;
  1145. }
  1146. /*
  1147. * merge together two sorted lists, yielding a sorted list
  1148. */
  1149. static Decl*
  1150. declmerge(Decl *e, Decl *f)
  1151. {
  1152. Decl rock, *d;
  1153. int es, fs, v;
  1154. d = &rock;
  1155. while(e != nil && f != nil){
  1156. fs = f->ty->size;
  1157. es = e->ty->size;
  1158. /* v = 0; */
  1159. v = (e->link == nil) - (f->link == nil);
  1160. if(v == 0 && (es <= IBY2WD || fs <= IBY2WD))
  1161. v = fs - es;
  1162. if(v == 0)
  1163. v = e->refs - f->refs;
  1164. if(v == 0)
  1165. v = fs - es;
  1166. if(v == 0)
  1167. v = -strcmp(e->sym->name, f->sym->name);
  1168. if(v >= 0){
  1169. d->next = e;
  1170. d = e;
  1171. e = e->next;
  1172. while(e != nil && e->nid == 0){
  1173. d = e;
  1174. e = e->next;
  1175. }
  1176. }else{
  1177. d->next = f;
  1178. d = f;
  1179. f = f->next;
  1180. while(f != nil && f->nid == 0){
  1181. d = f;
  1182. f = f->next;
  1183. }
  1184. }
  1185. /* d = d->next; */
  1186. }
  1187. if(e != nil)
  1188. d->next = e;
  1189. else
  1190. d->next = f;
  1191. return rock.next;
  1192. }
  1193. /*
  1194. * recursively split lists and remerge them after they are sorted
  1195. */
  1196. static Decl*
  1197. recdeclsort(Decl *d, int n)
  1198. {
  1199. Decl *r, *dd;
  1200. int i, m;
  1201. if(n <= 1)
  1202. return d;
  1203. m = n / 2 - 1;
  1204. dd = d;
  1205. for(i = 0; i < m; i++){
  1206. dd = dd->next;
  1207. while(dd->nid == 0)
  1208. dd = dd->next;
  1209. }
  1210. r = dd->next;
  1211. while(r->nid == 0){
  1212. dd = r;
  1213. r = r->next;
  1214. }
  1215. dd->next = nil;
  1216. return declmerge(recdeclsort(d, n / 2),
  1217. recdeclsort(r, (n + 1) / 2));
  1218. }
  1219. /*
  1220. * sort the ids by size and number of references
  1221. */
  1222. Decl*
  1223. declsort(Decl *d)
  1224. {
  1225. Decl *dd;
  1226. int n;
  1227. n = 0;
  1228. for(dd = d; dd != nil; dd = dd->next)
  1229. if(dd->nid > 0)
  1230. n++;
  1231. return recdeclsort(d, n);
  1232. }
  1233. Src nilsrc;
  1234. /* Do we finally
  1235. * (a) pick off pointers as in the code below
  1236. * (b) generate a block move from zeroed memory as in tfree() in gen.b in limbo version
  1237. * (c) add a new block zero instruction to dis
  1238. * (d) reorganize the locals/temps in a frame
  1239. */
  1240. void
  1241. zcom1(Node *n, Node **nn)
  1242. {
  1243. Type *ty;
  1244. Decl *d;
  1245. Node *e, *dn;
  1246. Src src;
  1247. ty = n->ty;
  1248. if (!tmustzero(ty))
  1249. return;
  1250. if (n->op == Oname && n->decl->refs == 0)
  1251. return;
  1252. if (nn) {
  1253. if(n->op != Oname)
  1254. nerror(n, "fatal: bad op in zcom1 map");
  1255. n->right = *nn;
  1256. *nn = n;
  1257. return;
  1258. }
  1259. if (debug['Z'])
  1260. print("zcom1 : %n\n", n);
  1261. if (ty->kind == Tadtpick)
  1262. ty = ty->tof;
  1263. if (ty->kind == Ttuple || ty->kind == Tadt) {
  1264. for (d = ty->ids; d != nil; d = d->next) {
  1265. if (tmustzero(d->ty)) {
  1266. if (d->next != nil)
  1267. dn = dupn(0, nil, n);
  1268. else
  1269. dn = n;
  1270. e = mkbin(Odot, dn, mkname(&nilsrc, d->sym));
  1271. e->right->decl = d;
  1272. e->ty = e->right->ty = d->ty;
  1273. zcom1(e, nn);
  1274. }
  1275. }
  1276. }
  1277. else {
  1278. src = n->src;
  1279. n->src = nilsrc;
  1280. e = mkbin(Oas, n, mknil(&nilsrc));
  1281. e->ty = e->right->ty = ty;
  1282. /*
  1283. if (debug['Z'])
  1284. print("ecom %n\n", e);
  1285. */
  1286. pushblock();
  1287. e = simplify(e);
  1288. sumark(e);
  1289. ecom(&e->src, nil, e);
  1290. popblock();
  1291. n->src = src;
  1292. }
  1293. }
  1294. void
  1295. zcom0(Decl *id, Node **nn)
  1296. {
  1297. Node *e;
  1298. e = mkname(&nilsrc, id->sym);
  1299. e->decl = id;
  1300. e->ty = id->ty;
  1301. zcom1(e, nn);
  1302. }
  1303. /* end of scope */
  1304. void
  1305. zcom(Node *n, Node **nn)
  1306. {
  1307. Decl *ids, *last;
  1308. Node *r, *nt;
  1309. for ( ; n != nil; n = r) {
  1310. r = n->right;
  1311. n->right = nil;
  1312. switch (n->op) {
  1313. case Ovardecl :
  1314. last = n->left->decl;
  1315. for (ids = n->decl; ids != last->next; ids = ids->next)
  1316. zcom0(ids, nn);
  1317. break;
  1318. case Oname :
  1319. if (n->decl != nildecl)
  1320. zcom1(dupn(0, nil, n), nn);
  1321. break;
  1322. case Otuple :
  1323. for (nt = n->left; nt != nil; nt = nt->right)
  1324. zcom(nt->left, nn);
  1325. break;
  1326. default :
  1327. fatal("bad node in zcom()");
  1328. break;
  1329. }
  1330. n->right = r;
  1331. }
  1332. }
  1333. static int
  1334. ret(Node *n, int nilret)
  1335. {
  1336. if(n == nil)
  1337. return nilret;
  1338. if(n->op == Oseq)
  1339. n = n->left;
  1340. return n->op == Oret && n->left == nil;
  1341. }
  1342. /*
  1343. * tail-recursive call
  1344. */
  1345. static int
  1346. trcom(Node *e, Node *ne, int nilret)
  1347. {
  1348. Decl *d, *id;
  1349. Node *as, *a, *f, *n;
  1350. Inst *p;
  1351. if(1)
  1352. return 0; /* TO DO: should we enable this? */
  1353. if(e->op != Ocall || e->left->op != Oname)
  1354. return 0;
  1355. d = e->left->decl;
  1356. if(d != curfn || d->handler || ispoly(d))
  1357. return 0;
  1358. if(!ret(ne, nilret))
  1359. return 0;
  1360. pushblock();
  1361. id = d->ty->ids;
  1362. /* evaluate args in same order as normal calls */
  1363. for(as = e->right; as != nil; as = as->right){
  1364. a = as->left;
  1365. if(!(a->op == Oname && id == a->decl)){
  1366. if(occurs(id, as->right)){
  1367. f = talloc(mkn(0, nil, nil), id->ty, nil);
  1368. f->flags |= TEMP;
  1369. }
  1370. else
  1371. f = mkdeclname(&as->src, id);
  1372. n = mkbin(Oas, f, a);
  1373. n->ty = id->ty;
  1374. scom(n);
  1375. if(f->flags&TEMP)
  1376. as->left = f;
  1377. }
  1378. id = id->next;
  1379. }
  1380. id = d->ty->ids;
  1381. for(as = e->right; as != nil; as = as->right){
  1382. a = as->left;
  1383. if(a->flags&TEMP){
  1384. f = mkdeclname(&as->src, id);
  1385. n = mkbin(Oas, f, a);
  1386. n->ty = id->ty;
  1387. scom(n);
  1388. tfree(a);
  1389. }
  1390. id = id->next;
  1391. }
  1392. p = genrawop(&e->src, IJMP, nil, nil, nil);
  1393. patch(p, d->pc);
  1394. popblock();
  1395. return 1;
  1396. }