home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d110 / pdc.lha / Pdc / src / Outcode.c < prev    next >
C/C++ Source or Header  |  1987-10-28  |  12KB  |  462 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. extern char     *litlate();
  26.  
  27. /*      variable initialization         */
  28.  
  29. enum e_gt { nogen, bytegen, wordgen, longgen };
  30. enum e_sg { noseg, codeseg, dataseg };
  31.  
  32. enum e_gt    gentype = nogen;
  33. enum e_sg    curseg = noseg;
  34. int        outcol = 0;
  35.  
  36. struct oplst {
  37.         char    *s;
  38.         enum e_op     ov;
  39.         }       opl[] =
  40.         {       {"move",op_move}, {"moveq",op_moveq}, {"add",op_add},
  41.                 {"add",op_addi}, {"addq",op_addq}, {"sub",op_sub},
  42.                 {"sub",op_subi}, {"subq",op_subq}, {"and",op_and},
  43.                 {"or",op_or}, {"eor",op_eor}, {"muls",op_muls},
  44.                 {"divs",op_divs}, {"swap",op_swap}, {"beq",op_beq},
  45.                 {"bhi",op_bhi}, {"bhs",op_bhs}, {"blo",op_blo},
  46.                 {"bls",op_bls}, {"mulu",op_mulu}, {"divu",op_divu},
  47.                 {"bne",op_bne}, {"blt",op_blt}, {"ble",op_ble},
  48.                 {"bgt",op_bgt}, {"bge",op_bge}, {"neg",op_neg},
  49.                 {"not",op_not}, {"cmp",op_cmp}, {"ext",op_ext},
  50.                 {"jmp",op_jmp}, {"jsr",op_jsr}, {"rts",op_rts},
  51.                 {"lea",op_lea}, {"asr",op_asr}, {"asl",op_asl},
  52.                 {"clr",op_clr}, {"link",op_link}, {"unlk",op_unlk},
  53.                 {"bra",op_bra}, {"movem",op_movem}, {"pea",op_pea},
  54.                 {"cmp",op_cmpi}, {"tst",op_tst}, {"dc",op_dc},
  55.                 {(char *)0,(enum e_op)0} };
  56.  
  57. putop(op)
  58. enum e_op     op;
  59. {       int     i;
  60.         i = 0;
  61.         while( opl[i].s )
  62.                 {
  63.                 if( opl[i].ov == op )
  64.                         {
  65.                         fprintf(output,"\t%s",opl[i].s);
  66.                         return;
  67.                         }
  68.                 ++i;
  69.                 }
  70.         printf("DIAG - illegal opcode.\n");
  71. }
  72.  
  73. putconst(offset)
  74. /*
  75.  *      put a constant to the output file.
  76.  */
  77. struct enode    *offset;
  78. {       switch( offset->nodetype )
  79.                 {
  80.                 case en_autocon:
  81.                 case en_icon:
  82.                         fprintf(output,"%ld",offset->v.i);
  83.                         break;
  84.                 case en_labcon:
  85.                         fprintf(output,"L%ld",offset->v.i);
  86.                         break;
  87.                 case en_nacon:
  88.                         fprintf(output,"_%s",offset->v.p[0]);
  89.                         break;
  90.                 case en_add:
  91.                         putconst(offset->v.p[0]);
  92.                         fprintf(output,"+");
  93.                         putconst(offset->v.p[1]);
  94.                         break;
  95.                 case en_sub:
  96.                         putconst(offset->v.p[0]);
  97.                         fprintf(output,"-");
  98.                         putconst(offset->v.p[1]);
  99.                         break;
  100.                 case en_uminus:
  101.                         fprintf(output,"-");
  102.                         putconst(offset->v.p[0]);
  103.                         break;
  104.                 default:
  105.                         printf("DIAG - illegal constant node.\n");
  106.                         break;
  107.                 }
  108. }
  109.  
  110. putlen(l)
  111. /*
  112.  *      append the length field to an instruction.
  113.  */
  114. int     l;
  115. {       switch( l )
  116.                 {
  117.                 case 0:
  118.                         break;  /* no length field */
  119.                 case 1:
  120.                         fprintf(output,".b");
  121.                         break;
  122.                 case 2:
  123.                         fprintf(output,".w");
  124.                         break;
  125.                 case 4:
  126.                         fprintf(output,".l");
  127.                         break;
  128.                 default:
  129.                         printf("DIAG - illegal length field.\n");
  130.                         break;
  131.                 }
  132. }
  133.  
  134. putamode(ap)
  135. /*
  136.  *      output a general addressing mode.
  137.  */
  138. struct amode    *ap;
  139. {       switch( ap->mode )
  140.                 {
  141.                 case am_immed:
  142.                         fprintf(output,"#");
  143.                 case am_direct:
  144.                         putconst(ap->offset);
  145.                         break;
  146.                 case am_areg:
  147.                         fprintf(output,"a%d",ap->preg);
  148.                         break;
  149.                 case am_dreg:
  150.                         fprintf(output,"d%d",ap->preg);
  151.                         break;
  152.                 case am_ind:
  153.                         fprintf(output,"(a%d)",ap->preg);
  154.                         break;
  155.                 case am_ainc:
  156.                         fprintf(output,"(a%d)+",ap->preg);
  157.                         break;
  158.                 case am_adec:
  159.                         fprintf(output,"-(a%d)",ap->preg);
  160.                         break;
  161.                 case am_indx:
  162.                         putconst(ap->offset);
  163.                         fprintf(output,"(a%d)",ap->preg);
  164.                         break;
  165.                 case am_xpc:
  166.                         putconst(ap->offset);
  167.                         fprintf(output,"(d%d,pc)",ap->preg);
  168.                         break;
  169.                 case am_indx2:
  170.                         putconst(ap->offset);
  171.                         fprintf(output,"(a%d,d%d.l)",ap->preg,ap->sreg);
  172.                         break;
  173.                 case am_indx3:
  174.                         putconst(ap->offset);
  175.                         fprintf(output,"(a%d,a%d.l)",ap->preg,ap->sreg);
  176.                         break;
  177.                 case am_mask:
  178.                         put_mask((long)(ap->offset));
  179.                         break;
  180.                 default:
  181.                         printf("DIAG - illegal address mode.\n");
  182.             fprintf(output,"<DIAG - illegal address mode.>");
  183.                         break;
  184.                 }
  185. }
  186.  
  187. put_code(op,len,aps,apd)
  188. /*
  189.  *      output a generic instruction.
  190.  */
  191. struct amode    *aps, *apd;
  192. enum e_op    op;
  193. int             len;
  194. {
  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.     if( op == op_cmp || op == op_cmpi )
  213.        putamode( apd );
  214.     else
  215.        putamode(aps);
  216.         if( apd != 0 )
  217.        {
  218.          fprintf(output,",");
  219.          if( op == op_cmp || op == op_cmpi )
  220.         putamode( aps );
  221.          else
  222.                 putamode(apd);
  223.              }
  224.    }
  225.    fprintf(output,"\n");
  226. }
  227.  
  228. startRange(bit)
  229. unsigned int bit;
  230. {
  231.   char *s;
  232.  
  233.   if ( bit <= 7)
  234.      s = (char *)"d%d";
  235.   else
  236.      s = (char *)"a%d";
  237.   fprintf( output, s, bit % 8 ); 
  238. }
  239.  
  240. endRange(first,bit)
  241. unsigned int first,bit;
  242. {
  243.   if (first<=7 && bit>7) 
  244.     {
  245.       endRange(first,7);
  246.       fprintf(output,"/");
  247.       startRange(8);
  248.       first=8;
  249.     }
  250.   if (bit>first) 
  251.     {
  252.       fprintf(output,"-");
  253.       startRange(bit);
  254.     }
  255. }
  256.  
  257. put_mask(mask1)
  258. /*
  259.  *      generate a register mask for restore and save.
  260.  */
  261. long mask1;
  262. {
  263.   int mask = mask1; int bit; int inrange=-1; int some=0;
  264.  
  265.   for (bit = 0; bit <= 15; ++bit) 
  266.     {
  267.        if ( (mask>>bit) & 1 ) 
  268.     {
  269.       if (inrange < 0) 
  270.         {
  271.         if (some) fprintf( output, "/");
  272.         startRange(bit);
  273.         some=1;
  274.         inrange=bit;
  275.          }
  276.     }
  277.        else if (inrange >= 0) 
  278.      {
  279.        endRange( inrange, bit-1 );
  280.        inrange=-1;
  281.      }
  282.     }
  283.   if (inrange >= 0) 
  284.     endRange( inrange, 15);
  285. }
  286.  
  287. putreg(r)
  288. /*
  289.  *      generate a register name from a tempref number.
  290.  */
  291. int     r;
  292. {       if( r < 8 )
  293.                 fprintf(output,"D%d",r);
  294.         else
  295.                 fprintf(output,"A%d",r - 8);
  296. }
  297.  
  298. gen_strlab(s)
  299. /*
  300.  *      generate a named label.
  301.  */
  302. char    *s;
  303. {       fprintf(output,"_%s:\n",s);
  304. }
  305.  
  306. put_label(lab)
  307. /*
  308.  *      output a compiler generated label.
  309.  */
  310. long     lab;
  311. {       fprintf(output,"L%ld\n",lab);
  312. }
  313.  
  314. genbyte(val)
  315. int     val;
  316. {       if( gentype == bytegen && outcol < 60) {
  317.                 fprintf(output,",%d",val & 0x00ff);
  318.                 outcol += 4;
  319.                 }
  320.         else    {
  321.                 nl();
  322.                 fprintf(output,"\tDC.b\t%d",val & 0x00ff);
  323.                 gentype = bytegen;
  324.                 outcol = 19;
  325.                 }
  326. }
  327.  
  328. genword(val)
  329. long     val;
  330. {       if( gentype == wordgen && outcol < 58) {
  331.                 fprintf(output,",%ld",val & 0x0ffff);
  332.                 outcol += 6;
  333.                 }
  334.         else    {
  335.                 nl();
  336.                 fprintf(output,"\tDC.w\t%ld",val & 0x0ffff);
  337.                 gentype = wordgen;
  338.                 outcol = 21;
  339.                 }
  340. }
  341.  
  342. genlong(val)
  343. long     val;
  344. {       if( gentype == longgen && outcol < 56) {
  345.                 fprintf(output,",%ld",val);
  346.                 outcol += 10;
  347.                 }
  348.         else    {
  349.                 nl();
  350.                 fprintf(output,"\tDC.l\t%ld",val);
  351.                 gentype = longgen;
  352.                 outcol = 25;
  353.                 }
  354. }
  355.  
  356. genref(sp,offset)
  357. SYM     *sp;
  358. int     offset;
  359. {       char    sign;
  360.         if( offset < 0) {
  361.                 sign = '-';
  362.                 offset = -offset;
  363.                 }
  364.         else
  365.                 sign = '+';
  366.         if( gentype == longgen && outcol < 55 - strlen(sp->name)) {
  367.                 if( sp->storage_class == sc_static)
  368.                         fprintf(output,",L%ld%c%d",sp->value.i,sign,offset);
  369.                 else
  370.                         fprintf(output,",_%s%c%d",sp->name,sign,offset);
  371.                 outcol += (11 + strlen(sp->name));
  372.                 }
  373.         else    {
  374.                 nl();
  375.                 if(sp->storage_class == sc_static)
  376.                     fprintf(output,"\tDS.l\t.%ld%c%d",sp->value.i,sign,offset);
  377.                 else
  378.                     fprintf(output,"\tDS.l\t_%s%c%d",sp->name,sign,offset);
  379.                 outcol = 26 + strlen(sp->name);
  380.                 gentype = longgen;
  381.                 }
  382. }
  383.  
  384. genstorage(nbytes)
  385. int     nbytes;
  386. {       nl();
  387.         fprintf(output,"\tDS.b\t%d\n",nbytes);
  388. }
  389.  
  390. gen_labref(n)
  391. int     n;
  392. {       if( gentype == longgen && outcol < 58) {
  393.                 fprintf(output,",.%d",n);
  394.                 outcol += 6;
  395.                 }
  396.         else    {
  397.                 nl();
  398.                 fprintf(output,"\tDS.l\t.%d",n);
  399.                 outcol = 22;
  400.                 gentype = longgen;
  401.                 }
  402. }
  403.  
  404. long     stringlit(s)
  405. /*
  406.  *      make s a string literal and return it's label number.
  407.  */
  408. char    *s;
  409. {       struct slit     *lp;
  410.         ++global_flag;          /* always allocate from global space. */
  411.         lp = xalloc(sizeof(struct slit));
  412.         lp->label = nextlabel++;
  413.         lp->str = litlate(s);
  414.         lp->next = strtab;
  415.         strtab = lp;
  416.         --global_flag;
  417.         return lp->label;
  418. }
  419.  
  420. dumplits()
  421. /*
  422.  *      dump the string literal pool.
  423.  */
  424. {       char            *cp;
  425.         while( strtab != 0) {
  426.                 cseg();
  427.                 nl();
  428.                 put_label((long)(strtab->label));
  429.                 cp = strtab->str;
  430.                 while(*cp)
  431.                         genbyte(*cp++);
  432.                 genbyte(0);
  433.                 strtab = strtab->next;
  434.                 }
  435.         nl();
  436. }
  437.  
  438. nl()
  439. {       if(outcol > 0) {
  440.                 fprintf(output,"\n");
  441.                 outcol = 0;
  442.                 gentype = nogen;
  443.                 }
  444. }
  445.  
  446. cseg()
  447. {       if( curseg != codeseg) {
  448.                 nl();
  449.                 fprintf(output,"\tCODE\n");
  450.                 curseg = codeseg;
  451.                 }
  452. }
  453.  
  454. dseg()
  455. {       if( curseg != dataseg) {
  456.                 nl();
  457.                 fprintf(output,"\tSECTION\t2,DATA\n");
  458.                 curseg = dataseg;
  459.                 }
  460. }
  461.  
  462.