home *** CD-ROM | disk | FTP | other *** search
/ Dream 48 / Amiga_Dream_48.iso / Atari / c / sozobon-v2 / scsrc20.lzh / HCC.LZH / OUT_ST.C < prev    next >
C/C++ Source or Header  |  1991-02-22  |  14KB  |  841 lines

  1. /* Copyright (c) 1988,1991 by Sozobon, Limited.  Author: Johann Ruegg
  2.  *
  3.  * Permission is granted to anyone to use this software for any purpose
  4.  * on any computer system, and to redistribute it freely, with the
  5.  * following restrictions:
  6.  * 1) No charge may be made other than reasonable charges for reproduction.
  7.  * 2) Modified versions must be clearly marked as such.
  8.  * 3) The authors are not responsible for any harmful consequences
  9.  *    of using this software, even if they result from defects in it.
  10.  *
  11.  *    out.c
  12.  *
  13.  *    Code generation output routines.
  14.  */
  15.  
  16. #include <stdio.h>
  17. #include "param.h"
  18. #include "nodes.h"
  19. #include "flags.h"
  20. #include "bstok.h"
  21. #include "tytok.h"
  22. #include "gen.h"
  23.  
  24. #if dLibs
  25. #include <ctype.h>
  26. #endif
  27.  
  28. #if MMCC
  29. overlay "pass2"
  30. #endif
  31.  
  32. #if CC68
  33. FILE *fopen();
  34. #endif
  35.  
  36. #if NEEDBUF
  37. char my_obuf[BUFSIZ];
  38. #endif
  39.  
  40. #define T_SEG    0
  41. #define D_SEG    1
  42. #define B_SEG    2
  43.  
  44. #define TO_TEXT    to_seg(T_SEG)
  45. #define TO_DATA    to_seg(D_SEG)
  46. #define TO_BSS    to_seg(B_SEG)
  47.  
  48. #define isareg(np)    ((np)->g_token == REGVAR && (np)->g_rno >= AREG)
  49.  
  50. extern FILE *output;
  51.  
  52. static int in_seg;
  53. static int lblnum;
  54. static int dat_size;
  55.  
  56. out_start(outs)
  57. char *outs;
  58. {
  59.     register int len;
  60.     char suff;
  61.     extern char tmpdir[];
  62.     char oname[128];
  63.  
  64.     len = strlen(outs);
  65.     if (len >= 2 && outs[len-2] == '.') {
  66.         suff = outs[len-1];
  67.         if (suff != 'c' && suff != 'C')
  68.             fatals("Invalid suffix", outs);
  69. #if defined(MINIX) || defined(UNIX)
  70.         sprintf(oname, "%s/%s", tmpdir, outs);
  71. #else
  72.         sprintf(oname, "%s\\%s", tmpdir, outs);
  73. #endif
  74.         len = strlen(oname);
  75.  
  76.         oname[len-1] = 's';
  77.         output = fopen(oname, "w");
  78.         if (output == NULL)
  79.             fatals("Cant open", oname);
  80. #if NEEDBUF
  81.         setbuf(output, my_obuf);
  82. #endif
  83.     } else
  84.         output = stdout;
  85.  
  86.     in_seg = -1;
  87.     lblnum = 0;
  88.     dat_size = 0;
  89. }
  90.  
  91. out_end()
  92. {
  93.     if (output != stdout)
  94.         fclose(output);
  95. }
  96.  
  97. static char *sg_go[] = {
  98.     ".text",
  99.     ".data",
  100.     ".bss"
  101. };
  102.  
  103. to_text()
  104. {
  105.     TO_TEXT;
  106. }
  107.  
  108. to_seg(sg)
  109. {
  110.     if (sg == in_seg)
  111.         return;
  112.     fprintf(output, "\t%s\n", sg_go[sg]);
  113.     in_seg = sg;
  114. }
  115.  
  116. o_aln(x)
  117. {
  118.     if (x && (dat_size & 1)) {
  119.         dat_size++;
  120.         TO_DATA;
  121.         fprintf(output, "\t.even\n");
  122.     }
  123. }
  124.  
  125. char *rnms[] = {
  126.     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  127.     "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",
  128. };
  129.  
  130. char *regnm(n)
  131. {
  132.     return rnms[n];
  133. }
  134.  
  135. #define regnm(x)    rnms[x]
  136.  
  137. char *
  138. init_str(n)
  139. {
  140.     char *s;
  141.  
  142.     switch (n) {
  143.     case 1:
  144.         s = ".dc.b";    break;
  145.     case 2:
  146.         s = ".dc.w";    break;
  147.     default:
  148.         s = ".dc.l";    break;
  149.     }
  150.     return s;
  151. }
  152.  
  153. tlen(n)
  154. {
  155.     switch (n) {
  156.     case 1:
  157.         return 'b';
  158.     case 2:
  159.         return 'w';
  160.     default:
  161.         return 'l';
  162.     }
  163. }
  164.  
  165. out_fi(val)
  166. {
  167.     fprintf(output, "\t.dc.w\t$%x\n", val);
  168. }
  169.  
  170. o_vinit(tp, xp)
  171. NODEP tp, xp;
  172. {
  173.     fprintf(output, "\t%s\t", init_str((int)tp->t_size));
  174.     dat_size += tp->t_size;
  175.  
  176.     p2_expr(&xp);
  177.     asn_chk(tp, xp);
  178.     to_init(xp, tp);
  179.  
  180.     fputc('\n', output);
  181. }
  182.  
  183. to_init(np, typ)
  184. NODEP np, typ;
  185. {
  186.     NODEP tp;
  187.  
  188.     tp = allocnode();
  189.     tp->e_token = TCONV;
  190.     tp->n_tptr = typ;
  191.     tp->n_flags |= N_COPYT;
  192.     tp->n_left = np;
  193.     tp->e_type = E_UNARY;
  194.     strcpy(tp->n_name, "i cast");
  195.  
  196.     genx(tp, FORINIT);
  197. }
  198.  
  199. out_advice(np)
  200. NODEP np;
  201. {
  202.     long size;
  203.  
  204.     size = np->n_tptr->t_size;
  205.     if (size == 0)
  206.         return;
  207.  
  208.     switch (np->e_sc) {
  209.     case K_AUTO:
  210.         fprintf(output, ";var\t%d\t%d\t", (int)size,
  211.             (int)np->e_offs);
  212.         break;
  213.     case K_REGISTER:
  214.         fprintf(output, ";reg\t%d\t%s\t", (int)size,
  215.             regnm(np->e_rno));
  216.         break;
  217.     default:
  218.         return;
  219.     }
  220.     out_nm(np);
  221.     fputc('\n', output);
  222. }
  223.  
  224. out_argreg(np)
  225. NODEP np;
  226. {
  227.     fprintf(output, "\tmove.%c\t%d(%s),%s\n",
  228.         tlen((int)np->n_tptr->t_size), (int)np->e_offs,
  229.         regnm(FRAMEP), regnm(np->e_rno));
  230. }
  231.  
  232. out_fstart(np)
  233. NODEP np;
  234. {
  235.     extern    int    pflag;
  236.  
  237.     TO_TEXT;
  238.     if (np->e_sc != K_STATIC) {
  239.         fprintf(output, "\t.globl\t");
  240.         und_nnm(np);
  241.         fputc('\n', output);
  242.     }
  243.     und_nnm(np);
  244.     fprintf(output, ":\n");    
  245.  
  246.     if (pflag) {
  247.         int    tlab = new_lbl();
  248.  
  249.         TO_BSS;
  250.         fprintf(output, "L%d:\t.ds.l\t1\n", tlab);
  251.         TO_TEXT;
  252.         fprintf(output, "\tmove.l\t#");
  253.         und_nnm(np);
  254.         fprintf(output, ",a0\n");
  255.  
  256.         fprintf(output, "\tmove.l\t#L%d,a1\n", tlab);
  257.         fprintf(output,    "\tjsr\tmcount\n");
  258.     }
  259. }
  260.  
  261. static char rbuf[30];
  262.  
  263. char *
  264. regstr(regs)
  265. {
  266.     int lod, hid, loa, hia;
  267.     register i;
  268.     char *bp = rbuf;
  269.  
  270.     lod = 999;
  271.     hid = -1;
  272.     for (i=DRV_START; i<=DRV_END; i++)
  273.         if (regs & (1<<i)) {
  274.             if (i < lod)  lod = i;
  275.             if (i > hid)  hid = i;
  276.         }
  277.     loa = 999;
  278.     hia = -1;
  279.     for (i=ARV_START; i<=ARV_END; i++)
  280.         if (regs & (1<<i)) {
  281.             if (i < loa)  loa = i;
  282.             if (i > hia)  hia = i;
  283.         }
  284.     if (lod < 999) {
  285.         if (lod != hid)
  286.             sprintf(bp, "%s-%s", rnms[lod], rnms[hid]);
  287.         else
  288.             sprintf(bp, "%s", rnms[lod]);
  289.         if (loa < 999) {
  290.             bp += strlen(rbuf);
  291.             *bp++ = '/';
  292.         }
  293.     }
  294.     if (loa < 999) {
  295.         if (loa != hia)
  296.             sprintf(bp, "%s-%s", rnms[loa], rnms[hia]);
  297.         else
  298.             sprintf(bp, "%s", rnms[loa]);
  299.     }
  300.     return rbuf;
  301. }
  302.  
  303. out_fend(regs, lsize)
  304. long lsize;
  305. {
  306.     if (lsize < 0x7fff)
  307.         fprintf(output, "\tlink\t%s,#-%d\n", rnms[FRAMEP], (int)lsize);
  308.     else
  309.         fprintf(output, "\tlink\t%s,#0\n\tsub.l\t#%ld,sp\n",
  310.             rnms[FRAMEP], lsize);
  311.     if (regs)
  312.         fprintf(output, "\tmovem.l\t%s,-(sp)\n", regstr(regs));
  313. }
  314.  
  315. out_fret(regs, strl)
  316. {
  317.     if (regs)
  318.         fprintf(output, "\tmovem.l\t(sp)+,%s\n", regstr(regs));
  319.     if (strl)
  320.         fprintf(output, "\tmove.l\t#L%d,a0\n", strl);
  321.     fprintf(output, "\tunlk\t%s\n\trts\n", rnms[FRAMEP]);
  322. }
  323.  
  324. out_fs(strl, size)
  325. long size;
  326. {
  327.     TO_BSS;
  328.     def_lbl(strl);
  329.     if (size & 1)
  330.         fprintf(output, "\t.ds.b\t%ld\n", size);
  331.     else
  332.         fprintf(output, "\t.ds.w\t%ld\n", size/2);
  333. }
  334.  
  335. out_gv(np, isbss)
  336. register NODEP np;
  337. {
  338.     long sz;
  339.     char c;
  340.  
  341.     if (np->e_sc == K_STATIC) {
  342.         np->e_offs = lblnum++;
  343.     }
  344.     if (np->e_sc != K_EXTERN) {
  345.         to_seg(isbss ? B_SEG : D_SEG);
  346.         if (np->e_sc != K_STATIC) {
  347.             fprintf(output, "\t.globl\t");
  348.             out_nm(np);
  349.             fputc('\n', output);
  350.         }
  351.         if (isbss) {
  352.             if (np->e_sc == K_STATIC) {
  353.                 out_nm(np);
  354.                 sz = np->n_tptr->t_size;
  355.                 c = 'b';
  356.                 if (np->n_tptr->t_aln) {
  357.                     c = 'w';
  358.                     sz /= 2;
  359.                 }
  360.                 fprintf(output, ":\t.ds.%c\t%ld\n", c, sz);
  361.             } else {
  362.                 fprintf(output, "\t.comm\t");
  363.                 out_nm(np);
  364.                 sz = np->n_tptr->t_size;
  365.                 if (sz & 1) sz++;  /* ALCYON hack */
  366.                 fprintf(output, ",%ld\n", sz);
  367.             }
  368.         } else {
  369.             out_nm(np);
  370.             fprintf(output, ":\n");
  371.         }
  372.     }
  373. }
  374.  
  375. new_lbl()
  376. {
  377.     return lblnum++;
  378. }
  379.  
  380. def_lbl(l)
  381. {
  382.     fprintf(output, "L%d:\n", l);
  383. }
  384.  
  385. out_br(l)
  386. {
  387.     if (l < 0)
  388.         error("bad branch");
  389.     else
  390.         fprintf(output, "\tbra\tL%d\n", l);
  391. }
  392.  
  393. static char *bnm[] = {
  394.     "",
  395.     "beq",
  396.     "bne",
  397.     "blt",
  398.     "bge",
  399.     "ble",
  400.     "bgt",
  401.     "bra",
  402.     "nop",
  403.     "bcs",
  404.     "bcc",
  405.     "bls",
  406.     "bhi"
  407. };
  408.  
  409. static char *snm[] = {
  410.     "",
  411.     "seq",
  412.     "sne",
  413.     "slt",
  414.     "sge",
  415.     "sle",
  416.     "sgt",
  417.     "",
  418.     "",
  419.     "scs",
  420.     "scc",
  421.     "sls",
  422.     "shi"
  423. };
  424.  
  425. out_b(key, l)
  426. {
  427.     if (key != B_NO)
  428.         fprintf(output, "\t%s\tL%d\n", bnm[key], l);
  429. }
  430.  
  431. out_bnol(key)
  432. {
  433.     fprintf(output, "\t%s\t", bnm[key]);
  434. }
  435.  
  436. out_snol(key)
  437. {
  438.     fprintf(output, "\t%s\t", snm[key]);
  439. }
  440.  
  441. out_d0cmp(x)
  442. {
  443.     fprintf(output, "\tcmp.w\t#%d,d0\n", x);
  444. }
  445.  
  446. out_d0sub(x)
  447. {
  448.     fprintf(output, "\tsub.w\t#%d,d0\n", x);
  449. }
  450.  
  451. out_tlbl(l)
  452. {
  453.     fprintf(output, "\t.dc.l\tL%d\n", l);
  454. }
  455.  
  456. out_tsw()
  457. {
  458.     fprintf(output, "\text.l\td0\n");
  459.     fprintf(output, "\tasl.l\t#2,d0\n");
  460.     fprintf(output, "\tmove.l\t4(pc,d0.l),a0\n");
  461.     fprintf(output, "\tjmp\t(a0)\n");
  462. }
  463.  
  464. out_nm(np)
  465. NODEP np;
  466. {
  467.     if (np->e_sc == K_STATIC)
  468.         fprintf(output, "L%d", (int)np->e_offs);
  469.     else
  470.         und_nnm(np);
  471. }
  472.  
  473. out_zi(tp)
  474. NODEP tp;
  475. {
  476.     char *s;
  477. /*
  478.     switch (tp->t_token) {
  479.     case K_FLOAT:
  480.         fprintf(output, "\t.float\t0.0\n");    return;
  481.     case K_DOUBLE:
  482.         fprintf(output, "\t.double\t0.0\n");    return;
  483.     }
  484. */
  485.     dat_size += tp->t_size;
  486.     s = init_str((int)tp->t_size);
  487.     fprintf(output, "\t%s\t0\n", s);
  488. }
  489.  
  490. o_nz(sz, aln)
  491. long sz;
  492. {
  493.     dat_size += sz;
  494.     if (aln) {
  495.         if (sz & 1)
  496.             fprintf(output, "\t.ds.b\t1\n");
  497.         sz >>= 1;
  498.         fprintf(output, "\t.ds.w\t%ld\n", sz);
  499.     } else {
  500.         fprintf(output, "\t.ds.b\t%ld\n", sz);
  501.     }
  502. }
  503.  
  504. dumpstrs(np)
  505. NODEP np;
  506. {
  507.     TO_DATA;
  508. more:
  509.     if (np == NULL)
  510.         return;
  511.     fprintf(output, "L%d:", (int)np->g_offs);
  512.     out_scon(np);
  513.     np = np->n_next;
  514.     goto more;
  515. }
  516.  
  517. int see_esc;
  518.  
  519. out_scon(np)
  520. NODEP np;
  521. {
  522.     int len = 0;
  523.  
  524.     if (np == NULL)
  525.         return 0;
  526.     see_esc = 0;
  527. more:
  528.     if (np->n_name[0]) {
  529.         fprintf(output, "\t.dc.b\t");
  530.         len += out_str(np->n_name);
  531.         putc('\n', output);
  532.     }
  533.     np = np->n_nmx;
  534.     if (np)
  535.         goto more;
  536.  
  537.     fprintf(output, "\t.dc.b\t0\n");
  538.     len++;
  539.     dat_size += len;
  540.     return len;
  541. }
  542.  
  543. out_str(s)
  544. char *s;
  545. {
  546.     int len;
  547.     register c;
  548.  
  549.     len = 0;
  550.     for ( ; c = *s; s++) {
  551.         if (see_esc) {    /* allow null */
  552.             c--;
  553.             see_esc = 0;
  554.         } else if (c == 1) {
  555.             see_esc = 1;
  556.             continue;
  557.         }
  558.         if (len) {
  559.             if ((len & 15) == 0)
  560.                 fprintf(output, "\n\t.dc.b\t");
  561.             else
  562.                 putc(',', output);
  563.         }
  564.         out_1c(c);
  565.         len++;
  566.     }
  567.     return len;
  568. }
  569.  
  570. out_asm(np)
  571. NODEP np;
  572. {
  573.     putc('\t', output);
  574. more:
  575.     fprintf(output, "%s", np->n_name);    /* no \0 or \1 please! */
  576.     np = np->n_nmx;
  577.     if (np)
  578.         goto more;
  579.     putc('\n', output);
  580. }
  581.  
  582. und_nnm(np)
  583. NODEP np;
  584. {
  585.     fputc('_', output);
  586.     fput_nnm(np);
  587. }
  588.  
  589. out_1c(c)
  590. char c;
  591. {
  592.     fprintf(output, "$%x", c & 0xff);
  593. }
  594.  
  595. outcode(np)
  596. register NODEP np;
  597. {
  598.     NODEP tp;
  599.  
  600.     if (np == NULL) return;
  601.  
  602.     switch (np->g_type) {
  603.     case EV_NONE:
  604.         break;
  605.     case EV_RL:
  606.         outcode(np->n_right);
  607.         outsub(np->g_betw, np);
  608.         /* fall through */
  609.     case EV_LEFT:
  610.         outcode(np->n_left);
  611.         break;
  612.     case EV_LR:
  613.     case EV_LRSEP:
  614.         outcode(np->n_left);
  615.         outsub(np->g_betw, np);
  616.         /* fall through */
  617.     case EV_RIGHT:
  618.         outcode(np->n_right);
  619.         break;
  620.     default:
  621.         printf("bad eval %d ", np->g_type);
  622.     }
  623.     if (np->n_flags & N_COPYT)    /* g_code is a char * */
  624.         outsub(np->g_code, np);
  625.     else                /* g_code is a list of nodes */
  626.         for (tp=np->g_code; tp != NULL; tp = tp->g_code)
  627.             outsub(tp->n_name, np);
  628. }
  629.  
  630. outsub(cp, np)
  631. register char *cp;
  632. register NODEP np;
  633. {
  634.     register char c;
  635.  
  636.     if (cp == NULL) return;
  637.     while (c = *cp++)
  638.         if (c == '<')
  639.             out_let(*cp++, np->n_left);
  640.         else if (c == '>')
  641.             out_let(*cp++, np->n_right);
  642.         else if (c == '\'') {
  643.             c = *cp++;
  644.             fputc(c, output);
  645.         } else if (c == 'L')
  646.             seelab(*cp++, np);
  647.         else if (c == 'R')
  648.             seereg(np, *cp++);
  649.         else if (c >= 'A' && c <= 'Z') {
  650.             out_let(c, np);
  651.         } else
  652.             fputc(c, output);
  653. }
  654.  
  655. seereg(np, c)
  656. NODEP np;
  657. {
  658.     int i;
  659.  
  660.     switch (c) {
  661.     case '0':    i = np->g_rno;  break;
  662.     case '1':    i = np->g_r1;   break;
  663.     case '2':    i = np->g_r2;   break;
  664.     }
  665.     fprintf(output, regnm(i));    
  666. }
  667.  
  668. out_let(c, np)
  669. register NODEP np;
  670. {
  671.     int i;
  672.  
  673.     switch (c) {
  674.     case 'A':
  675.         if (np->g_flags & IMMEDID)
  676.             fputc('#', output);
  677.         out_a(np, output);
  678.         break;
  679.     case 'E':
  680.     case 'F':    /* branch if false */
  681.         i = cctok(np);
  682.         i = (i&1) ? i+1 : i-1;    /* reverse truth */
  683.         if (c == 'F')
  684.             out_bnol(i);
  685.         else
  686.             out_snol(i);
  687.         break;
  688.     case 'H':    /* last a reg (for struct assign) */
  689.         fprintf(output, regnm(ARV_START-1));
  690.         break;
  691.     case 'K':
  692.         fprintf(output, "%ld", np->g_bsize);
  693.         break;
  694.     case 'N':
  695.         fprintf(output, "%s", np->n_name);
  696.         break;
  697.     case 'O':
  698.         fprintf(output, "%ld", np->g_offs);
  699.         break;
  700.     case 'Q':
  701.         if (np->g_flags & IMMEDID) {
  702.             warn("constant test expr");
  703.             if (np->g_token == ICON && np->g_offs == 0)
  704.                 fprintf(output, "\tor\t#$FF,ccr\n");
  705.             else
  706.                 fprintf(output, "\tand\t#0,ccr\n");
  707.             return;
  708.         }
  709.         fprintf(output, "\t%s.%c\t", isareg(np) ? "cmp" : "tst",
  710.             tlen(np->g_sz));
  711.         if (isareg(np))
  712.             fprintf(output, "#0,");
  713.         out_let('A', np);
  714.         fputc('\n', output);
  715.         break;
  716.     case 'S':
  717.         fputc(tlen(np->g_sz), output);
  718.         break;
  719.     case 'T':    /* branch if true */
  720.         out_bnol(cctok(np));
  721.         break;
  722.     case 'U':
  723.         fputc(np->g_ty == ET_U ? 'u' : 's', output);
  724.         break;
  725.     case 'W':    /* field width 1's */
  726.         fprintf(output, "$%x", ones(np->g_fldw));
  727.         break;
  728.     case 'X':    /* ~(W << offset) */
  729.         fprintf(output, "$%x", (unsigned short)
  730.                 (~(ones(np->g_fldw)<<np->g_fldo)));
  731.         break;
  732.     case 'Y':    /* field offset */
  733.         fprintf(output, "%d", np->g_fldo);
  734.         break;
  735.     case 'Z':    /* field offset - 8 */
  736.         fprintf(output, "%d", np->g_fldo - 8);
  737.         break;
  738.     default:
  739.         printf("bad out_let %c ", c);
  740.     }
  741. }
  742.  
  743. #ifdef UNIX
  744. /*
  745.  * conversion routine for IEEE based cross compile
  746.  */
  747. long
  748. ieee_to_ffp(d)
  749. double d;
  750. {
  751.     union {
  752.         float fval;
  753.         long ival;
  754.     } v;
  755.     int sign, exp;
  756.     long mant, rv;
  757.  
  758.     v.fval = d;
  759.  
  760.     sign = (v.ival < 0) ? 0x80 : 0;
  761.     exp = (v.ival >> 23) & 0xff;
  762.     exp -= (127 - 1);
  763.     mant = 0x800000L | (v.ival & 0x7fffffL);
  764.  
  765.     if (exp <= -64) {
  766.         return 0;
  767.     } else if (exp > 63) {
  768.         exp = 63;
  769.         mant = 0xffffff;
  770.     }
  771.  
  772.     rv = (mant << 8) | sign | (exp + 64);
  773.     return rv;
  774. }
  775. #endif
  776.  
  777. out_a(np, fd)
  778. register NODEP np;
  779. FILE *fd;
  780. {
  781.     int offs = np->g_offs;
  782.  
  783.     switch (np->g_token) {
  784.     case ICON:
  785.         fprintf(fd, "%ld", np->g_offs);
  786.         break;
  787.     case FCON:
  788. #ifndef UNIX
  789.         /* works for ALCYON C */
  790.         /* otherwise depends on floating internal format */
  791.         fprintf(fd, "$%lx", np->g_offs);
  792. #else
  793.         fprintf(fd, "$%lx", ieee_to_ffp(np->g_fval));
  794. #endif
  795.         break;
  796.     case ONAME:
  797.         while (np->g_flags & (CHILDNM|RCHILDNM)) {
  798.             np = (np->g_flags & CHILDNM) ? 
  799.                 np->n_left : np->n_right;
  800.         }
  801.         qput_nnm(np, fd);
  802.         if (offs)
  803.             fprintf(fd, offs > 0 ? "+%d" : "%d", offs);
  804.         break;
  805.     case PUSHER:
  806.         fprintf(fd, "(sp)+");
  807.         break;
  808.     case OREG:
  809.         if (offs)
  810.             fprintf(fd, "%d", offs);
  811.         fprintf(fd, "(%s)", regnm(np->g_rno));
  812.         break;
  813.     case REGVAR:
  814.         fprintf(fd, regnm(np->g_rno));
  815.         break;
  816.     case ',':
  817.         fputc(',', fd);        /* for debug */
  818.         break;
  819.     default:
  820.         if (np->g_token >= BR_TOK) {
  821.             fprintf(fd, "B_%s", bnm[np->g_token - BR_TOK]);
  822.             break;
  823.         }
  824.         printf("? tok %d ", np->g_token);
  825.     }
  826. }
  827.  
  828. seelab(c, np)
  829. char c;
  830. NODEP np;
  831. {
  832.     c -= '1';
  833.     fprintf(output, "L%d", (int)np->g_bsize+c);
  834. }
  835.  
  836. ones(n)
  837. {
  838.     return (1 << n) - 1;
  839. }
  840.     
  841.