⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cc4.c

📁 small c complier 它也Menuet OS的一个附件,同样他也是有汇编实现
💻 C
📖 第 1 页 / 共 2 页
字号:
      dumpstage();
    snext = 0;
  }

/*
** dump the staging buffer
*/
dumpstage()
  {
    int i;
    stail = snext;
    snext = stage;
    while(snext < stail)
      {
	if(optimize)
	  {
restart:
	    i = -1; 
	    while(++i <= HIGH_SEQ)
	      if(peep(seq[i]))
		{
#ifdef DISOPT
		  if(isatty(output))
		    fprintf(stderr, "                   optimized %2u\n", i);
#endif
		  goto restart;
		}
	  }
	outcode(snext[0], snext[1]);
	snext += 2;
      }
  }

/*
** change to a new segment
** may be called with NULL, CODESEG, or DATASEG
** With NASM the section names are case-sensitive
*/
toseg(newseg)
int newseg;
  {
    if(oldseg == newseg)
      return;
/*    if(oldseg == CODESEG)
      outline("_TEXT ENDS");
    else if(oldseg == DATASEG)
      outline("_DATA ENDS");  <-- */

/* - FASM
    if(newseg == CODESEG)
      {
	outline("SECTION .text");
      }
    else if(newseg == DATASEG)
      outline("SECTION .data");
*/
    oldseg = newseg;
  }

/*
** declare entry point
*/
public(ident) int ident;{
  if(ident == FUNCTION)
       toseg(CODESEG);
  else toseg(DATASEG);
/* - FASM
  outstr("GLOBAL ");
  outname(ssname);
*/
  newline();
  outname(ssname);
  if(ident == FUNCTION) {
    colon();
    newline();
    }
  }

/*
** declare external reference
*/
external(name, size, ident) char *name; int size, ident; {
  if(ident == FUNCTION)
       toseg(CODESEG);
  else toseg(DATASEG);
/* - FASM
  outstr("EXTERN ");
  outname(name);
/#  colon();
  outsize(size, ident);	<-- #/
  newline();
*/
  }

/*
** output the size of the object pointed to.
*/
outsize(size, ident) int size, ident;
  {
    /* why not size on FUNCTION and POINTER ? */
    if (ident == FUNCTION)
      outstr("NEAR");
    else if (ident == POINTER)
      outstr("DWORD");
    else if(size == 1)
      outstr("BYTE");
    else if(size == 2)
      outstr("WORD");
    else
      outstr("DWORD");
  }

/*
** point to following object(s)
*/
point() {
  outline(" DW $+2");
  }

/*
** dump the literal pool
*/
dumplits(size) int size;
{
  int j, k;
  k = 0;
  while (k < litptr)
    {
      if(size == 1)
	{
	  gen(BYTE_, NULL);
	}
      else if (size == 2)
	{
	  gen(WORD_, NULL);
	}
      else
	{
	  gen(DWORD_,NULL);
	}
      j = 10;
      while(j--)
	{
	  outdec(getint(litq + k, size));
	  k += size;
	  if(j == 0 || k >= litptr)
	    {
	      newline();
	      break;
	    }
	  fputc(',', output);
	}
    }
}

/*
** dump zeroes for default initial values
*/
dumpzero(size, count)
int size, count;
{
  if(count > 0)
    {
      if(size == 1)
	gen(BYTEr0, count);
      else if (size == 2)
	gen(WORDr0, count);
      else
	gen(DWORDr0, count);
    }
  }

/******************** optimizer functions ***********************/

/*
** Try to optimize sequence at snext in the staging buffer.
*/
peep(seq) int *seq; {
  int *next, *count, *pop, n, skip, tmp, reply;
  char c;
  next = snext;
  count = seq++;
  while(*seq) {
    switch(*seq) {
      case any:   if(next < stail)       break;      return (NO);
      case pfree: if(isfree(PRI, next))  break;      return (NO);
      case sfree: if(isfree(SEC, next))  break;      return (NO);
      case comm:  if(*next & COMMUTES)   break;      return (NO);
      case _pop:  if(pop = getpop(next)) break;      return (NO);
      default:    if(next >= stail || *next != *seq) return (NO);
      }
    next += 2; ++seq;
    }

  /****** have a match, now optimize it ******/

  *count += 1;
  reply = skip = NO;
  while(*(++seq) || skip) {
    if(skip) {
      if(*seq == 0) skip = NO;
      continue;
      }
    if(*seq >= PCODES) {
      c = *seq & 0xFF;            /* get low byte of command */
      n = c;                      /* and sign extend into n */
      switch(*seq & 0xFF00) {
        case ife:   if(snext[1] != n) skip = YES;  break;
        case ifl:   if(snext[1] >= n) skip = YES;  break;
        case go:    snext += (n<<1);               break;
        case gc:    snext[0] =  snext[(n<<1)];     goto done;
        case gv:    snext[1] =  snext[(n<<1)+1];   goto done;
        case sum:   snext[1] += snext[(n<<1)+1];   goto done;
        case neg:   snext[1] = -snext[1];          goto done;
        case topop: pop[0] = n; pop[1] = snext[1]; goto done;
        case swv:   tmp = snext[1];
                    snext[1] = snext[(n<<1)+1];
                    snext[(n<<1)+1] = tmp;
        done:       reply = YES;
                    break;
        }
      }
    else snext[0] = *seq;         /* set p-code */
    }
  return (reply);
  }

/*
** Is the primary or secondary register free?
** Is it zapped or unused by the p-code at pp
** or a successor?  If the primary register is
** unused by it still may not be free if the
** context uses the value of the expression.
*/
isfree(reg, pp) int reg, *pp; {
  char *cp;
  while(pp < stail) {
    cp = code[*pp];
    if(*cp & USES & reg) return (NO);
    if(*cp & ZAPS & reg) return (YES);
    pp += 2;
    }
  if(usexpr) return (reg & 001);   /* PRI => NO, SEC => YES at end */
  else       return (YES);
  }

/*
** Get place where the currently pushed value is popped?
** NOTE: Function arguments are not popped, they are
** wasted with an ADDSP.
*/
getpop(next) int *next; {
  char *cp;
  int level;  level = 0;
  while(YES) {
    if(next >= stail)                     /* compiler error */
      return 0;
    if(*next == POP2)
      if(level) --level;
      else return next;                   /* have a matching POP2 */
    else if(*next == ADDSP) {             /* after func call */
      if((level -= (next[1]>>LBPW)) < 0)
        return 0;
      }
    else {
      cp = code[*next];                   /* code string ptr */
      if(*cp & PUSHES) ++level;           /* must be a push */
      } 
    next += 2;
    }
  }

/******************* output functions *********************/

colon() {
  fputc(':', output);
  }

newline() {
  fputc('\15', output);
  fputc(NEWLINE, output);
  }

/*
** output assembly code.
** 
*/
outcode(pcode, value)
int pcode, value;
  {
    int part, skip, count;
    int byte_opt;
    char *cp, *back;
    int loc_label;
    part = back = 0;
    skip = NO;
    byte_opt = 0;
    
    cp = code[pcode] + 1;          /* skip 1st byte of code string */

#ifdef _MSC_VER

    switch (pcode)
      {
	case BYTE_:
	case BYTEn:
	case BYTEr0:
	case WORD_:
	case WORDn:
	case WORDr0:
	case DWORD_:
	case DWORDn:
	case DWORDr0:
	case REFm:
	case COMMAn:
	case PLUSn:
	  break;

	default:

	  dump_debug (pcode, value);
	  outtab ();
    }
#endif

    if (pcode == ADD1n)
      {
	if (value < 0)
	  {
	    pcode = SUB1n;
	    value = -value;
	  }
	if (value < 128)
	  {
	    byte_opt = 1;
	  }
      }
    
    while(*cp)
      {
	if(*cp == '<')
	  {
	    ++cp;                      /* skip to action code */
	    if(skip == NO)
	      switch(*cp)
		{
		  case 'm':
		    outname(value+NAME);
		    break; /* mem ref by label */
		  case 'n':
		    if (byte_opt)
		      {
			outstr ("BYTE ");
		      }
		    outdec(value);
		    break; /* numeric constant */
		  case 'o':
		    offset(value);
		    break; /* numeric constant */
		  case 'l':
		    outdec(litlab);
		    break; /* current literal label */
		  case 'g':	/* generate local label */
		    loc_label = getlabel ();
		    break;
		  case 'd':	/* dump local label */
		    outdec(loc_label);
		    break;
		}
	      cp += 2;                   /* skip past > */
	  }
	else if(*cp == '?')        /* ?..if value...?...if not value...? */
	  {
	    switch(++part)
	      {
		case 1:
		  if(value == 0)
		    skip = YES;
		  break;
		case 2:
		  skip = !skip;
		  break;
		case 3:
		  part = 0;
		  skip = NO;
		  break;
	      }
	    ++cp;                      /* skip past ? */
	  }
	else if(*cp == '#')
	  {        /* repeat #...# value times */
	    ++cp;
	    if(back == 0)
	      {
		if((count = value) < 1)
		  {
		    while(*cp && *cp++ != '#')
		      ;
		    continue;
		  }
		back = cp;
		continue;
	      }
	    if(--count > 0)
	      cp = back;
	    else
	      back = 0;
	  }
	else if(skip == NO)
	  fputc(*cp++, output);
	else
	  ++cp;
      }
  }

outdec(number)  int number; {
  int k, zs;
  char c, *q, *r;
  zs = 0;
  k = 1000000000;

#ifdef _MSC_VER
//  fprintf(output, "/* %d */", number);
#endif
  
  if(number < 0) {
    number = -number;
    fputc('-', output);
    }
  
  while (k >= 1) {
    q = 0;
    r = number;
    while(r >= k) {++q; r = r - k;}
    c = q + '0';
    if(c != '0' || k == 1 || zs) {
      zs = 1;
      fputc(c, output);
      }
    number = r;
    k /= 10;
    }
  }

offset(number)
int number;
{
  int k, zs;
  char c, *q, *r;
  zs = 0;
  k = 1000000000;
  if(number < 0) {
    number = -number;
    fputc('-', output);
    }
  else
    {
      fputc('+',output);
    }
  
  while (k >= 1) {
    q = 0;
    r = number;
    while(r >= k) {++q; r = r - k;}
    c = q + '0';
    if(c != '0' || k == 1 || zs) {
      zs = 1;
      fputc(c, output);
      }
    number = r;
    k /= 10;
    }
  }

outline(ptr)  char ptr[];  {
  outstr(ptr);
  newline();
  }

outname(ptr) char ptr[]; {
  outstr("_");
  while(*ptr >= ' ') fputc(*ptr++, output);
  }

outstr(ptr) char ptr[]; {
  while(*ptr == '\t' || *ptr >= ' ') fputc(*ptr++, output);
  }

outtab ()
  {
    fputc ('\t', output);
  }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -