home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 2 / crawlyvol2.bin / program / c / c68k_src / outcode.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-10  |  11.8 KB  |  435 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.         {       {"MOVE",op_move}, {"MOVE",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}, {"MOVEM",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. {
  77.    char su[80];
  78.  
  79.        switch( offset->nodetype )
  80.                 {
  81.                 case en_autocon:
  82.                 case en_icon:
  83.                         fprintf(output,"%d",offset->v.i);
  84.                         break;
  85.                 case en_labcon:
  86.                         fprintf(output,"L.%d",offset->v.i);
  87.                         break;
  88.                 case en_nacon:
  89.                         strcpy(su,offset->v.p[0]);    /* copy labels str */
  90.                         upcase(su);              /* Transform to upper */
  91.                         fprintf(output,"%s",su);
  92.                         break;
  93.                 case en_add:
  94.                         putconst(offset->v.p[0]);
  95.                         fprintf(output,"+");
  96.                         putconst(offset->v.p[1]);
  97.                         break;
  98.                 case en_sub:
  99.                         putconst(offset->v.p[0]);
  100.                         fprintf(output,"-");
  101.                         putconst(offset->v.p[1]);
  102.                         break;
  103.                 case en_uminus:
  104.                         fprintf(output,"-");
  105.                         putconst(offset->v.p[0]);
  106.                         break;
  107.                 default:
  108.                         printf("DIAG - illegal constant node.\n");
  109.                         break;
  110.                 }
  111. }
  112.  
  113. putlen(l)
  114. /*
  115.  *      append the length field to an instruction.
  116.  */
  117. int     l;
  118. {       switch( l )
  119.                 {
  120.                 case 0:
  121.                         break;  /* no length field */
  122.                 case 1:
  123.                         fprintf(output,".B");
  124.                         break;
  125.                 case 2:
  126.                         fprintf(output,".W");
  127.                         break;
  128.                 case 4:
  129.                         fprintf(output,".L");
  130.                         break;
  131.                 default:
  132.                         printf("DIAG - illegal length field.\n");
  133.                         break;
  134.                 }
  135. }
  136.  
  137. putamode(ap)
  138. /*
  139.  *      output a general addressing mode.
  140.  */
  141. struct amode    *ap;
  142. {       switch( ap->mode )
  143.                 {
  144.                 case am_immed:
  145.                         fprintf(output,"#");
  146.                 case am_direct:
  147.                         putconst(ap->offset);
  148.                         break;
  149.                 case am_areg:
  150.                         fprintf(output,"A%d",ap->preg);
  151.                         break;
  152.                 case am_dreg:
  153.                         fprintf(output,"D%d",ap->preg);
  154.                         break;
  155.                 case am_ind:
  156.                         fprintf(output,"(A%d)",ap->preg);
  157.                         break;
  158.                 case am_ainc:
  159.                         fprintf(output,"(A%d)+",ap->preg);
  160.                         break;
  161.                 case am_adec:
  162.                         fprintf(output,"-(A%d)",ap->preg);
  163.                         break;
  164.                 case am_indx:
  165.                         putconst(ap->offset);
  166.                         fprintf(output,"(A%d)",ap->preg);
  167.                         break;
  168.                 case am_xpc:
  169.                         putconst(ap->offset);
  170.                         fprintf(output,"(D%d,PC)",ap->preg);
  171.                         break;
  172.                 case am_indx2:
  173.                         putconst(ap->offset);
  174.                         fprintf(output,"(A%d,D%d.L)",ap->preg,ap->sreg);
  175.                         break;
  176.                 case am_indx3:
  177.                         putconst(ap->offset);
  178.                         fprintf(output,"(A%d,A%d.L)",ap->preg,ap->sreg);
  179.                         break;
  180.                 case am_mask:
  181.                         put_mask(ap->offset);
  182.                         break;
  183.                 default:
  184.                         printf("DIAG - illegal address mode.\n");
  185.                         break;
  186.                 }
  187. }
  188.  
  189. put_code(op,len,aps,apd)
  190. /*
  191.  *      output a generic instruction.
  192.  */
  193. struct amode    *aps, *apd;
  194. int             op, len;
  195. {       if( op == op_dc )
  196.         {
  197.         switch( len )
  198.             {
  199.             case 1: fprintf(output,"\tDC.B"); break;
  200.             case 2: fprintf(output,"\tDC.W"); break;
  201.             case 4: fprintf(output,"\tDC.L"); break;
  202.             }
  203.         }
  204.     else
  205.         {
  206.         putop(op);
  207.             putlen(len);
  208.         }
  209.         if( aps != 0 )
  210.                 {
  211.                 fprintf(output,"\t");
  212.         putamode(aps);
  213.                 if( apd != 0 )
  214.                         {
  215.                         fprintf(output,",");
  216.                            putamode(apd);
  217.                         }
  218.                 }
  219.         fprintf(output,"\n");
  220. }
  221.  
  222. put_mask(mask)
  223. /*
  224.  *      generate a register mask for restore and save.
  225.  */
  226. int     mask;
  227. {       int     i;
  228.         int     notfirst;
  229. /*        fprintf(output,"#$%04X",mask);    */
  230.  
  231.         notfirst = 0;
  232.         for(i=0; i< 16; i++)
  233.         {  if((mask & (1 << (15-i))) != 0)
  234.            { if( notfirst ) fprintf(output,"/");
  235.              notfirst=1;
  236.              putreg(i);
  237.            }
  238.         }
  239.  
  240.  
  241. }
  242.  
  243. putreg(r)
  244. /*
  245.  *      generate a register name from a tempref number.
  246.  */
  247. int     r;
  248. {       if( r < 8 )
  249.                 fprintf(output,"D%d",r);
  250.         else
  251.                 fprintf(output,"A%d",r - 8);
  252. }
  253.  
  254. gen_strlab(s)
  255. /*
  256.  *      generate a named label.
  257.  */
  258. char    *s;
  259. {
  260.   char su[80];
  261.   strcpy(su,s);            /* Copy the label... */
  262.   upcase(su);            /* Convert to upper case */
  263.        fprintf(output,"%s:\n",su);
  264. }
  265.  
  266. put_label(lab)
  267. /*
  268.  *      output a compiler generated label.
  269.  */
  270. int     lab;
  271. {       fprintf(output,"L.%d:\n",lab);
  272. }
  273.  
  274. genbyte(val)
  275. int     val;
  276. {       if( gentype == bytegen && outcol < 60) {
  277.                 fprintf(output,",%d",val & 0x00ff);
  278.                 outcol += 4;
  279.                 }
  280.         else    {
  281.                 nl();
  282.                 fprintf(output,"\tDC.B\t%d",val & 0x00ff);
  283.                 gentype = bytegen;
  284.                 outcol = 19;
  285.                 }
  286. }
  287.  
  288. genword(val)
  289. int     val;
  290. {       if( gentype == wordgen && outcol < 58) {
  291.                 fprintf(output,",%d",val & 0x0ffff);
  292.                 outcol += 6;
  293.                 }
  294.         else    {
  295.                 nl();
  296.                 fprintf(output,"\tDC.W\t%d",val & 0x0ffff);
  297.                 gentype = wordgen;
  298.                 outcol = 21;
  299.                 }
  300. }
  301.  
  302. genlong(val)
  303. int     val;
  304. {       if( gentype == longgen && outcol < 56) {
  305.                 fprintf(output,",%d",val);
  306.                 outcol += 10;
  307.                 }
  308.         else    {
  309.                 nl();
  310.                 fprintf(output,"\tDC.L\t%d",val);
  311.                 gentype = longgen;
  312.                 outcol = 25;
  313.                 }
  314. }
  315.  
  316. genref(sp,offset)
  317. SYM     *sp;
  318. int     offset;
  319. {       char    sign;
  320.         if( offset < 0) {
  321.                 sign = '-';
  322.                 offset = -offset;
  323.                 }
  324.         else
  325.                 sign = '+';
  326.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  327.                 if( sp->storage_class == sc_static)
  328.                         fprintf(output,",L.%d%c%d",sp->value.i,sign,offset);
  329.                 else
  330.                         fprintf(output,",%s%c%d",sp->name,sign,offset);
  331.                 outcol += (11 + strlen(sp->name));
  332.                 }
  333.         else    {
  334.                 nl();
  335.                 if(sp->storage_class == sc_static)
  336.                     fprintf(output,"\tlong\tL.%d%c%d",sp->value.i,sign,offset);
  337.                 else
  338.                     fprintf(output,"\tlong\t%s%c%d",sp->name,sign,offset);
  339.                 outcol = 26 + strlen(sp->name);
  340.                 gentype = longgen;
  341.                 }
  342. }
  343.  
  344. genstorage(nbytes)
  345. int     nbytes;
  346. {       nl();
  347.         fprintf(output,"\tDS.B\t%d\n",nbytes);
  348. }
  349.  
  350. gen_labref(n)
  351. int     n;
  352. {       if( gentype == longgen && outcol < 58) {
  353.                 fprintf(output,",L.%d",n);
  354.                 outcol += 6;
  355.                 }
  356.         else    {
  357.                 nl();
  358.                 fprintf(output,"\tlong\tL.%d",n);
  359.                 outcol = 22;
  360.                 gentype = longgen;
  361.                 }
  362. }
  363.  
  364. int     stringlit(s)
  365. /*
  366.  *      make s a string literal and return it's label number.
  367.  */
  368. char    *s;
  369. {       struct slit     *lp;
  370.         ++global_flag;          /* always allocate from global space. */
  371.         lp = xalloc(sizeof(struct slit));
  372.         lp->label = nextlabel++;
  373.         lp->str = litlate(s);
  374.         lp->next = strtab;
  375.         strtab = lp;
  376.         --global_flag;
  377.         return lp->label;
  378. }
  379.  
  380. dumplits()
  381. /*
  382.  *      dump the string literal pool.
  383.  */
  384. {       char            *cp;
  385.         while( strtab != 0) {
  386.                 cseg();
  387.                 nl();
  388.                 put_label(strtab->label);
  389.                 cp = strtab->str;
  390.                 while(*cp)
  391.                         genbyte(*cp++);
  392.                 genbyte(0);
  393.                 strtab = strtab->next;
  394.                 }
  395.         nl();
  396. }
  397.  
  398. nl()
  399. {       if(outcol > 0) {
  400.                 fprintf(output,"\n");
  401.                 outcol = 0;
  402.                 gentype = nogen;
  403.                 }
  404. }
  405.  
  406. cseg()
  407. {       if( curseg != codeseg) {
  408.                 nl();
  409.                 fprintf(output,"\tSECTION\t9\n");
  410.                 curseg = codeseg;
  411.                 }
  412. }
  413.  
  414. dseg()
  415. {       if( curseg != dataseg) {
  416.                 nl();
  417.                 fprintf(output,"\tSECTION\t15\n");
  418.                 curseg = dataseg;
  419.                 }
  420. }
  421. upcase(stg)                /* Convert string to upper case */
  422. char stg[];
  423. {
  424.   int i;
  425.   char toupper();
  426.  
  427.   i=0;
  428.   while(stg[i])
  429.   {
  430.     stg[i]=toupper(stg[i]);
  431.     i++;
  432.   }
  433. }
  434.  
  435.