home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_200 / 204_01 / outcode.c < prev    next >
Text File  |  1979-12-31  |  12KB  |  407 lines

  1. #include        <stdio.h>
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or questions
  18.  *    to:
  19.  *
  20.  *        Matthew Brandt
  21.  *        Box 920337
  22.  *        Norcross, Ga 30092
  23.  */
  24.  
  25. /*      variable initialization         */
  26.  
  27. enum e_gt { nogen, bytegen, wordgen, longgen };
  28. enum e_sg { noseg, codeseg, dataseg };
  29.  
  30. int           gentype = nogen;
  31. int           curseg = noseg;
  32. int        outcol = 0;
  33.  
  34. struct oplst {
  35.         char    *s;
  36.         int     ov;
  37.         }       opl[] =
  38.         {       {"mov",op_move}, {"mov",op_moveq}, {"add",op_add},
  39.                 {"add",op_addi}, {"add",op_addq}, {"sub",op_sub},
  40.                 {"sub",op_subi}, {"sub",op_subq}, {"and",op_and},
  41.                 {"or",op_or}, {"eor",op_eor}, {"muls",op_muls},
  42.                 {"divs",op_divs}, {"swap",op_swap}, {"beq",op_beq},
  43.                 {"bhi",op_bhi}, {"bhs",op_bhs}, {"blo",op_blo},
  44.                 {"bls",op_bls}, {"mulu",op_mulu}, {"divu",op_divu},
  45.                 {"bne",op_bne}, {"blt",op_blt}, {"ble",op_ble},
  46.                 {"bgt",op_bgt}, {"bge",op_bge}, {"neg",op_neg},
  47.                 {"not",op_not}, {"cmp",op_cmp}, {"ext",op_ext},
  48.                 {"jmp",op_jmp}, {"jsr",op_jsr}, {"rts",op_rts},
  49.                 {"lea",op_lea}, {"asr",op_asr}, {"asl",op_asl},
  50.                 {"clr",op_clr}, {"link",op_link}, {"unlk",op_unlk},
  51.                 {"bra",op_bra}, {"movm",op_movem}, {"pea",op_pea},
  52.                 {"cmp",op_cmpi}, {"tst",op_tst}, {"dc",op_dc},
  53.                 {0,0} };
  54.  
  55. putop(op)
  56. int     op;
  57. {       int     i;
  58.         i = 0;
  59.         while( opl[i].s )
  60.                 {
  61.                 if( opl[i].ov == op )
  62.                         {
  63.                         fprintf(output,"\t%s",opl[i].s);
  64.                         return;
  65.                         }
  66.                 ++i;
  67.                 }
  68.         printf("DIAG - illegal opcode.\n");
  69. }
  70.  
  71. putconst(offset)
  72. /*
  73.  *      put a constant to the output file.
  74.  */
  75. struct enode    *offset;
  76. {       switch( offset->nodetype )
  77.                 {
  78.                 case en_autocon:
  79.                 case en_icon:
  80.                         fprintf(output,"%d",offset->v.i);
  81.                         break;
  82.                 case en_labcon:
  83.                         fprintf(output,"L%%%d",offset->v.i);
  84.                         break;
  85.                 case en_nacon:
  86.                         fprintf(output,"%s",offset->v.p[0]);
  87.                         break;
  88.                 case en_add:
  89.                         putconst(offset->v.p[0]);
  90.                         fprintf(output,"+");
  91.                         putconst(offset->v.p[1]);
  92.                         break;
  93.                 case en_sub:
  94.                         putconst(offset->v.p[0]);
  95.                         fprintf(output,"-");
  96.                         putconst(offset->v.p[1]);
  97.                         break;
  98.                 case en_uminus:
  99.                         fprintf(output,"-");
  100.                         putconst(offset->v.p[0]);
  101.                         break;
  102.                 default:
  103.                         printf("DIAG - illegal constant node.\n");
  104.                         break;
  105.                 }
  106. }
  107.  
  108. putlen(l)
  109. /*
  110.  *      append the length field to an instruction.
  111.  */
  112. int     l;
  113. {       switch( l )
  114.                 {
  115.                 case 0:
  116.                         break;  /* no length field */
  117.                 case 1:
  118.                         fprintf(output,".b");
  119.                         break;
  120.                 case 2:
  121.                         fprintf(output,".w");
  122.                         break;
  123.                 case 4:
  124.                         fprintf(output,".l");
  125.                         break;
  126.                 default:
  127.                         printf("DIAG - illegal length field.\n");
  128.                         break;
  129.                 }
  130. }
  131.  
  132. putamode(ap)
  133. /*
  134.  *      output a general addressing mode.
  135.  */
  136. struct amode    *ap;
  137. {       switch( ap->mode )
  138.                 {
  139.                 case am_immed:
  140.                         fprintf(output,"&");
  141.                 case am_direct:
  142.                         putconst(ap->offset);
  143.                         break;
  144.                 case am_areg:
  145.                         fprintf(output,"%%a%d",ap->preg);
  146.                         break;
  147.                 case am_dreg:
  148.                         fprintf(output,"%%d%d",ap->preg);
  149.                         break;
  150.                 case am_ind:
  151.                         fprintf(output,"(%%a%d)",ap->preg);
  152.                         break;
  153.                 case am_ainc:
  154.                         fprintf(output,"(%%a%d)+",ap->preg);
  155.                         break;
  156.                 case am_adec:
  157.                         fprintf(output,"-(%%a%d)",ap->preg);
  158.                         break;
  159.                 case am_indx:
  160.                         putconst(ap->offset);
  161.                         fprintf(output,"(%%a%d)",ap->preg);
  162.                         break;
  163.                 case am_xpc:
  164.                         putconst(ap->offset);
  165.                         fprintf(output,"(%%d%d,%%pc)",ap->preg);
  166.                         break;
  167.                 case am_indx2:
  168.                         putconst(ap->offset);
  169.                         fprintf(output,"(%%a%d,%%d%d.l)",ap->preg,ap->sreg);
  170.                         break;
  171.                 case am_indx3:
  172.                         putconst(ap->offset);
  173.                         fprintf(output,"(%%a%d,%%a%d.l)",ap->preg,ap->sreg);
  174.                         break;
  175.                 case am_mask:
  176.                         put_mask(ap->offset);
  177.                         break;
  178.                 default:
  179.                         printf("DIAG - illegal address mode.\n");
  180.                         break;
  181.                 }
  182. }
  183.  
  184. put_code(op,len,aps,apd)
  185. /*
  186.  *      output a generic instruction.
  187.  */
  188. struct amode    *aps, *apd;
  189. int             op, len;
  190. {       if( op == op_dc )
  191.         {
  192.         switch( len )
  193.             {
  194.             case 1: fprintf(output,"\tbyte"); break;
  195.             case 2: fprintf(output,"\tshort"); break;
  196.             case 4: fprintf(output,"\tlong"); break;
  197.             }
  198.         }
  199.     else
  200.         {
  201.         putop(op);
  202.             putlen(len);
  203.         }
  204.         if( aps != 0 )
  205.                 {
  206.                 fprintf(output,"\t");
  207.         if( op == op_cmp || op == op_cmpi )
  208.             putamode( apd );
  209.         else
  210.             putamode(aps);
  211.                 if( apd != 0 )
  212.                         {
  213.                         fprintf(output,",");
  214.             if( op == op_cmp || op == op_cmpi )
  215.                 putamode( aps );
  216.             else
  217.                             putamode(apd);
  218.                         }
  219.                 }
  220.         fprintf(output,"\n");
  221. }
  222.  
  223. put_mask(mask)
  224. /*
  225.  *      generate a register mask for restore and save.
  226.  */
  227. int     mask;
  228. {       int     i;
  229.         fprintf(output,"&0x%04x",mask);
  230. }
  231.  
  232. putreg(r)
  233. /*
  234.  *      generate a register name from a tempref number.
  235.  */
  236. int     r;
  237. {       if( r < 8 )
  238.                 fprintf(output,"D%d",r);
  239.         else
  240.                 fprintf(output,"A%d",r - 8);
  241. }
  242.  
  243. gen_strlab(s)
  244. /*
  245.  *      generate a named label.
  246.  */
  247. char    *s;
  248. {       fprintf(output,"%s:\n",s);
  249. }
  250.  
  251. put_label(lab)
  252. /*
  253.  *      output a compiler generated label.
  254.  */
  255. int     lab;
  256. {       fprintf(output,"L%%%d:\n",lab);
  257. }
  258.  
  259. genbyte(val)
  260. int     val;
  261. {       if( gentype == bytegen && outcol < 60) {
  262.                 fprintf(output,",%d",val & 0x00ff);
  263.                 outcol += 4;
  264.                 }
  265.         else    {
  266.                 nl();
  267.                 fprintf(output,"\tbyte\t%d",val & 0x00ff);
  268.                 gentype = bytegen;
  269.                 outcol = 19;
  270.                 }
  271. }
  272.  
  273. genword(val)
  274. int     val;
  275. {       if( gentype == wordgen && outcol < 58) {
  276.                 fprintf(output,",%d",val & 0x0ffff);
  277.                 outcol += 6;
  278.                 }
  279.         else    {
  280.                 nl();
  281.                 fprintf(output,"\tshort\t%d",val & 0x0ffff);
  282.                 gentype = wordgen;
  283.                 outcol = 21;
  284.                 }
  285. }
  286.  
  287. genlong(val)
  288. int     val;
  289. {       if( gentype == longgen && outcol < 56) {
  290.                 fprintf(output,",%d",val);
  291.                 outcol += 10;
  292.                 }
  293.         else    {
  294.                 nl();
  295.                 fprintf(output,"\tlong\t%d",val);
  296.                 gentype = longgen;
  297.                 outcol = 25;
  298.                 }
  299. }
  300.  
  301. genref(sp,offset)
  302. SYM     *sp;
  303. int     offset;
  304. {       char    sign;
  305.         if( offset < 0) {
  306.                 sign = '-';
  307.                 offset = -offset;
  308.                 }
  309.         else
  310.                 sign = '+';
  311.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  312.                 if( sp->storage_class == sc_static)
  313.                         fprintf(output,",L%%%d%c%d",sp->value.i,sign,offset);
  314.                 else
  315.                         fprintf(output,",%s%c%d",sp->name,sign,offset);
  316.                 outcol += (11 + strlen(sp->name));
  317.                 }
  318.         else    {
  319.                 nl();
  320.                 if(sp->storage_class == sc_static)
  321.                     fprintf(output,"\tlong\tL%%%d%c%d",sp->value.i,sign,offset);
  322.                 else
  323.                     fprintf(output,"\tlong\t%s%c%d",sp->name,sign,offset);
  324.                 outcol = 26 + strlen(sp->name);
  325.                 gentype = longgen;
  326.                 }
  327. }
  328.  
  329. genstorage(nbytes)
  330. int     nbytes;
  331. {       nl();
  332.         fprintf(output,"\tspace\t%d\n",nbytes);
  333. }
  334.  
  335. gen_labref(n)
  336. int     n;
  337. {       if( gentype == longgen && outcol < 58) {
  338.                 fprintf(output,",L%%%d",n);
  339.                 outcol += 6;
  340.                 }
  341.         else    {
  342.                 nl();
  343.                 fprintf(output,"\tlong\tL%%%d",n);
  344.                 outcol = 22;
  345.                 gentype = longgen;
  346.                 }
  347. }
  348.  
  349. int     stringlit(s)
  350. /*
  351.  *      make s a string literal and return it's label number.
  352.  */
  353. char    *s;
  354. {       struct slit     *lp;
  355.         ++global_flag;          /* always allocate from global space. */
  356.         lp = xalloc(sizeof(struct slit));
  357.         lp->label = nextlabel++;
  358.         lp->str = litlate(s);
  359.         lp->next = strtab;
  360.         strtab = lp;
  361.         --global_flag;
  362.         return lp->label;
  363. }
  364.  
  365. dumplits()
  366. /*
  367.  *      dump the string literal pool.
  368.  */
  369. {       char            *cp;
  370.         while( strtab != 0) {
  371.                 cseg();
  372.                 nl();
  373.                 put_label(strtab->label);
  374.                 cp = strtab->str;
  375.                 while(*cp)
  376.                         genbyte(*cp++);
  377.                 genbyte(0);
  378.                 strtab = strtab->next;
  379.                 }
  380.         nl();
  381. }
  382.  
  383. nl()
  384. {       if(outcol > 0) {
  385.                 fprintf(output,"\n");
  386.                 outcol = 0;
  387.                 gentype = nogen;
  388.                 }
  389. }
  390.  
  391. cseg()
  392. {       if( curseg != codeseg) {
  393.                 nl();
  394.                 fprintf(output,"\ttext\n");
  395.                 curseg = codeseg;
  396.                 }
  397. }
  398.  
  399. dseg()
  400. {       if( curseg != dataseg) {
  401.                 nl();
  402.                 fprintf(output,"\tdata\t2\n");
  403.                 curseg = dataseg;
  404.                 }
  405. }
  406.  
  407.