output.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919
  1. /*
  2. * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* #define CODEDEBUG /* print readable code */
  6. #ifdef CODEDEBUG
  7. int code_in_c=0; /* put readable code in "code" */
  8. int tabledebug=1; /* generate code for table debugging */
  9. #else
  10. int code_in_c=1; /* put code in "tables.c" */
  11. int tabledebug=0; /* do not generate code for table debugging */
  12. #endif
  13. int verbose=0; /* print all statistics */
  14. int use_tes; /* use top element size information */
  15. char *c_file= "tables.c";
  16. char *h_file= "tables.H";
  17. char *cd_file= "code";
  18. #ifndef NORCSID
  19. static char rcsid[]= "$Id$";
  20. #endif
  21. #include <stdio.h>
  22. #include <ctype.h>
  23. #include "assert.h"
  24. #include "varinfo.h"
  25. #include "param.h"
  26. #include "reg.h"
  27. #include "property.h"
  28. #include "token.h"
  29. #include "set.h"
  30. #include "instruct.h"
  31. #include "lookup.h"
  32. #include <cgg_cg.h>
  33. #include "pseudo.h"
  34. #include "regvar.h"
  35. #include "extern.h"
  36. #define BMASK 0xFF
  37. #define BSHIFT 8
  38. FILE *ctable,*htable;
  39. FILE *code;
  40. short *lineset;
  41. int maxline;
  42. extern int nstrings;
  43. extern char *l_strings[];
  44. extern int ninstances;
  45. extern inst_t l_instances[];
  46. extern int nmoves;
  47. extern move_t l_moves[];
  48. extern int ntests;
  49. extern test_t l_tests[];
  50. extern int nstacks;
  51. extern c1_t l_stacks[];
  52. extern int ncoercs;
  53. extern c3_t l_coercs[];
  54. extern int nsplit,maxsplit;
  55. extern c2_t l_split[];
  56. extern set_t l_sets[];
  57. int maxallreg=0;
  58. int maxregvars=0;
  59. int setsize;
  60. opnfile(f,s) FILE **f; char *s; {
  61. if ((*f=fopen(s,"w"))==NULL)
  62. fatal("Can't create %s",s);
  63. }
  64. unlfile(f,s) FILE *f; char *s; {
  65. if (f) fclose(f);
  66. if (unlink(s)<0)
  67. error("%s incorrect, must be removed!!",s);
  68. }
  69. initio() {
  70. extern char *myalloc();
  71. opnfile(&ctable,c_file);
  72. opnfile(&htable,h_file);
  73. if (code_in_c)
  74. fprintf(ctable,"char coderules[] = {");
  75. else
  76. opnfile(&code,cd_file);
  77. patbyte(0);
  78. if (tabledebug)
  79. lineset = (short *) myalloc(SZOFSET(MAXSOURCELINES)*sizeof(short));
  80. }
  81. finishcode() {
  82. if (code_in_c)
  83. fprintf(ctable,"\n};\n\n");
  84. fprintf(ctable, "int allsetno = %d;\n", allsetno);
  85. if (tabledebug) {
  86. int fd;
  87. int sz;
  88. if ((fd=creat("lineset",0666))>=0) {
  89. sz = SZOFSET(maxline)*2;
  90. write(fd,&sz,sizeof(int));
  91. write(fd,lineset,sz);
  92. close(fd);
  93. } else
  94. error("Can't create lineset");
  95. }
  96. }
  97. errorexit() {
  98. unlfile(ctable,c_file);
  99. unlfile(htable,h_file);
  100. if (!code_in_c)
  101. unlfile(code,cd_file);
  102. }
  103. #ifdef CODEDEBUG
  104. #define code8(x) fprintf(code,"%s","x")
  105. #define code8nl(x) fprintf(code,"%s\n","x")
  106. #define code53(x,y) fprintf(code,"%s-%d","x",y)
  107. #define codeint(x) fprintf(code," %d",x)
  108. #define codenl() fprintf(code,"\n")
  109. #else
  110. #define codenl()
  111. #define code8nl(x) code8(x)
  112. code8(x) {
  113. codeindex++;
  114. if (code_in_c)
  115. fprintf(ctable,"%d,",x&0377);
  116. else
  117. putc(x,code);
  118. }
  119. code53(x,y) {
  120. code8(x+(y<<5));
  121. }
  122. codeint(x) {
  123. assert(x>=0 && x<=32767);
  124. if (x<128) {
  125. code8(x);
  126. } else {
  127. code8(x/256+128);
  128. code8(x%256);
  129. }
  130. }
  131. #endif
  132. int prevind=0;
  133. int npatbytes= -1;
  134. char pattern[MAXPATBYTES];
  135. int pathash[256];
  136. outpatterns() {
  137. extern int npatterns;
  138. extern int patindex[];
  139. extern int empatlen;
  140. extern int emmnem[];
  141. extern int empatexpr;
  142. register i;
  143. if (!inproc) {
  144. patbyte(0);
  145. patshort(prevind);
  146. prevind = npatbytes-2;
  147. patbyte(empatlen);
  148. for(i=0;i<empatlen;i++)
  149. patbyte(emmnem[i]);
  150. pat(empatexpr);
  151. }
  152. if (callproc==0) {
  153. patbyte(npatterns);
  154. for(i=0;i<npatterns;i++)
  155. pat(patindex[i]);
  156. } else {
  157. patbyte(0);
  158. pat(callproc);
  159. pat(nprocargs);
  160. for (i = 0; i < nprocargs; i++) pat(procarg[i]);
  161. }
  162. }
  163. pat(n) {
  164. assert(n>=0);
  165. if (n<128)
  166. patbyte(n);
  167. else {
  168. patbyte(n/256+128);
  169. patbyte(n%256);
  170. }
  171. }
  172. patshort(n) {
  173. patbyte(n%256);
  174. patbyte(n/256);
  175. }
  176. patbyte(n) {
  177. NEXT(npatbytes, MAXPATBYTES, "Pattern bytes");
  178. pattern[npatbytes]=n;
  179. }
  180. hashpatterns() {
  181. short index;
  182. register char *bp,*tp;
  183. register short i;
  184. unsigned short hashvalue;
  185. int patlen;
  186. index = prevind;
  187. while (index != 0) {
  188. bp = &pattern[index];
  189. tp = &bp[PO_MATCH];
  190. i = *tp++&BMASK;
  191. if (i==BMASK) {
  192. i = *tp++&BMASK;
  193. i |= (*tp++&BMASK)<<BSHIFT;
  194. }
  195. patlen = i;
  196. hashvalue = 0;
  197. switch(patlen) {
  198. default: /* 3 or more */
  199. hashvalue = (hashvalue<<4)^(*tp++&BMASK);
  200. case 2:
  201. hashvalue = (hashvalue<<4)^(*tp++&BMASK);
  202. case 1:
  203. hashvalue = (hashvalue<<4)^(*tp++&BMASK);
  204. }
  205. assert(hashvalue!= ILLHASH);
  206. i=index;
  207. index = (bp[PO_NEXT]&BMASK)|(bp[PO_NEXT+1]<<BSHIFT);
  208. bp[PO_HASH] = hashvalue>>BSHIFT;
  209. hashvalue &= BMASK;
  210. bp[PO_NEXT] = pathash[hashvalue]&BMASK;
  211. bp[PO_NEXT+1] = pathash[hashvalue]>>BSHIFT;
  212. pathash[hashvalue] = i;
  213. }
  214. }
  215. outincludes() {
  216. fprintf(ctable,"#include \"param.h\"\n");
  217. fprintf(ctable,"#include \"tables.h\"\n");
  218. fprintf(ctable,"#include \"types.h\"\n");
  219. fprintf(ctable,"#include <cgg_cg.h>\n");
  220. fprintf(ctable,"#include \"data.h\"\n");
  221. }
  222. outregs() {
  223. register i,j,k;
  224. short rset[SZOFSET(MAXREGS)];
  225. short clashlist[MAXREGS*MAXREGS];
  226. int iclashlist = 0;
  227. int t,ready;
  228. fprintf(ctable,"char stregclass[] = {\n");
  229. for (i=0;i<nregs;i++)
  230. fprintf(ctable,"\t%d,\n",l_regs[i].ri_class);
  231. fprintf(ctable,"};\n\nstruct reginfo machregs[] = {\n{0},\n");
  232. for (i=1;i<nregs;i++) {
  233. fprintf(ctable,"{%d,%d",strlookup(l_regs[i].ri_repr),
  234. l_regs[i].ri_size);
  235. if (maxmembers!=0) {
  236. fprintf(ctable,",{");
  237. for(j=0;j<maxmembers;j++)
  238. fprintf(ctable,"%d,",l_regs[i].ri_memb[j]);
  239. /* now compute and print set of registers
  240. * that clashes with this register.
  241. * A register clashes with al its children (and theirs)
  242. * and with all their parents.
  243. */
  244. for (j=0;j<SZOFSET(MAXREGS);j++)
  245. rset[j]=0;
  246. BIS(rset,i);
  247. do {
  248. ready=1;
  249. for (j=1;j<nregs;j++)
  250. if (BIT(rset,j))
  251. for (k=0;k<2;k++)
  252. if ((t=l_regs[j].ri_memb[k])!=0) {
  253. if (BIT(rset,t)==0)
  254. ready=0;
  255. BIS(rset,t);
  256. }
  257. } while (!ready);
  258. do {
  259. ready=1;
  260. for (j=1;j<nregs;j++)
  261. for (k=0;k<2;k++)
  262. if ((t=l_regs[j].ri_memb[k])!=0)
  263. if (BIT(rset,t)) {
  264. if (BIT(rset,j)==0)
  265. ready=0;
  266. BIS(rset,j);
  267. }
  268. } while (!ready);
  269. fprintf(ctable,"},{");
  270. for (j=0;j<SZOFSET(nregs);j++)
  271. fprintf(ctable,"0%o,",rset[j]&0xFFFF);
  272. fprintf(ctable,"}, %d", iclashlist);
  273. for (j = 1; j < nregs; j++) {
  274. if (BIT(rset, j)) clashlist[iclashlist++] = j;
  275. }
  276. clashlist[iclashlist++] = 0;
  277. }
  278. fprintf(ctable,",%d",l_regs[i].ri_rregvar>=0);
  279. fprintf(ctable,"},\n");
  280. }
  281. fprintf(ctable,"};\n\n short clashlist[] = {\n\t");
  282. for (i = 0; i < iclashlist; i++) {
  283. fprintf(ctable, "%d, ", clashlist[i]);
  284. if (clashlist[i] == 0) fprintf(ctable, "\n\t");
  285. }
  286. fprintf(ctable, "0};\n\n");
  287. }
  288. outregvars() {
  289. register i,j;
  290. fprintf(htable,"#define REGVARS\n");
  291. fprintf(ctable,"#include \"regvar.h\"\n");
  292. fprintf(ctable,"int nregvar[4] = { ");
  293. for (i=0;i<4;i++) {
  294. fprintf(ctable,"%d, ",nregvar[i]);
  295. if (nregvar[i]>maxregvars)
  296. maxregvars = nregvar[i];
  297. }
  298. fprintf(ctable,"};\n");
  299. for (i=0;i<4;i++)
  300. if (nregvar[i]>0)
  301. fprintf(ctable,"struct regassigned ratar%d[%d];\n",
  302. i,nregvar[i]);
  303. for (i=0;i<4;i++) if (nregvar[i]>0) {
  304. fprintf(ctable,"int rvtar%d[] = {",i);
  305. for (j=0;j<nregvar[i];j++)
  306. fprintf(ctable,"%d,",rvnumbers[i][j]);
  307. fprintf(ctable,"};\n");
  308. }
  309. fprintf(ctable,"\nint *rvnumbers[] = {\n");
  310. for (i=0;i<4;i++)
  311. if (nregvar[i]>0)
  312. fprintf(ctable,"\trvtar%d,\n",i);
  313. else
  314. fprintf(ctable,"\t0,\n");
  315. fprintf(ctable,"};\n\nstruct regassigned *regassigned[] = {\n");
  316. for (i=0;i<4;i++)
  317. if (nregvar[i]>0)
  318. fprintf(ctable,"\tratar%d,\n",i);
  319. else
  320. fprintf(ctable,"\t0,\n");
  321. fprintf(ctable,"};\n");
  322. }
  323. typeconv(n) {
  324. if (n>=0) return(2);
  325. if (n== -1) return(1);
  326. if (n== -2) return(3);
  327. assert (n== -3);
  328. return(0);
  329. }
  330. outfmt(p)
  331. register char *p;
  332. {
  333. register int c;
  334. fprintf(ctable,"\"");
  335. while ((c= (*p++&0377))!=0) {
  336. if (! isascii(c) || iscntrl(c)) {
  337. fprintf(ctable,"\\%c%c%c",
  338. ((c&~0300)>>6) + '0', ((c&070)>>3)+'0',
  339. (c&07)+'0');
  340. }
  341. else fprintf(ctable, "%c",c);
  342. }
  343. fprintf(ctable,"\"");
  344. }
  345. outtokens() {
  346. register tokno,i;
  347. register token_p tp;
  348. fprintf(ctable,"tkdef_t tokens[] = {{0},\n");
  349. for (tokno=1;tokno<ntokens;tokno++) {
  350. tp = l_tokens[tokno];
  351. fprintf(ctable,"/* %3d */{%d,{%d,%d},{", tokno,
  352. tp->tk_size, tp->tk_cost.ct_space, tp->tk_cost.ct_time);
  353. for(i=0;i<maxtokensize;i++)
  354. fprintf(ctable,"%d,",typeconv(tp->tk_att[i].ta_type));
  355. fprintf(ctable,"},%d},\t/* ",tp->tk_format);
  356. if (tp->tk_format >= 0) outfmt(l_strings[tp->tk_format]);
  357. else fprintf(ctable, "(no format)");
  358. fprintf(ctable," */\n");
  359. }
  360. fprintf(ctable,"{0}};\n\n");
  361. }
  362. outenodes() {
  363. register node_p np;
  364. extern node_t nodes[];
  365. extern int nnodes;
  366. fprintf(ctable,"node_t enodes[] = {\n");
  367. for (np=nodes;np<&nodes[nnodes];np++)
  368. fprintf(ctable,"{%d,%d,%d},\n",
  369. np->ex_operator,np->ex_lnode,np->ex_rnode);
  370. fprintf(ctable,"};\n\n");
  371. }
  372. outstrings() {
  373. register i;
  374. register char *p;
  375. register int c;
  376. extern char * filename;
  377. if (tabledebug)
  378. fprintf(ctable,"char *tablename = \"%s\";\n",filename);
  379. fprintf(ctable,"string codestrings[] = {\n");
  380. for(i=0;i<nstrings;i++) {
  381. fprintf(ctable,"\t");
  382. outfmt(l_strings[i]);
  383. #if 0
  384. while ((c= (*p++&0377))!=0) {
  385. if (! isascii(c) || iscntrl(c)) {
  386. fprintf(ctable,"\\%c%c%c",
  387. ((c&~0300)>>6) + '0', ((c&070)>>3)+'0',
  388. (c&07)+'0');
  389. }
  390. else fprintf(ctable, "%c",c);
  391. }
  392. fprintf(ctable,"\",\n");
  393. #endif
  394. fprintf(ctable,",\n");
  395. }
  396. fprintf(ctable,"};\n\n");
  397. }
  398. extern set_t unstackset;
  399. outsets() {
  400. register i;
  401. register set_p sp;
  402. fprintf(ctable,"set_t machsets[] = {\n");
  403. for (sp=l_sets;sp< &l_sets[nsets]; sp++) {
  404. fprintf(ctable,"/* %3ld */ {%3d,{",(long)(sp-l_sets),sp->set_size);
  405. for (i=0;i<setsize;i++)
  406. fprintf(ctable,"0x%x,",sp->set_val[i]&0xFFFF);
  407. fprintf(ctable,"}},\n");
  408. }
  409. fprintf(ctable,"};\n\n");
  410. fprintf(ctable, "set_t unstackset = { %3d,{\n", unstackset.set_size);
  411. for (i = 0; i<setsize;i++)
  412. fprintf(ctable,"0x%x,",unstackset.set_val[i]&0xFFFF);
  413. fprintf(ctable,"}};\n\n");
  414. }
  415. outinstances() {
  416. register inst_p ip;
  417. register i;
  418. fprintf(ctable,"inst_t tokeninstances[] = {\n");
  419. for (ip=l_instances;ip< &l_instances[ninstances]; ip++) {
  420. fprintf(ctable,"{ %d, {",ip->in_which);
  421. for(i=0;i<=maxtokensize;i++)
  422. fprintf(ctable,"%d,",ip->in_info[i]);
  423. fprintf(ctable,"}},\n");
  424. }
  425. fprintf(ctable,"};\n\n");
  426. }
  427. outmoves() {
  428. register move_p mp;
  429. fprintf(ctable,"move_t moves[] = {\n");
  430. for (mp=l_moves; mp< &l_moves[nmoves]; mp++)
  431. fprintf(ctable,"{%d,%d,%d,%d,%d},\n",
  432. mp->m_set1, mp->m_expr1,
  433. mp->m_set2, mp->m_expr2,
  434. mp->m_cindex);
  435. fprintf(ctable,"{-1}\n};\n\n");
  436. }
  437. outtests() {
  438. register test_p tp;
  439. fprintf(ctable,"test_t tests[] = {\n");
  440. for (tp=l_tests; tp< &l_tests[ntests]; tp++)
  441. fprintf(ctable,"{%d,%d,%d},\n",
  442. tp->t_set, tp->t_expr,
  443. tp->t_cindex);
  444. fprintf(ctable,"{-1}\n};\n\n");
  445. }
  446. outstacks() {
  447. register c1_p cp;
  448. fprintf(ctable,"c1_t c1coercs[] = {\n");
  449. for (cp=l_stacks; cp< &l_stacks[nstacks]; cp++)
  450. fprintf(ctable,"{%d,%d,%d,%d},\n",
  451. cp->c1_texpno, cp->c1_expr,
  452. cp->c1_prop, cp->c1_codep);
  453. fprintf(ctable,"{-1}\n};\n\n");
  454. }
  455. outsplits() {
  456. register c2_p cp;
  457. register i;
  458. fprintf(ctable,"c2_t c2coercs[] = {\n");
  459. for (cp=l_split; cp< &l_split[nsplit]; cp++) {
  460. fprintf(ctable,"{%d,%d,%d,{",
  461. cp->c2_texpno, cp->c2_expr, cp->c2_nsplit);
  462. for (i=0;i<maxsplit;i++)
  463. fprintf(ctable,"%d,",cp->c2_repl[i]);
  464. fprintf(ctable,"},%d},\n",cp->c2_codep);
  465. }
  466. fprintf(ctable,"{-1}\n};\n\n");
  467. }
  468. outcoercs() {
  469. register c3_p cp;
  470. fprintf(ctable,"c3_t c3coercs[] = {\n");
  471. for (cp=l_coercs; cp< &l_coercs[ncoercs]; cp++)
  472. fprintf(ctable,"{%d,%d,%d,%d,%d},\n",
  473. cp->c3_texpno, cp->c3_expr,
  474. cp->c3_prop, cp->c3_repl, cp->c3_codep);
  475. fprintf(ctable,"{-1}\n};\n\n");
  476. }
  477. outproplists() {
  478. register propno;
  479. register regno;
  480. for(propno=0;propno<nprops;propno++) {
  481. fprintf(ctable,"struct reginfo *rlist%d[] = {\n",propno);
  482. for(regno=1;regno<nregs;regno++)
  483. if (BIT(l_props[propno].pr_regset,regno))
  484. fprintf(ctable,"&machregs[%d],\n",regno);
  485. fprintf(ctable,"0\n};\n");
  486. }
  487. fprintf(ctable,"struct reginfo **reglist[] = {\n");
  488. for(propno=0;propno<nprops;propno++)
  489. fprintf(ctable,"rlist%d,\n",propno);
  490. fprintf(ctable,"};\n\n");
  491. }
  492. outconsts() {
  493. fprintf(ctable,"unsigned cc1 = %u;\n",fc1);
  494. fprintf(ctable,"unsigned cc2 = %u;\n",fc2);
  495. fprintf(ctable,"unsigned cc3 = %u;\n",fc3);
  496. fprintf(ctable,"unsigned cc4 = %u;\n",fc4);
  497. }
  498. cdef(s,n) char *s; {
  499. fprintf(htable,"#define %s %d\n",s,n);
  500. }
  501. passon(s) char *s; {
  502. char buf[32];
  503. sprintf(buf,"T%s",s);
  504. cdef(buf,cmustbeset(s));
  505. }
  506. outdefs() {
  507. register symbol *sy_p;
  508. extern int maxempatlen,maxrule;
  509. char *wrdfmt;
  510. passon("EM_WSIZE");
  511. passon("EM_PSIZE");
  512. passon("EM_BSIZE");
  513. if ((sy_p=lookup("FORMAT",symsconst,justlooking))!=0) {
  514. wrdfmt = l_strings[sy_p->sy_value.syv_stringno];
  515. fprintf(htable,"#define WRD_FMT \"%s\"\n",wrdfmt);
  516. }
  517. cdef("MAXALLREG",maxallreg);
  518. cdef("SETSIZE",setsize);
  519. cdef("NREGS",nregs);
  520. cdef("REGSETSIZE",SZOFSET(nregs));
  521. cdef("TOKENSIZE",maxtokensize);
  522. cdef("MAXMEMBERS",maxmembers);
  523. cdef("LONGESTPATTERN",maxempatlen);
  524. cdef("MAXPATLEN",maxtokpatlen);
  525. cdef("MAXREPLLEN",maxtokrepllen);
  526. cdef("MAXEMREPLLEN",maxemrepllen);
  527. cdef("MAXPROCARG",maxprocargs);
  528. cdef("MAXRULE",maxrule<16 ? 16 : maxrule);
  529. if (nsplit>0) {
  530. cdef("MAXSPLIT",maxsplit);
  531. }
  532. if (tabledebug)
  533. cdef("TABLEDEBUG",1);
  534. if (use_tes)
  535. cdef("USE_TES",1);
  536. }
  537. outars() {
  538. register i;
  539. if (code_in_c)
  540. fprintf(htable,"#define CODEINC 1\n");
  541. else {
  542. fprintf(ctable,"char coderules[%d];\n",codeindex);
  543. fprintf(ctable,"int ncodebytes=%d;\n",codeindex);
  544. }
  545. fprintf(ctable,"char pattern[%d]={\n",npatbytes+1);
  546. for(i=0;i<=npatbytes;i++) {
  547. fprintf(ctable,"%d,%c",pattern[i]&BMASK,i%16==15 ? '\n' : ' ');
  548. }
  549. fprintf(ctable,"};\n\n");
  550. fprintf(ctable,"int pathash[256]={\n");
  551. for(i=0;i<256;i++) {
  552. fprintf(ctable,"%d,%c",pathash[i]&0xFFFF,i%10==9 ? '\n' : ' ');
  553. }
  554. fprintf(ctable,"};\n");
  555. }
  556. finishio() {
  557. extern int nregs;
  558. finishcode();
  559. hashpatterns();
  560. setsize = SZOFSET(nregs+ntokens);
  561. outdefs();
  562. outincludes();
  563. outregs();
  564. outtokens();
  565. outenodes();
  566. outstrings();
  567. outsets();
  568. outinstances();
  569. outmoves();
  570. outtests();
  571. outstacks();
  572. if (nsplit>0)
  573. outsplits();
  574. outcoercs();
  575. outproplists();
  576. outconsts();
  577. if (rvused)
  578. outregvars();
  579. outars();
  580. }
  581. codecoco(cocono) {
  582. if (cocono== -1)
  583. return;
  584. code8(DO_SETCC);
  585. codeint(cocono);
  586. codenl();
  587. }
  588. dopattern(stackcoerc,kills,allocates,generates,yields,leaving)
  589. varinfo *kills,*allocates,*generates,*yields,*leaving;
  590. {
  591. register i;
  592. int n,nops;
  593. register struct varinfo *vp,*vivp;
  594. register instr_p instp;
  595. int al,deal;
  596. int vil;
  597. int cocono= -1;
  598. cost_t totcost;
  599. int nremoves;
  600. int removelist[100];
  601. static char tlab[] = "0:";
  602. extern int optexact,optstack,startline;
  603. extern char *filename;
  604. extern int lineno;
  605. #ifdef CODEDEBUG
  606. fprintf(code,"Code(%d) at \"%s\", line %d\n",stackcoerc,filename,lineno);
  607. #endif
  608. if (code_in_c)
  609. fprintf(ctable,"\n/* \"%s\", line %d */ ",filename,lineno);
  610. if (tabledebug) {
  611. code8(DO_DLINE);
  612. codeint(startline);
  613. codenl();
  614. if (startline<MAXSOURCELINES) {
  615. if (startline>maxline)
  616. maxline=startline;
  617. BIS(lineset,startline);
  618. } else {
  619. static int beenhere=0;
  620. if (!beenhere) {
  621. beenhere++;
  622. error("Too many source lines for table debug");
  623. }
  624. }
  625. }
  626. /* MATCH part */
  627. if (tokpatlen) {
  628. if (optexact)
  629. if (optstack)
  630. code53(DO_XXMATCH,tokpatlen);
  631. else
  632. code53(DO_XMATCH,tokpatlen);
  633. else
  634. code53(DO_MATCH,tokpatlen);
  635. for (i=0;i<tokpatlen;i++)
  636. codeint(tokpatset[i]);
  637. codenl();
  638. } else if (stackcoerc)
  639. code8nl(DO_COERC);
  640. if (optstack) {
  641. code53(DO_TOSTACK,0);
  642. codeint(allsetno);
  643. codenl();
  644. }
  645. /* The kills */
  646. for (vp=kills;vp!=0;vp=vp->vi_next) {
  647. if (vp->vi_int[1] != 0) {
  648. code53(DO_REMOVE,1);
  649. codeint(vp->vi_int[0]);
  650. codeint(vp->vi_int[1]);
  651. } else if (vp->vi_int[0] >= 0) {
  652. code53(DO_REMOVE,0);
  653. codeint(vp->vi_int[0]);
  654. } else {
  655. code8(DO_KILLREG);
  656. codeint(-vp->vi_int[0] - 1);
  657. }
  658. codenl();
  659. }
  660. nremoves=0;
  661. for(vp=generates;vp!=0;vp=vp->vi_next) {
  662. if (vp->vi_int[0] != INSREMOVE)
  663. continue;
  664. for(i=0;i<nremoves;i++)
  665. if (vp->vi_int[1]==removelist[i])
  666. break;
  667. if (i==nremoves) {
  668. assert(nremoves<(sizeof(removelist)/sizeof(int)));
  669. removelist[nremoves++] = vp->vi_int[1];
  670. }
  671. }
  672. for(i=0;i<nremoves;i++) {
  673. code8(DO_RREMOVE);
  674. codeint(removelist[i]);
  675. codenl();
  676. }
  677. /* allocate part */
  678. deal=0;al=0;
  679. for (vp=allocates;vp!=0;vp=vp->vi_next) {
  680. if (vp->vi_int[0] == -1) { /* Deallocate */
  681. deal++;
  682. code8(DO_DEALLOCATE);
  683. codeint(vp->vi_int[1]);
  684. codenl();
  685. } else {
  686. if (vp->vi_int[1]==0) {
  687. code53(DO_ALLOCATE,0);
  688. codeint(vp->vi_int[0]);
  689. codenl();
  690. } else {
  691. code53(DO_ALLOCATE,1);
  692. codeint(vp->vi_int[0]);
  693. codeint(vp->vi_int[1]);
  694. codenl();
  695. }
  696. al++;
  697. }
  698. }
  699. if (deal)
  700. code8nl(DO_REALLOCATE);
  701. if (al>maxallreg)
  702. maxallreg=al;
  703. totcost.ct_space = 0;
  704. totcost.ct_time = 0;
  705. for(vp=generates;vp!=0;vp=vp->vi_next) {
  706. n= vp->vi_int[0];
  707. switch(n) {
  708. default:
  709. assert(n>=0);
  710. instp = &l_instr[n];
  711. nops=instp->i_nops;
  712. code53(DO_INSTR,nops);
  713. if (vp->vi_int[1]==0) {
  714. codeint(instp->i_asname);
  715. } else {
  716. codeint(10000+vp->vi_int[1]);
  717. }
  718. vivp=vp->vi_vi;
  719. for(i=0;i<nops;i++) {
  720. codeint(vivp->vi_int[0]);
  721. vivp = vivp->vi_vi;
  722. }
  723. codenl();
  724. totcost.ct_space += instp->i_cost.ct_space;
  725. totcost.ct_time += instp->i_cost.ct_time ;
  726. break;
  727. case INSREMOVE:
  728. break;
  729. case INSMOVE:
  730. codecoco(cocono);
  731. code8(DO_MOVE);
  732. codeint(vp->vi_int[1]);
  733. codeint(vp->vi_int[2]);
  734. codenl();
  735. break;
  736. case INSTEST:
  737. codecoco(cocono);
  738. code8(DO_TEST);
  739. codeint(vp->vi_int[1]);
  740. codenl();
  741. break;
  742. case INSPRETURN:
  743. code8(DO_PRETURN);
  744. codenl();
  745. break;
  746. case INSTLAB:
  747. cocono = 0;
  748. tlab[0] = vp->vi_int[1] + '0';
  749. code53(DO_INSTR,0);
  750. codeint(strlookup(tlab));
  751. codenl();
  752. break;
  753. case INSSETCC:
  754. cocono=vp->vi_int[1];
  755. break;
  756. case INSERASE:
  757. code8(DO_ERASE);
  758. codeint(vp->vi_int[1]);
  759. codenl();
  760. break;
  761. case INSLABDEF:
  762. cocono = 0;
  763. code8(DO_LABDEF);
  764. codeint(vp->vi_int[1]);
  765. codenl();
  766. break;
  767. }
  768. }
  769. codecoco(cocono);
  770. vil = vilength(yields);
  771. if (vil!=0 || tokpatlen!=0 || allocates!=0) {
  772. code53(DO_TOKREPLACE,vilength(yields));
  773. for(vp=yields;vp!=0;vp=vp->vi_next) {
  774. codeint(vp->vi_int[0]);
  775. }
  776. codenl();
  777. }
  778. if (leaving!=0) {
  779. code53(DO_EMREPLACE,vilength(leaving));
  780. while (leaving!=0) {
  781. codeint(leaving->vi_int[0]);
  782. codeint(leaving->vi_int[1]);
  783. leaving = leaving->vi_next;
  784. }
  785. codenl();
  786. }
  787. if (totcost.ct_space!=0 || totcost.ct_time!=0) {
  788. code8(DO_COST);
  789. codeint(totcost.ct_space);
  790. codeint(totcost.ct_time);
  791. codenl();
  792. }
  793. if (empatlen==0 && !inproc)
  794. code8nl(DO_RETURN);
  795. else
  796. code8nl(DO_NEXTEM);
  797. }
  798. used(resource,use,max) char *resource; {
  799. if (verbose || 4*use > 3*max)
  800. fprintf(stderr,"%s %d(%d)\n",resource,use,max);
  801. }
  802. statistics() {
  803. extern char *beg_sbrk,*sbrk();
  804. extern int nnodes, maxempatlen,maxrule;
  805. used("Registers",nregs,MAXREGS);
  806. used("Properties",nprops,MAXPROPS);
  807. used("Tokens",ntokens,MAXTOKENS);
  808. used("Tokensize",maxtokensize,MAXATT);
  809. used("Sets",nsets,MAXSETS);
  810. used("Instructions",ninstr,MAXINSTR);
  811. used("Strings",nstrings,MAXSTRINGS);
  812. used("Exp-nodes",nnodes,MAXNODES);
  813. used("EM-pat length",maxempatlen,EMPATMAX);
  814. used("rules/EM-pattern",maxrule,MAXPATTERNS);
  815. used("Allocates/rule",maxallreg,MAXALLREG);
  816. used("Instances",ninstances,MAXINSTANCES);
  817. used("Moves",nmoves,MAXMOVES);
  818. used("Tests",ntests,MAXTESTS);
  819. used("Stacks",nstacks,MAXSTACKS);
  820. used("1->1 Coercions",ncoercs,MAXCOERCS);
  821. used("Splitting coercions",nsplit,MAXSPLCOERC);
  822. used("Register variables",maxregvars,MAXREGVAR);
  823. used("Pat bytes",npatbytes+1,MAXPATBYTES);
  824. if (tabledebug)
  825. used("Source lines",maxline,MAXSOURCELINES);
  826. fprintf(stderr,"%ldK heap used\n",((long) (sbrk(0)-beg_sbrk+1023))/1024);
  827. }