📄 cc4.c
字号:
/*** 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 + -