codegen.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  1. #ifndef NORCSID
  2. static char rcsid[] = "$Id$";
  3. #endif
  4. #include "assert.h"
  5. #include "param.h"
  6. #include "tables.h"
  7. #include "types.h"
  8. #include <cg_pattern.h>
  9. #include "data.h"
  10. #include "result.h"
  11. #include "state.h"
  12. #include "equiv.h"
  13. #include "extern.h"
  14. /*
  15. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  16. * See the copyright notice in the ACK home directory, in the file "Copyright".
  17. *
  18. * Author: Hans van Staveren
  19. */
  20. #define SHORTCUT /* Stop searching at distance 0 */
  21. #if NREGS >= MAXRULE
  22. #define MAXPOS NREGS
  23. #else
  24. #define MAXPOS MAXRULE
  25. #endif
  26. #define MAXPATTERN 5
  27. #define MAXREPLLEN 5 /* Max length of EM-replacement, should come from boot */
  28. byte startupcode[] = { DO_NEXTEM };
  29. byte *nextem();
  30. unsigned costcalc();
  31. unsigned docoerc();
  32. unsigned stackupto();
  33. string tostring();
  34. #ifdef NDEBUG
  35. #define DEBUG(xxxxx)
  36. #else
  37. #include <stdio.h>
  38. #define DEBUG(string) {if(Debug) fprintf(stderr,"%-*d%s\n",4*level,level,string);}
  39. #endif
  40. #define BROKE() {assert(origcp!=startupcode);DEBUG("BROKE");goto doreturn;}
  41. #define CHKCOST() {if (totalcost>=costlimit) BROKE();}
  42. unsigned codegen(codep,ply,toplevel,costlimit,forced) byte *codep; unsigned costlimit; {
  43. #ifndef NDEBUG
  44. byte *origcp=codep;
  45. static int level=0;
  46. #endif
  47. unsigned totalcost = 0;
  48. byte *bp;
  49. int n;
  50. unsigned mindistance,dist;
  51. register int i;
  52. int cindex;
  53. int npos,npos2,pos[MAXPOS],pos2[MAXPOS];
  54. #ifdef STONSTACK
  55. state_t state;
  56. #define SAVEST savestatus(&state)
  57. #define RESTST restorestatus(&state)
  58. #define FREEST /* nothing */
  59. #else
  60. state_p state;
  61. #define SAVEST state=savestatus()
  62. #define RESTST restorestatus(state)
  63. #define FREEST freestatus(state)
  64. #endif
  65. unsigned mincost,t;
  66. int texpno,nodeno;
  67. token_p tp;
  68. tkdef_p tdp;
  69. int tinstno;
  70. register struct reginfo *rp;
  71. struct reginfo **rpp;
  72. token_t token,mtoken,token2;
  73. int propno;
  74. int exactmatch;
  75. int j;
  76. int decision;
  77. int stringno;
  78. result_t result;
  79. cost_t cost;
  80. int size,lsize,repllen;
  81. int tokexp[MAXPATTERN];
  82. int nregneeded;
  83. token_p regtp[MAXCREG];
  84. c3_p regcp[MAXCREG];
  85. rl_p regls[MAXCREG];
  86. c3_p findcoerc();
  87. int sret;
  88. token_t reptoken[MAXREPLLEN];
  89. int emrepllen,eminstr;
  90. int inscoerc=0;
  91. int stackpad;
  92. struct perm *tup,*ntup,*besttup,*tuples();
  93. #ifndef NDEBUG
  94. level++;
  95. DEBUG("Entering codegen");
  96. #endif
  97. for (;;) {
  98. switch( (*codep++)&037 ) {
  99. default:
  100. assert(FALSE);
  101. /* NOTREACHED */
  102. case DO_NEXTEM:
  103. DEBUG("NEXTEM");
  104. tokpatlen = 0;
  105. nallreg=0;
  106. if (toplevel) {
  107. garbage_collect();
  108. totalcost=0;
  109. } else {
  110. if (--ply <= 0)
  111. goto doreturn;
  112. }
  113. if (stackheight>MAXFSTACK-7)
  114. totalcost += stackupto(&fakestack[6],ply,toplevel);
  115. bp = nextem(toplevel);
  116. if (bp == 0) {
  117. /*
  118. * No pattern found, can be pseudo or error
  119. * in table.
  120. */
  121. if (toplevel) {
  122. codep--;
  123. DEBUG("pseudo");
  124. dopseudo();
  125. } else
  126. goto doreturn;
  127. } else {
  128. #ifndef NDEBUG
  129. chkregs();
  130. #endif
  131. if (! toplevel) {
  132. ply -= emp-saveemp+1;
  133. if (ply <= 0) ply = 1;
  134. }
  135. n = *bp++;
  136. assert(n>0 && n<=MAXRULE);
  137. if (n>1) {
  138. mindistance = MAXINT; npos=0;
  139. for(i=0;i<n;i++) {
  140. getint(cindex,bp);
  141. dist=distance(cindex);
  142. #ifndef NDEBUG
  143. if (Debug)
  144. fprintf(stderr,"distance of pos %d is %u\n",i,dist);
  145. #endif
  146. if (dist<=mindistance) {
  147. if (dist<mindistance) {
  148. #ifdef SHORTCUT
  149. if(dist==0)
  150. goto gotit;
  151. #endif
  152. npos=0;
  153. mindistance = dist;
  154. }
  155. pos[npos++] = cindex;
  156. }
  157. }
  158. assert(mindistance<MAXINT);
  159. if (npos>1) {
  160. /*
  161. * More than 1 tokenpattern is a candidate.
  162. * Decision has to be made by lookahead.
  163. */
  164. SAVEST;
  165. mincost = costlimit-totalcost+1;
  166. for(i=0;i<npos;i++) {
  167. t=codegen(&coderules[pos[i]],ply,FALSE,
  168. costlimit<MAXINT?mincost:MAXINT,0);
  169. #ifndef NDEBUG
  170. if (Debug)
  171. fprintf(stderr,"mincost %u,cost %u,pos %d\n",mincost,t,i);
  172. #endif
  173. if (t<mincost) {
  174. mincost = t;
  175. cindex = pos[i];
  176. }
  177. RESTST;
  178. }
  179. FREEST;
  180. if (totalcost+mincost>costlimit) {
  181. totalcost += mincost;
  182. BROKE();
  183. }
  184. } else {
  185. cindex = pos[0];
  186. }
  187. } else {
  188. getint(cindex,bp);
  189. }
  190. gotit:
  191. /*
  192. * Now cindex contains the code-index of the best candidate
  193. * so proceed to use it.
  194. */
  195. codep = &coderules[cindex];
  196. }
  197. break;
  198. case DO_COERC:
  199. DEBUG("COERC");
  200. tokpatlen=1;
  201. inscoerc=1;
  202. break;
  203. case DO_XXMATCH:
  204. DEBUG("XXMATCH");
  205. case DO_XMATCH:
  206. DEBUG("XMATCH");
  207. tokpatlen=(codep[-1]>>5)&07;
  208. for (i=0;i<tokpatlen;i++)
  209. getint(tokexp[i],codep);
  210. tokexp[i]=0;
  211. break; /* match already checked by distance() */
  212. case DO_MATCH:
  213. DEBUG("MATCH");
  214. tokpatlen=(codep[-1]>>5)&07;
  215. for(i=0;i<tokpatlen;i++)
  216. getint(tokexp[i],codep);
  217. tokexp[i] = 0;
  218. tp = &fakestack[stackheight-1];
  219. i=0;
  220. while (i<tokpatlen && tp>=fakestack) {
  221. size=tsize(tp);
  222. while (i<tokpatlen && (lsize=ssize(tokexp[i]))<=size) {
  223. size -= lsize;
  224. i++;
  225. }
  226. if (i<tokpatlen && size!=0) {
  227. totalcost += stackupto(tp,ply,toplevel);
  228. CHKCOST();
  229. break;
  230. }
  231. tp--;
  232. }
  233. tp = &fakestack[stackheight-1];
  234. i=0;
  235. while (i<tokpatlen && tp >= fakestack) {
  236. size = tsize(tp);
  237. lsize= ssize(tokexp[i]);
  238. if (size != lsize) { /* find coercion */
  239. #ifdef MAXSPLIT
  240. sret = split(tp,&tokexp[i],ply,toplevel);
  241. if (sret==0) {
  242. #endif /* MAXSPLIT */
  243. totalcost += stackupto(tp,ply,toplevel);
  244. CHKCOST();
  245. break;
  246. #ifdef MAXSPLIT
  247. }
  248. i += sret;
  249. #endif /* MAXSPLIT */
  250. } else
  251. i += 1;
  252. tp--;
  253. }
  254. nextmatch:
  255. tp = &fakestack[stackheight-1];
  256. i=0; nregneeded = 0;
  257. while (i<tokpatlen && tp>=fakestack) {
  258. if (!match(tp,&machsets[tokexp[i]],0)) {
  259. register c3_p cp = findcoerc(tp, &machsets[tokexp[i]]);
  260. if (cp==0) {
  261. for (j=0;j<nregneeded;j++)
  262. regtp[j] -= (tp-fakestack+1);
  263. totalcost += stackupto(tp,ply,toplevel);
  264. CHKCOST();
  265. break;
  266. } else {
  267. if (cp->c3_prop==0) {
  268. totalcost+=docoerc(tp,cp,ply,toplevel,0);
  269. CHKCOST();
  270. } else {
  271. assert(nregneeded<MAXCREG);
  272. regtp[nregneeded] = tp;
  273. regcp[nregneeded] = cp;
  274. regls[nregneeded] = curreglist;
  275. nregneeded++;
  276. }
  277. }
  278. }
  279. i++; tp--;
  280. }
  281. if (tokpatlen>stackheight) {
  282. int k;
  283. stackpad = tokpatlen-stackheight;
  284. for (j=stackheight-1, k = j + stackpad;j>=0;j--, k--) {
  285. fakestack[k] = fakestack[j];
  286. /* fakestack[j+stackpad] = fakestack[j]; does not
  287. compile under Xenix
  288. */
  289. }
  290. for (j=0;j<stackpad;j++)
  291. fakestack[j].t_token=0;
  292. stackheight += stackpad;
  293. for (j=0;j<nregneeded;j++)
  294. regtp[j] += stackpad;
  295. tp = &fakestack[stackpad-1];
  296. while (i<tokpatlen && tp>=fakestack) {
  297. register c3_p cp = findcoerc((token_p) 0, &machsets[tokexp[i]]);
  298. if (cp==0) {
  299. assert(!toplevel);
  300. for (j=0;j<nregneeded;j++)
  301. myfree(regls[j]);
  302. totalcost=INFINITY;
  303. BROKE();
  304. }
  305. if (cp->c3_prop==0) {
  306. totalcost+=docoerc(tp,cp,ply,toplevel,0);
  307. CHKCOST();
  308. } else {
  309. assert(nregneeded<MAXCREG);
  310. regtp[nregneeded] = tp;
  311. regcp[nregneeded] = cp;
  312. regls[nregneeded] = curreglist;
  313. nregneeded++;
  314. }
  315. i++; tp--;
  316. }
  317. } else
  318. stackpad=0;
  319. assert(i==tokpatlen);
  320. if (nregneeded==0)
  321. break;
  322. SAVEST;
  323. mincost=costlimit-totalcost+1;
  324. tup = tuples(regls,nregneeded);
  325. besttup=0;
  326. for (; tup != 0; tup = ntup) {
  327. #ifndef NDEBUG
  328. if(Debug>1) { fprintf(stderr,"Next tuple %d,%d,%d,%d\n",
  329. tup->p_rar[0],
  330. tup->p_rar[1],
  331. tup->p_rar[2],
  332. tup->p_rar[3]);
  333. fprintf(stderr, "totalcost = %u, costlimit = %u, mincost = %u\n",
  334. totalcost, costlimit, mincost);
  335. }
  336. #endif
  337. ntup = tup->p_next;
  338. for (i=0,t=0;i<nregneeded && t<mincost; i++)
  339. t += docoerc(regtp[i],regcp[i],ply,FALSE,tup->p_rar[i]);
  340. #ifndef NDEBUG
  341. if (Debug > 1) fprintf(stderr, "cost after coercions: %u\n", t);
  342. #endif
  343. if (t<mincost)
  344. t += codegen(codep,ply,FALSE,mincost<MAXINT?mincost-t:MAXINT,0);
  345. if (t<mincost) {
  346. mincost = t;
  347. besttup = tup;
  348. } else
  349. myfree(tup);
  350. RESTST;
  351. }
  352. FREEST;
  353. for (i=0;i<nregneeded;i++)
  354. myfree(regls[i]);
  355. if (totalcost+mincost>costlimit) {
  356. if (besttup)
  357. myfree(besttup);
  358. if (stackpad!=tokpatlen) {
  359. if (stackpad) {
  360. if (costlimit<MAXINT) {
  361. totalcost = costlimit+1;
  362. BROKE();
  363. }
  364. for (i=0;i<stackheight-stackpad;i++)
  365. fakestack[i] = fakestack[i+stackpad];
  366. stackheight -= stackpad;
  367. totalcost += stackupto(&fakestack[stackheight-1],ply,toplevel);
  368. } else
  369. totalcost += stackupto(fakestack,ply,toplevel);
  370. CHKCOST();
  371. goto nextmatch;
  372. }
  373. totalcost += mincost;
  374. BROKE();
  375. }
  376. for (i=0;i<nregneeded;i++)
  377. totalcost += docoerc(regtp[i],regcp[i],ply,toplevel,besttup->p_rar[i]);
  378. myfree(besttup);
  379. break;
  380. case DO_REMOVE:
  381. DEBUG("REMOVE");
  382. if (codep[-1]&32) {
  383. getint(texpno,codep);
  384. getint(nodeno,codep);
  385. } else {
  386. getint(texpno,codep);
  387. nodeno=0;
  388. }
  389. for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--)
  390. if (match(tp,&machsets[texpno],nodeno)) {
  391. /* investigate possible coercion to register */
  392. totalcost += stackupto(tp,ply,toplevel);
  393. CHKCOST();
  394. break;
  395. }
  396. for (rp=machregs+2;rp<machregs+NREGS;rp++)
  397. if (match(&rp->r_contents,&machsets[texpno],nodeno))
  398. rp->r_contents.t_token=0;
  399. break;
  400. case DO_RREMOVE: /* register remove */
  401. DEBUG("RREMOVE");
  402. getint(nodeno,codep);
  403. result=compute(&enodes[nodeno]);
  404. assert(result.e_typ==EV_REG);
  405. for (tp= &fakestack[stackheight-tokpatlen-1];tp>=&fakestack[0];tp--)
  406. if (tp->t_token==-1) {
  407. if(tp->t_att[0].ar==result.e_v.e_reg)
  408. goto gotone;
  409. } else {
  410. tdp = &tokens[tp->t_token];
  411. for(i=0;i<TOKENSIZE;i++)
  412. if (tdp->t_type[i]==EV_REG &&
  413. tp->t_att[i].ar==result.e_v.e_reg)
  414. goto gotone;
  415. }
  416. break;
  417. gotone:
  418. /* investigate possible coercion to register */
  419. totalcost += stackupto(tp,ply,toplevel);
  420. CHKCOST();
  421. break;
  422. case DO_DEALLOCATE:
  423. DEBUG("DEALLOCATE");
  424. getint(tinstno,codep);
  425. instance(tinstno,&token);
  426. if (token.t_token==-1)
  427. chrefcount(token.t_att[0].ar,-1,TRUE);
  428. else {
  429. tdp= &tokens[token.t_token];
  430. for (i=0;i<TOKENSIZE;i++)
  431. if (tdp->t_type[i]==EV_REG)
  432. chrefcount(token.t_att[i].ar,-1,TRUE);
  433. }
  434. break;
  435. case DO_REALLOCATE:
  436. DEBUG("REALLOCATE");
  437. for(rp=machregs;rp<machregs+NREGS;rp++)
  438. if(rp->r_tcount) {
  439. rp->r_refcount -= rp->r_tcount;
  440. rp->r_tcount = 0;
  441. }
  442. break;
  443. case DO_ALLOCATE:
  444. DEBUG("ALLOCATE");
  445. if (codep[-1]&32) {
  446. getint(propno,codep);
  447. getint(tinstno,codep);
  448. } else {
  449. getint(propno,codep);
  450. tinstno=0;
  451. }
  452. instance(tinstno,&token);
  453. if (!forced) {
  454. do {
  455. npos=exactmatch=0;
  456. for(rpp=reglist[propno];rp= *rpp; rpp++)
  457. if (getrefcount((int)(rp-machregs), FALSE)==0) {
  458. pos[npos++] = rp-machregs;
  459. if (eqtoken(&rp->r_contents,&token))
  460. exactmatch++;
  461. }
  462. /*
  463. * Now pos[] contains all free registers with desired
  464. * property. If none then some stacking has to take place.
  465. */
  466. if (npos==0) {
  467. if (stackheight<=tokpatlen) {
  468. if (!toplevel) {
  469. totalcost = INFINITY;
  470. BROKE();
  471. } else {
  472. fatal("No regs available");
  473. }
  474. }
  475. totalcost += stackupto( &fakestack[0],ply,toplevel);
  476. CHKCOST();
  477. }
  478. } while (npos==0);
  479. if (!exactmatch) {
  480. npos2=npos;
  481. for(i=0;i<npos;i++)
  482. pos2[i]=pos[i];
  483. } else {
  484. /*
  485. * Now we are reducing the number of possible registers.
  486. * We take only one equally likely register out of every
  487. * equivalence class as given by set of properties.
  488. */
  489. mtoken = token;
  490. npos2=0;
  491. for(i=0;i<npos;i++)
  492. if (eqtoken(&machregs[pos[i]].r_contents,&mtoken)) {
  493. pos2[npos2++] = pos[i];
  494. for(j=0;j<npos2-1;j++)
  495. if (eqregclass(pos2[j],pos[i])) {
  496. npos2--;
  497. break;
  498. }
  499. }
  500. }
  501. /*
  502. * Now pos2[] contains all possibilities to try, if more than
  503. * one, lookahead is necessary.
  504. */
  505. token2.t_token= -1;
  506. for (i=1;i<TOKENSIZE;i++)
  507. token2.t_att[i].aw=0;
  508. if (npos2==1)
  509. decision=pos2[0];
  510. else {
  511. SAVEST;
  512. mincost=costlimit-totalcost+1;
  513. for(j=0;j<npos2;j++) {
  514. chrefcount(pos2[j],1,FALSE);
  515. token2.t_att[0].ar=pos2[j];
  516. allreg[nallreg++] = pos2[j];
  517. if (token.t_token != 0)
  518. t=move(&token,&token2,ply,FALSE,mincost);
  519. else {
  520. t = 0;
  521. erasereg(pos2[j]);
  522. }
  523. if (t<mincost)
  524. t += codegen(codep,ply,FALSE,mincost<MAXINT?mincost-t:MAXINT,0);
  525. if (t<mincost) {
  526. mincost=t;
  527. decision=pos2[j];
  528. }
  529. RESTST;
  530. }
  531. FREEST;
  532. if (totalcost+mincost>costlimit) {
  533. totalcost = INFINITY;
  534. BROKE();
  535. }
  536. }
  537. } else {
  538. decision = forced;
  539. if (getrefcount(decision, FALSE)!=0) {
  540. totalcost = INFINITY;
  541. BROKE();
  542. }
  543. token2.t_token = -1;
  544. }
  545. chrefcount(decision,1,FALSE);
  546. token2.t_att[0].ar=decision;
  547. if (token.t_token != 0) {
  548. totalcost+=move(&token,&token2,ply,toplevel,MAXINT);
  549. CHKCOST();
  550. } else
  551. erasereg(decision);
  552. allreg[nallreg++]=decision;
  553. break;
  554. case DO_LOUTPUT:
  555. DEBUG("LOUTPUT");
  556. getint(stringno,codep);
  557. getint(nodeno,codep);
  558. if (toplevel) {
  559. gencode(codestrings[stringno]);
  560. genexpr(nodeno);
  561. }
  562. break;
  563. case DO_ROUTPUT:
  564. DEBUG("ROUTPUT");
  565. i=((codep[-1]>>5)&07);
  566. do {
  567. getint(stringno,codep);
  568. if (toplevel) {
  569. gencode(codestrings[stringno]);
  570. gennl();
  571. }
  572. } while (i--);
  573. break;
  574. case DO_MOVE:
  575. DEBUG("MOVE");
  576. getint(tinstno,codep);
  577. instance(tinstno,&token);
  578. getint(tinstno,codep);
  579. instance(tinstno,&token2);
  580. totalcost += move(&token,&token2,ply,toplevel,costlimit-totalcost+1);
  581. CHKCOST();
  582. break;
  583. case DO_ERASE:
  584. DEBUG("ERASE");
  585. getint(nodeno,codep);
  586. result=compute(&enodes[nodeno]);
  587. assert(result.e_typ==EV_REG);
  588. erasereg(result.e_v.e_reg);
  589. break;
  590. case DO_TOKREPLACE:
  591. DEBUG("TOKREPLACE");
  592. assert(stackheight>=tokpatlen);
  593. repllen=(codep[-1]>>5)&07;
  594. for(i=0;i<repllen;i++) {
  595. getint(tinstno,codep);
  596. instance(tinstno,&reptoken[i]);
  597. tref(&reptoken[i],1);
  598. }
  599. for(i=0;i<tokpatlen;i++) {
  600. if (!inscoerc)
  601. tref(&fakestack[stackheight-1],-1);
  602. stackheight--;
  603. }
  604. for (i=0;i<repllen;i++) {
  605. assert(stackheight<MAXFSTACK);
  606. fakestack[stackheight] = reptoken[i];
  607. stackheight++;
  608. /* do not combine previous two statements; that does not
  609. compile under Xenix V3.2
  610. */
  611. }
  612. for(i=0;i<nallreg;i++)
  613. chrefcount(allreg[i],-1,FALSE);
  614. break;
  615. case DO_EMREPLACE:
  616. DEBUG("EMREPLACE");
  617. emrepllen=(codep[-1]>>5)&07;
  618. j=emp-emlines;
  619. if (emrepllen>j) {
  620. int k = nemlines + emrepllen - j;
  621. assert(k<MAXEMLINES);
  622. for (i=nemlines;i>=0;i--, k--)
  623. emlines[k] = emlines[i];
  624. nemlines += emrepllen-j;
  625. emp += emrepllen-j;
  626. }
  627. emp -= emrepllen;
  628. for (i=0;i<emrepllen;i++) {
  629. getint(eminstr,codep);
  630. getint(nodeno,codep);
  631. emp[i].em_instr = eminstr;
  632. result = compute(&enodes[nodeno]);
  633. switch(result.e_typ) {
  634. default:
  635. assert(FALSE);
  636. case 0:
  637. emp[i].em_optyp = OPNO;
  638. emp[i].em_soper = 0;
  639. break;
  640. case EV_INT:
  641. emp[i].em_optyp = OPINT;
  642. emp[i].em_soper = tostring(result.e_v.e_con);
  643. emp[i].em_u.em_ioper = result.e_v.e_con;
  644. break;
  645. case EV_STR:
  646. emp[i].em_optyp = OPSYMBOL;
  647. emp[i].em_soper = result.e_v.e_str;
  648. break;
  649. }
  650. }
  651. if (!toplevel) {
  652. ply += emrepllen;
  653. }
  654. break;
  655. case DO_COST:
  656. DEBUG("COST");
  657. getint(cost.c_size,codep);
  658. getint(cost.c_time,codep);
  659. totalcost += costcalc(cost);
  660. CHKCOST();
  661. break;
  662. #ifdef REGVARS
  663. case DO_PRETURN:
  664. if (toplevel) {
  665. swtxt();
  666. regreturn(); /* in mach.c */
  667. }
  668. break;
  669. #endif
  670. case DO_RETURN:
  671. DEBUG("RETURN");
  672. assert(origcp!=startupcode);
  673. doreturn:
  674. #ifndef NDEBUG
  675. level--;
  676. #endif
  677. return(totalcost);
  678. }
  679. }
  680. }