home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_progs / prog_c / zc.lzh / ZC / ZCSRC.LZH / src / out.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-06-16  |  14.4 KB  |  835 lines

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