📄 cc3.c
字号:
gen(GETd1n, 0); skip();}/* attempt at right to left - do it later */#ifdef LATERpushargs(ptr, nargs)char *ptr;int nargs;{ if (streq(lptr, ")") != 0) return; if (endst()) return; if (ptr) { expression(&consta, &val); gen(PUSH1, 0); } else { gen(PUSH1, 0); expression(&consta, &val); gen(SWAP1s, 0); /* don't push addr */ } nargs = nargs + INTSIZE; /* count args*BPW */ if (match(",") == 0) break;}#endifcallfunc(ptr)char *ptr; /* symbol table entry or 0 */{ int nargs, consta, val; nargs = 0; blanks(); /* already saw open paren */ while (streq(lptr, ")") == 0) { if (endst()) break; if (ptr) { expression(&consta, &val); gen(PUSH1, 0); } else { gen(PUSH1, 0); expression(&consta, &val); gen(SWAP1s, 0); /* don't push addr */ } nargs = nargs + INTSIZE; /* count args*BPW */ if (match(",") == 0) break; } need(")"); if (ptr && (streq(ptr + NAME, "CCARGC") == 0)) /* accessing ... like va_args */ gen(ARGCNTn, nargs >> LBPD); /* to get start of frame */ if (ptr) gen(CALLm, ptr); else gen(CALL1, 0); gen(ADDSP, csp + nargs);}/*** true if is2's operand should be doubled*/fdouble(oper, is1, is2)int oper, is1[], is2[];{ ////////////////////////////////////////////////////// // This is a 'magic' function, its usage and function // are not so obvious // // Purpose: when indexing an address we must know // what we are pointing at so that the indexsize is // proper, e,g, // charptr++, should multiply index by a 1 // shortptr++, should multiply index by a 2 // intptr++, should multiply index by a 4 // // Algorithm: // IF // operation is ADD12 or SUB12 // AND // is1 is an address (pointer, array or via & operator // AND // is2 is NOT an address (pointer, array or via & operator // THEN // return the multiplication factor based on s1 (or true) // ELSE // return 0 (or false) // // Usage: The return value is used as a 'boolean' // for nonconstant values, indicating that runtime code // is necessary to do the necessary multiplication // For contant value the return value is used to do a compile-time // multiplication (shift actually) // if ((oper == ADD12 || oper == SUB12) && (is2[TA] == 0)) { switch (is1[TA] >> 2) { default: case 1: // char return (0); case 2: // short return (1); case 4: // int return (2); } } return (0);}step(oper, is, oper2)int oper, is[], oper2;{ fetch(is); gen(oper, is[TA] ? (is[TA] >> 2) : 1); store(is); if (oper2) gen(oper2, is[TA] ? (is[TA] >> 2) : 1);}store(is)int is[];{ char *ptr; if (is[TI]) { /* putstk */ if (is[TI] >> 2 == 1) { gen(PUTbp1, 0); } else if (is[TI] >> 2 == 2) { gen(PUTwp1, 0); } else { gen(PUTdp1, 0); } } else { /* putmem */ ptr = is[ST]; if (ptr[IDENT] == POINTER) { gen(PUTdm1, ptr); } else if (ptr[TYPE] >> 2 == 1) { gen(PUTbm1, ptr); } else if (ptr[TYPE] >> 2 == BPW) { gen(PUTwm1, ptr); } else { gen(PUTdm1, ptr); } }}fetch(is)int is[];{ char *ptr; ptr = is[ST]; if (is[TI]) { /* indirect */ if (is[TI] >> 2 == BPD) { /* pointer to DWORD */ gen(GETd1p, 0); } else if (is[TI] >> 2 == BPW) { /* pointer to WORD */ gen(GETw1p, 0); } else { if (ptr[TYPE] & UNSIGNED) gen(GETb1pu, 0); else gen(GETb1p, 0); } } else { /* direct */ if (ptr[IDENT] == POINTER) { gen(GETd1m, ptr); } else if (ptr[TYPE] >> 2 == BPD) { gen(GETd1m, ptr); } else if (ptr[TYPE] >> 2 == BPW) { gen(GETw1m, ptr); } else { if (ptr[TYPE] & UNSIGNED) gen(GETb1mu, ptr); else gen(GETb1m, ptr); } }}constant(is)int is[];{ int offset; if (is[TC] = number(is + CV)) { gen(GETd1n, is[CV]); } else if (is[TC] = chrcon(is + CV)) { gen(GETd1n, is[CV]); } else if (string(&offset)) { gen(POINT1l, offset); } else { return 0; } return 1;}number(value)int *value;{ int k, minus; k = minus = 0; while (1) { if (match("+")); else if (match("-")) minus = 1; else break; } if (isdigit(ch) == 0) return 0; if (ch == '0') { while (ch == '0') inbyte(); if (toupper(ch) == 'X') { inbyte(); while (isxdigit(ch)) { if (isdigit(ch)) k = k * 16 + (inbyte() - '0'); else k = k * 16 + 10 + (toupper(inbyte()) - 'A'); } } else while (ch >= '0' && ch <= '7') k = k * 8 + (inbyte() - '0'); } else while (isdigit(ch)) k = k * 10 + (inbyte() - '0'); if (minus) { *value = -k; return (INT); } if ((*value = k) < 0) return (UINT); else return (INT);}chrcon(value)int *value;{ int k; k = 0; if (match("'") == 0) return 0; while (ch != '\'') k = (k << 8) + (litchar() & 255); gch(); *value = k; return (INT);}string(offset)int *offset;{ char c; if (match(quote) == 0) return 0; *offset = litptr; while (ch != '"') { if (ch == 0) break; stowlit(litchar(), 1); } gch(); litq[litptr++] = 0; return 1;}stowlit(value, size)int value, size;{ if ((litptr + size) >= LITMAX) { error("literal queue overflow"); exit(ERRCODE); } putint(value, litq + litptr, size); litptr += size;}litchar(){ int i, oct; if (ch != '\\' || nch == 0) return gch(); gch(); switch (ch) { case 'n': gch(); return NEWLINE; case 't': gch(); return 9; /* HT */ case 'b': gch(); return 8; /* BS */ case 'f': gch(); return 12; /* FF */ } i = 3; oct = 0; while ((i--) > 0 && ch >= '0' && ch <= '7') oct = (oct << 3) + gch() - '0'; if (i == 2) return gch(); else return oct;}/***************** pipeline functions ******************//*** skim over terms adjoining || and && operators*/skim(opstr, tcode, dropval, endval, level, is)char *opstr;int tcode, dropval, endval, (*level) (), is[];{ int k, droplab, endlab; droplab = 0; while (1) { k = down1(level, is); if (nextop(opstr)) { bump(opsize); if (droplab == 0) droplab = getlabel(); dropout(k, tcode, droplab, is); } else if (droplab) { dropout(k, tcode, droplab, is); gen(GETd1n, endval); gen(JMPm, endlab = getlabel()); gen(LABm, droplab); gen(GETd1n, dropval); gen(LABm, endlab); is[TI] = is[TA] = is[TC] = is[CV] = is[SA] = 0; return 0; } else return k; }}/*** test for early dropout from || or && sequences*/dropout(k, tcode, exit1, is)int k, tcode, exit1, is[];{ if (k) fetch(is); else if (is[TC]) { gen(GETd1n, is[CV]); } gen(tcode, exit1); /* jumps on false */}/*** drop to a lower level*/down(opstr, opoff, level, is)char *opstr;int opoff, (*level) (), is[];{ int k; k = down1(level, is); if (nextop(opstr) == 0) return k; if (k) fetch(is); while (1) { if (nextop(opstr)) { int is2[7]; /* allocate only if needed */ null_is(is2); bump(opsize); opindex += opoff; down2(op[opindex], op2[opindex], level, is, is2); } else return 0; }}/*** unary drop to a lower level*/down1(level, is)int (*level) (), is[];{ int k, *before, *start; setstage(&before, &start); k = (*level) (is); if (is[TC]) clearstage(before, 0); /* load constant later */ return k;}/*** binary drop to a lower level*/down2(oper, oper2, level, is, is2)int oper, oper2, (*level) (), is[], is2[];{ int *before, *start; char *ptr; int value; setstage(&before, &start); is[SA] = 0; /* not "... op 0" syntax */ if (is[TC]) { /* consant op unknown */ if (down1(level, is2)) fetch(is2); if (is[CV] == 0) is[SA] = snext; gen(GETw2n, is[CV] << fdouble(oper, is2, is)); } else { /* variable op unknown */ gen(PUSH1, 0); /* at start in the buffer */ if (down1(level, is2)) fetch(is2); if (is2[TC]) { /* variable op constant */ if (is2[CV] == 0) is[SA] = start; csp += BPD; /* adjust stack and */ clearstage(before, 0); /* discard the PUSH */ if (oper == ADD12) { /* commutative */ gen(GETd2n, is2[CV] << fdouble(oper, is, is2)); } else { /* non-commutative */ gen(MOVE21, 0); gen(GETd1n, is2[CV] << fdouble(oper, is, is2)); } } else { /* variable op variable */ gen(POP2, 0); if (value = fdouble(oper, is, is2)) { gen(DBL1, 0); // index size 2 if (value > 1) gen(DBL1, 0); // .. or even 4 } if (value = fdouble(oper, is2, is)) { gen(DBL2, 0); if (value > 1) gen(DBL2, 0); } } } if (oper) { if (nosign(is) || nosign(is2)) oper = oper2; if (is[TC] = is[TC] & is2[TC]) { /* constant result */ is[CV] = calc(is[CV], oper, is2[CV]); clearstage(before, 0); if (is2[TC] == UINT) is[TC] = UINT; } else { /* variable result */ gen(oper, 0); if (oper == SUB12 && is[TA] >> 2 == BPW && is2[TA] >> 2 == BPW) { /* difference of two word addresses */ gen(SWAP12, 0); gen(GETw1n, 1); gen(ASR12, 0); /* div by 2 */ } is[OP] = oper; /* identify the operator */ } if (oper == SUB12 || oper == ADD12) { if (is[TA] && is2[TA]) /* addr +/- addr */ is[TA] = 0; else if (is2[TA]) { /* value +/- addr */ is[ST] = is2[ST]; is[TI] = is2[TI]; is[TA] = is2[TA]; } } if (is[ST] == 0 || ((ptr = is2[ST]) && (ptr[TYPE] & UNSIGNED))) is[ST] = is2[ST]; }}/*** unsigned operand?*/nosign(is)int is[];{ char *ptr; if (is[TA] || is[TC] == UINT || ((ptr = is[ST]) && (ptr[TYPE] & UNSIGNED)) ) return 1; return 0;}/*** calcualte signed constant result*/calc(left, oper, right)int left, oper, right;{ switch (oper) { case ADD12: return (left + right); case SUB12: return (left - right); case MUL12: return (left * right); case DIV12: return (left / right); case MOD12: return (left % right); case EQ12: return (left == right); case NE12: return (left != right); case LE12: return (left <= right); case GE12: return (left >= right); case LT12: return (left < right); case GT12: return (left > right); case AND12: return (left & right); case OR12: return (left | right); case XOR12: return (left ^ right); case ASR12: return (left >> right); case ASL12: return (left << right); } return (calc2(left, oper, right));}/*** calcualte unsigned constant result*/calc2(left, oper, right)unsigned left, right;int oper;{ switch (oper) { case MUL12u: return (left * right); case DIV12u: return (left / right); case MOD12u: return (left % right); case LE12u: return (left <= right); case GE12u: return (left >= right); case LT12u: return (left < right); case GT12u: return (left > right); } return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -