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

📄 cc4.c

📁 A simple C compiler source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** 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])) {		    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 (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);    outstr("GLOBAL $");    outname(ssname);    newline();    outstr("$");    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);    outstr("EXTERN ");    outname(name);    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(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 __GNUC__    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:	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;    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 + -