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

📄 cc4.c

📁 A simple C compiler source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Small-C Compiler -- Part 4 -- Back End.** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix** Copyright 1998 H T Walheim** All rights reserved.*/#include <stdio.h>#include "cc.h"/*************************** externals ****************************/extern char*cptr, *macn, *litq, *symtab, optimize, ssname[NAMESIZE];extern int*stage, litlab, litptr, csp, output, oldseg, usexpr,    *snext, *stail, *slast;/***************** optimizer command definitions ******************/	     /*     --      p-codes must not overlap these */#define any     0x00FF		/* matches any p-code */#define _pop    0x00FE		/* matches if corresponding POP2 exists */#define pfree   0x00FD		/* matches if pri register free */#define sfree   0x00FC		/* matches if sec register free */#define comm    0x00FB		/* matches if registers are commutative */	     /*     --      these digits are reserved for n */#define go      0x0100		/* go n entries */#define gc      0x0200		/* get code from n entries away */#define gv      0x0300		/* get value from n entries away */#define sum     0x0400		/* add value from nth entry away */#define neg     0x0500		/* negate the value */#define ife     0x0600		/* if value == n do commands to next 0 */#define ifl     0x0700		/* if value <  n do commands to next 0 */#define swv     0x0800		/* swap value with value n entries away */#define topop   0x0900		/* moves |code and current value to POP2 */#define p1      0x0001		/* plus 1 */#define p2      0x0002		/* plus 2 */#define p3      0x0003		/* plus 3 */#define p4      0x0004		/* plus 4 */#define m1      0x00FF		/* minus 1 */#define m2      0x00FE		/* minus 2 */#define m3      0x00FD		/* minus 3 */#define m4      0x00FC		/* minus 4 */#define PRI      0030		/* primary register bits */#define SEC      0003		/* secondary register bits */#define USES     0011		/* use register contents */#define ZAPS     0022		/* zap register contents */#define PUSHES   0100		/* pushes onto the stack */#define COMMUTES 0200		/* commutative p-code *//******************** optimizer command lists *********************/int seq00[] = { 0, ADD12, MOVE21, 0,	/* ADD21 */    go | p1, ADD21, 0}, seq01[] = {    0, ADD1n, 0,		/* rINC1 or rDEC1 ? */ifl | m2, 0, ifl | 0, rDEC1, neg, 0, ifl | p3, rINC1, 0, 0}, seq02[] = {    0, ADD2n, 0,		/* rINC2 or rDEC2 ? */ifl | m2, 0, ifl | 0, rDEC2, neg, 0, ifl | p3, rINC2, 0, 0}, seq03[] = {    0, rDEC1, PUTbp1, rINC1, 0,	/* SUBbpn or DECbp */go | p2, ife | p1, DECbp, 0, SUBbpn, 0}, seq04[] = {    0, rDEC1, PUTwp1, rINC1, 0,	/* SUBwpn or DECwp */go | p2, ife | p1, DECwp, 0, SUBwpn, 0}, seq05[] = {    0, rDEC1, PUTbm1, rINC1, 0,	/* SUB_m_ COMMAn */go | p1, SUB_m_, go | p1, COMMAn, go | m1, 0}, seq06[] = {    0, rDEC1, PUTwm1, rINC1, 0,	/* SUB_m_ COMMAn */go | p1, SUB_m_, go | p1, COMMAn, go | m1, 0}, seq07[] = {    0, GETw1m, GETw2n, ADD12, MOVE21, GETb1p, 0,	/* GETw2m GETb1p */go | p4, gv | m3, go | m1, GETw2m, gv | m3, 0}, seq08[] = {    0, GETw1m, GETw2n, ADD12, MOVE21, GETb1pu, 0,	/* GETw2m GETb1pu */go | p4, gv | m3, go | m1, GETw2m, gv | m3, 0}, seq09[] = {    0, GETw1m, GETw2n, ADD12, MOVE21, GETw1p, 0,	/* GETw2m GETw1p */go | p4, gv | m3, go | m1, GETw2m, gv | m3, 0}, seq10[] = {    0, GETw1m, GETw2m, SWAP12, 0,	/* GETw2m GETw1m */go | p2, GETw1m, gv | m1, go | m1, gv | m1, 0}, seq11[] = {    0, GETw1m, MOVE21, 0,	/* GETw2m */go | p1, GETw2m, gv | m1, 0}, seq12[] = {    0, GETw1m, PUSH1, pfree, 0,	/* PUSHm */go | p1, PUSHm, gv | m1, 0}, seq13[] = {    0, GETw1n, PUTbm1, pfree, 0,	/* PUT_m_ COMMAn */PUT_m_, go | p1, COMMAn, go | m1, swv | p1, 0}, seq14[] = {    0, GETw1n, PUTwm1, pfree, 0,	/* PUT_m_ COMMAn */PUT_m_, go | p1, COMMAn, go | m1, swv | p1, 0}, seq15[] = {    0, GETw1p, PUSH1, pfree, 0,	/* PUSHp */go | p1, PUSHp, gv | m1, 0}, seq16[] = {    0, GETw1s, GETw2n, ADD12, MOVE21, 0,	/* GETw2s ADD2n */go | p3, ADD2n, gv | m2, go | m1, GETw2s, gv | m2, 0}, seq17[] = {    0, GETw1s, GETw2s, SWAP12, 0,	/* GETw2s GETw1s */go | p2, GETw1s, gv | m1, go | m1, GETw2s, gv | m1, 0}, seq18[] = {    0, GETw1s, MOVE21, 0,	/* GETw2s */go | p1, GETw2s, gv | m1, 0}, seq19[] = {    0, GETw2m, GETw1n, SWAP12, SUB12, 0,	/* GETw1m SUB1n */go | p3, SUB1n, gv | m2, go | m1, GETw1m, gv | m2, 0}, seq20[] = {    0, GETw2n, ADD12, 0,	/* ADD1n */go | p1, ADD1n, gv | m1, 0}, seq21[] = {    0, GETw2s, GETw1n, SWAP12, SUB12, 0,	/* GETw1s SUB1n */go | p3, SUB1n, gv | m2, go | m1, GETw1s, gv | m2, 0}, seq22[] = {    0, rINC1, PUTbm1, rDEC1, 0,	/* ADDm_ COMMAn */go | p1, ADDm_, go | p1, COMMAn, go | m1, 0}, seq23[] = {    0, rINC1, PUTwm1, rDEC1, 0,	/* ADDm_ COMMAn */go | p1, ADDm_, go | p1, COMMAn, go | m1, 0}, seq24[] = {    0, rINC1, PUTbp1, rDEC1, 0,	/* ADDbpn or INCbp */go | p2, ife | p1, INCbp, 0, ADDbpn, 0}, seq25[] = {    0, rINC1, PUTwp1, rDEC1, 0,	/* ADDwpn or INCwp */go | p2, ife | p1, INCwp, 0, ADDwpn, 0}, seq26[] = {    0, MOVE21, GETw1n, SWAP12, SUB12, 0,	/* SUB1n */go | p3, SUB1n, gv | m2, 0}, seq27[] = {    0, MOVE21, GETw1n, comm, 0,	/* GETw2n comm */go | p1, GETw2n, 0}, seq28[] = {    0, POINT1m, GETw2n, ADD12, MOVE21, 0,	/* POINT2m_ PLUSn */go | p3, PLUSn, gv | m2, go | m1, POINT2m_, gv | m2, 0}, seq29[] = {    0, POINT1m, MOVE21, pfree, 0,	/* POINT2m */go | p1, POINT2m, gv | m1, 0}, seq30[] = {    0, POINT1m, PUSH1, pfree, _pop, 0,	/* ... POINT2m */topop | POINT2m, go | p2, 0}, seq31[] = {    0, POINT1s, GETw2n, ADD12, MOVE21, 0,	/* POINT2s */sum | p1, go | p3, POINT2s, gv | m3, 0}, seq32[] = {    0, POINT1s, PUSH1, MOVE21, 0,	/* POINT2s PUSH2 */go | p1, POINT2s, gv | m1, go | p1, PUSH2, go | m1, 0}, seq33[] = {    0, POINT1s, PUSH1, pfree, _pop, 0,	/* ... POINT2s */topop | POINT2s, go | p2, 0}, seq34[] = {    0, POINT1s, MOVE21, 0,	/* POINT2s */go | p1, POINT2s, gv | m1, 0}, seq35[] = {    0, POINT2m, GETb1p, sfree, 0,	/* GETb1m */go | p1, GETb1m, gv | m1, 0}, seq36[] = {    0, POINT2m, GETb1pu, sfree, 0,	/* GETb1mu */go | p1, GETb1mu, gv | m1, 0}, seq37[] = {    0, POINT2m, GETw1p, sfree, 0,	/* GETw1m */go | p1, GETw1m, gv | m1, 0}, seq38[] = {    0, POINT2m_, PLUSn, GETw1p, sfree, 0,	/* GETw1m_ PLUSn */go | p2, gc | m1, gv | m1, go | m1, GETw1m_, gv | m1, 0}, seq39[] = {    0, POINT2s, GETb1p, sfree, 0,	/* GETb1s */sum | p1, go | p1, GETb1s, gv | m1, 0}, seq40[] = {    0, POINT2s, GETb1pu, sfree, 0,	/* GETb1su */sum | p1, go | p1, GETb1su, gv | m1, 0}, seq41[] = {    0, POINT2s, GETw1p, PUSH1, pfree, 0,	/* PUSHs */sum | p1, go | p2, PUSHs, gv | m2, 0}, seq42[] = {    0, POINT2s, GETw1p, sfree, 0,	/* GETw1s */sum | p1, go | p1, GETw1s, gv | m1, 0}, seq43[] = {    0, PUSH1, any, POP2, 0,	/* MOVE21 any */go | p2, gc | m1, gv | m1, go | m1, MOVE21, 0}, seq44[] = {    0, PUSHm, _pop, 0,		/* ... GETw2m */topop | GETw2m, go | p1, 0}, seq45[] = {    0, PUSHp, any, POP2, 0,	/* GETw2p ... */go | p2, gc | m1, gv | m1, go | m1, GETw2p, gv | m1, 0}, seq46[] = {    0, PUSHs, _pop, 0,		/* ... GETw2s */topop | GETw2s, go | p1, 0}, seq47[] = {    0, SUB1n, 0,		/* rDEC1 or rINC1 ? */ifl | m2, 0, ifl | 0, rINC1, neg, 0, ifl | p3, rDEC1, 0, 0};#define HIGH_SEQ  47int seq[HIGH_SEQ + 1];setseq(){    seq[0] = seq00;    seq[1] = seq01;    seq[2] = seq02;    seq[3] = seq03;    seq[4] = seq04;    seq[5] = seq05;    seq[6] = seq06;    seq[7] = seq07;    seq[8] = seq08;    seq[9] = seq09;    seq[10] = seq10;    seq[11] = seq11;    seq[12] = seq12;    seq[13] = seq13;    seq[14] = seq14;    seq[15] = seq15;    seq[16] = seq16;    seq[17] = seq17;    seq[18] = seq18;    seq[19] = seq19;    seq[20] = seq20;    seq[21] = seq21;    seq[22] = seq22;    seq[23] = seq23;    seq[24] = seq24;    seq[25] = seq25;    seq[26] = seq26;    seq[27] = seq27;    seq[28] = seq28;    seq[29] = seq29;    seq[30] = seq30;    seq[31] = seq31;    seq[32] = seq32;    seq[33] = seq33;    seq[34] = seq34;    seq[35] = seq35;    seq[36] = seq36;    seq[37] = seq37;    seq[38] = seq38;    seq[39] = seq39;    seq[40] = seq40;    seq[41] = seq41;    seq[42] = seq42;    seq[43] = seq43;    seq[44] = seq44;    seq[45] = seq45;    seq[46] = seq46;    seq[47] = seq47;}/***************** assembly-code strings ******************/int code[PCODES];/*** First byte contains flag bits indicating:**    the value in ax is needed (010) or zapped (020)**    the value in bx is needed (001) or zapped (002)*/setcodes(){    setseq();    code[ADD12] = "\211ADD EAX,EBX\n";    code[ADD1n] = "\010?ADD EAX,<n>\n??";    code[ADD21] = "\211ADD EBX,EAX\n";    code[ADD2n] = "\010?ADD EBX,<n>\n??";    code[ADDbpn] = "\001ADD BYTE [EBX],<n>\n";    code[ADDwpn] = "\001ADD WORD [EBX],<n>\n";    code[ADDm_] = "\000ADD <m>";    code[ADDSP] = "\000?ADD ESP,<n>\n??";    code[AND12] = "\211AND EAX,EBX\n";    code[ANEG1] = "\010NEG EAX\n";    code[ARGCNTn] = "\000?MOV CL,<n>?XOR CL,CL?\n";    code[ASL12] = "\011MOV ECX,EAX\n\tMOV EAX,EBX\n\tSAL EAX,CL\n";    code[ASR12] = "\011MOV ECX,EAX\n\tMOV EAX,EBX\n\tSAR EAX,CL\n";    code[CALL1] = "\010CALL EAX\n";    code[CALLm] = "\020CALL $<m>\n";    code[BYTE_] = "\000 DB ";    code[BYTEn] = "\000 RESB <n>\n";    code[BYTEr0] = "\000 TIMES <n> DB 0\n";    code[COM1] = "\010NOT EAX\n";    code[COMMAn] = "\000,<n>\n";    code[DBL1] = "\010SHL EAX,1\n";    code[DBL2] = "\001SHL EBX,1\n";    code[DECbp] = "\001DEC BYTE [EBX]\n";    code[DECwp] = "\001DEC WORD [EBX]\n";    code[DIV12] = "\011CDQ\n\tIDIV EBX\n";	/* see gen() */    code[DIV12u] = "\011XOR EDX,EDX\n\tDIV EBX\n";	/* see gen() */    code[DWORD_] = "\000 DD ";    code[DWORDn] = "\000 DD <n>\n";    code[DWORDr0] = "\000 TIMES <n> DD 0\n";    code[ENTER] = "\100PUSH EBP\n\tMOV EBP,ESP\n";    code[EQ10f] = "\010<g>OR EAX,EAX\n\tJE _<d>\n\tJMP _<n>\n_<d>:\n";    code[EQ12] = ""; //   code[EQ12] = "\211CALL __eq\n";    code[GE10f] = "\010<g>OR EAX,EAX\n\tJGE _<d>\n\tJMP _<n>\n_<d>:\n";    code[GE12] = "";//    code[GE12] = "\011CALL __ge\n";//    code[GE12u] = "\011CALL __uge\n";    code[GE12u] = "";    code[GETb1m] = "\020MOVSX EAX,BYTE [$<m>]\n";    code[GETb1mu] = "\020MOVZX EAX,BYTE [$<m>]\n";    code[GETb1p] = "\021MOVSX EAX,BYTE [EBX?<o>??]\n";	/* see gen() */    code[GETb1pu] = "\021MOVZX EAX,BYTE [EBX?<o>??]\n";	/* see gen() */    code[GETb1s] = "\020MOVSX EAX,BYTE [EBP<o>]\n";    code[GETb1su] = "\020MOVZX EAX,BYTE [EBP<o>]\n";    code[GETd1m] = "\020MOV EAX,[$<m>]\n";    code[GETd1n] = "\020?MOV EAX,<n>?XOR EAX,EAX?\n";    code[GETd1p] = "\021MOV EAX, [EBX?<o>??]\n";	/* see gen() */    code[GETd2n] = "\002?MOV EBX,<n>?XOR EBX,EBX?\n";    code[GETw1m] = "\020MOVSX EAX,WORD [$<m>]\n";    code[GETw1m_] = "\020MOVSX EAX,WORD [$<m>]";    code[GETw1n] = "\020?MOV  EAX,<n>?XOR EAX,EAX?\n";    code[GETw1p] = "\021MOVSX EAX, WORD [EBX?<o>??]\n";	/* see gen() */    code[GETw1s] = "\020MOVSX EAX, WORD [EBP<o>]\n";    code[GETw2m] = "\002MOVSX EBX,WORD <m>\n";    code[GETw2n] = "\002?MOV EBX,<n>?XOR EBX,EBX?\n";    code[GETw2p] = "\021MOVSX EBX,WORD [EBX?<o>??]\n";    code[GETw2s] = "\002MOVSX EBX,WORD [EBP<o>]\n";    code[GT10f] = "\010<g>OR EAX,EAX\n\tJG _<d>\n\tJMP _<n>\n_<d>:\n";    code[GT12] = "";//    code[GT12] = "\010CALL __gt\n";    code[GT12u] = "";//    code[GT12u] = "\011CALL __ugt\n";    code[INCbp] = "\001INC BYTE [EBX]\n";    code[INCwp] = "\001INC WORD [EBX]\n";    code[WORD_] = "\000 DW ";    code[WORDn] = "\000 RESW <n>\n";    code[WORDr0] = "\000 TIMES <n> DW 0\n";    code[JMPm] = "\000JMP _<n>\n";    code[LABm] = "\000_<n>:\n";    code[LE10f] = "\010<g>OR EAX,EAX\n\tJLE _<d>\n\tJMP _<n>\n_<d>:\n";    code[LE12] = "";//    code[LE12] = "\011CALL __le\n";    code[LE12u] = "";    code[LNEG1] = "";    code[LT10f] = "\010<g>OR EAX,EAX\n\tJL _<d>\n\tJMP _<n>\n_<d>:\n";    code[LT12] = "";//    code[LT12] = "\011CALL __lt\n";    code[LT12u] = "";    code[MOD12] = "\011CDQ\n\tIDIV EBX\n\tMOV EAX,EDX\n";	/* see gen() */    code[MOD12u] = "\011XOR EDX,EDX\n\tDIV EBX\n\tMOV EAX,EDX\n";	/* see gen() */    code[MOVE21] = "\012MOV EBX,EAX\n";    code[MUL12] = "\211IMUL EBX\n";    code[MUL12u] = "\211MUL EBX\n";    code[NE10f] = "\010<g>OR EAX,EAX\n\tJNE _<d>\n\tJMP _<n>\n\t_<d>:\n";    code[NE12] = "";    code[NEARm] = "\000 DD _<n>\n";    code[OR12] = "\211OR EAX,EBX\n";    code[PLUSn] = "\000?+<n>??\n";    code[POINT1l] = "\020MOV EAX,_<l>+<n>\n";    code[POINT1m] = "\020MOV EAX,<m>\n";    code[POINT1s] = "\020LEA EAX,[EBP<o>]\n";    code[POINT2m] = "\002MOV EBX,<m>\n";    code[POINT2m_] = "\002MOV EBX,<m>";    code[POINT2s] = "\002LEA EBX,[EBP<o>]\n";    code[POP2] = "\002POP EBX\n";    code[PUSH1] = "\110PUSH EAX\n";    code[PUSH2] = "\101PUSH EBX\n";    code[PUSHm] = "\100PUSH $<m>\n";    code[PUSHp] = "\100PUSH [EBX?<o>??]\n";    code[PUSHs] = "\100PUSH [EBP?<o>??]\n";    code[PUT_m_] = "\000MOV $<m>";    code[PUTbm1] = "\010MOV BYTE [$<m>],AL\n";    code[PUTbp1] = "\011MOV [EBX],AL\n";    code[PUTdm1] = "\010MOV DWORD [$<m>],EAX\n";    code[PUTdp1] = "\011MOV [EBX],EAX\n";    code[PUTwm1] = "\010MOV WORD [$<m>],AX\n";    code[PUTwp1] = "\011MOV [EBX],AX\n";    code[rDEC1] = "\010#DEC EAX\n#";    code[rDEC2] = "\010#DEC EBX\n#";    code[REFm] = "\000_<n>";    code[RETURN] = "\000?MOV ESP,EBP\n\t??POP EBP\n\tRET\n";    code[rINC1] = "\010#INC EAX\n#";    code[rINC2] = "\010#INC EBX\n#";    code[SUB_m_] = "\000SUB $<m>";    code[SUB12] = "\011SUB EAX,EBX\n";	/* see gen() */    code[SUB1n] = "\010?SUB EAX,<n>\n??";    code[SUBbpn] = "\001SUB [EBX],<n>\n";    code[SUBwpn] = "\001SUB [EBX],<n>\n";    code[SWAP12] = "\011XCHG EAX,EBX\n";    code[SWAP1s] = "\012POP EBX\n\tXCHG EAX,EBX\n\tPUSH EBX\n";    code[SWITCH] = "";    code[XOR12] = "\211XOR EAX,EBX\n";}/***************** code generation functions *****************//*** print all assembler info before any code is generated** and ensure that the segments appear in the correct order.*/header(){    toseg(CODESEG);    outline("; Compiled with Simple C - http://retro.tunes.org/simplec");/*    outline("EXTERN __eq");    outline("EXTERN __ne");    outline("EXTERN __le");    outline("EXTERN __lt");    outline("EXTERN __ge");    outline("EXTERN __gt");    outline("EXTERN __ule");    outline("EXTERN __ult");    outline("EXTERN __uge");    outline("EXTERN __ugt");    outline("EXTERN __lneg");    outline("EXTERN __switch");*/    toseg(DATASEG);}/*** print any assembler stuff needed at the end*/trailer(){    char *cp;    cptr = STARTGLB;    while (cptr < ENDGLB) {	if (cptr[IDENT] == FUNCTION && cptr[CLASS] == AUTOEXT)	    external(cptr + NAME, 0, FUNCTION);	cptr += SYMMAX;    }    toseg(NULL);    outline("END");}/*** remember where we are in the queue in case we have to back up.*/setstage(before, start)int *before, *start;{    if ((*before = snext) == 0)	snext = stage;    *start = snext;}/*** generate code in staging buffer.*/gen(pcode, value)int pcode, value;{    int newcsp;    switch (pcode) {    case GETb1pu:    case GETb1p:    case GETw1p:    case GETd1p:	gen(MOVE21, 0);	break;    case SUB12:    case MOD12:    case MOD12u:    case DIV12:    case DIV12u:	gen(SWAP12, 0);	break;    case PUSH1:	csp -= BPD;	break;    case POP2:	csp += BPD;	break;    case ADDSP:    case RETURN:	newcsp = value;	value -= csp;	csp = newcsp;    }    if (snext == 0) {	outcode(pcode, value);	return;    }    if (snext >= slast) {	error("staging buffer overflow");	return;    }    snext[0] = pcode;    snext[1] = value;    snext += 2;}/*** dump the contents of the queue.** If start = 0, throw away contents.** If before != 0, don't dump queue yet.*/clearstage(before, start)int *before, *start;{    if (before) {	snext = before;	return;    }    if (start)	dumpstage();    snext = 0;}

⌨️ 快捷键说明

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