|
|
1.1 ! root 1: /* ! 2: * C compiler. ! 3: * Intel iAPX-86 et al. ! 4: * Prologs, etc. ! 5: */ ! 6: #ifdef vax ! 7: #include "INC$LIB:cc2.h" ! 8: #else ! 9: #include "cc2.h" ! 10: #endif ! 11: ! 12: int framesize; ! 13: int hasfloat; ! 14: static SYM *countp; ! 15: ! 16: /* ! 17: * Generate code for the ALIGN operation. ! 18: * The 'align' argument is ignored because there ! 19: * is only one style of alignment on the 8086: ! 20: * simple word alignment. ! 21: */ ! 22: genalign(align) ! 23: { ! 24: if ((dot&01) == 0) ! 25: return; ! 26: if (isvariant(VASM)) { ! 27: bput(ALIGN); iput(align); ! 28: } else if (dotseg == SBSS) ! 29: ++dot; ! 30: else ! 31: outab(0); ! 32: } ! 33: ! 34: /* ! 35: * Generate code for a function prologue. ! 36: */ ! 37: genprolog() ! 38: { ! 39: register int lab; ! 40: register SYM *labp; ! 41: ! 42: hasfloat = 0; ! 43: if (isvariant(VASM)) { ! 44: genone(ZPUSH, A_RSI); ! 45: genone(ZPUSH, A_RDI); ! 46: if (notvariant(V80186) || (framesize == 0) || isvariant(VPROF)) { ! 47: genone(ZPUSH, A_RBP); ! 48: gentwo(ZMOV, A_RBP, A_RSP); ! 49: } ! 50: if (isvariant(VPROF)) { ! 51: genseg(SBSS); ! 52: bput(LLABEL); iput(lab=newlab()); ! 53: genblock((sizeof_t)8); ! 54: genseg(SCODE); ! 55: gentwo(ZMOV, A_RBX, A_IMM|A_LID, lab); ! 56: genone(ZCALL, A_GID|A_DIR, "scount"); ! 57: } ! 58: if (framesize != 0) { ! 59: if (isvariant(V80186) && notvariant(VPROF)) ! 60: gentwo(ZENTER, A_IMM|A_OFFS, framesize, A_IMM|A_OFFS, 0); ! 61: else { ! 62: if (framesize <= 2) ! 63: genone(ZPUSH, A_RAX); ! 64: else ! 65: gentwo(ZSUB, A_RSP, A_OFFS|A_IMM, framesize); ! 66: } ! 67: } ! 68: } else { ! 69: outab(0x56); /* push si */ ! 70: outab(0x57); /* push di */ ! 71: if (notvariant(V80186) || (framesize == 0) || isvariant(VPROF)) { ! 72: outab(0x55); /* push bp */ ! 73: outab(0x8B); /* mov bp, sp */ ! 74: outab(0xEC); ! 75: } ! 76: if (isvariant(VPROF)) { ! 77: genseg(SBSS); ! 78: labp = llookup(newlab(), 1); ! 79: labp->s_seg = dotseg; ! 80: labp->s_value = dot; ! 81: genblock((sizeof_t)8); ! 82: genseg(SCODE); ! 83: outab(0xBB); /* mov bx, offset lab */ ! 84: outxw(labp, 0, 0); ! 85: if (countp == NULL) ! 86: countp = glookup("scount", 0); ! 87: outab(0xE8); /* near call */ ! 88: outxw(countp, 0, 1); ! 89: } ! 90: if (framesize != 0) { ! 91: if (isvariant(V80186) && notvariant(VPROF)) { ! 92: outab(0xC8); /* enter framesize,0 */ ! 93: outaw(framesize); ! 94: outab(0); ! 95: } else { ! 96: if (framesize <= 2) ! 97: outab(0x50); /* push ax */ ! 98: else { ! 99: if (framesize >= 128) ! 100: outab(0x81); /* sub, sw=01 */ ! 101: else ! 102: outab(0x83); /* sub, sw=11 */ ! 103: outab(0xEC); /* sp, */ ! 104: outab(framesize); /* value */ ! 105: if (framesize >= 128) ! 106: outab(framesize >> 8); ! 107: } ! 108: } ! 109: } ! 110: } ! 111: } ! 112: ! 113: /* ! 114: * Generate code for a function epilogue. ! 115: * Note that the i8086 OMF and i80286 OMF output writers ! 116: * know the length of the epilogue when they compute block length. ! 117: * The variable 'hasfloat' keeps track of whether each function performs ! 118: * floating point operations. ! 119: * If it does, the epilogue includes an FWAIT to assure completion; ! 120: * otherwise, a store into a local variable could complete after the exit, ! 121: * when the allocated stack space has been reused for something else. ! 122: */ ! 123: genepilog() ! 124: { ! 125: register INS *ip; ! 126: ! 127: if (isvariant(VASM)) { ! 128: if (hasfloat) { ! 129: if (isvariant(VEMU87)) ! 130: genone(ZCALL, A_GID|A_DIR, "emu87"); ! 131: else { ! 132: bput(CODE); bput(ZFWAIT); ! 133: } ! 134: } ! 135: if (isvariant(V80186)) { ! 136: bput(CODE); bput(ZLEAVE); ! 137: } else { ! 138: if (framesize != 0) ! 139: gentwo(ZMOV, A_RSP, A_RBP); ! 140: genone(ZPOP, A_RBP); ! 141: } ! 142: genone(ZPOP, A_RDI); ! 143: genone(ZPOP, A_RSI); ! 144: bput(CODE); bput(ZRET); ! 145: } else { ! 146: if (hasfloat) { ! 147: if (isvariant(VEMU87)) ! 148: outemucall(); /* call emu87 */ ! 149: else ! 150: outfb(0x9B); /* fwait */ ! 151: } ! 152: if (isvariant(V80186)) ! 153: outab(0xC9); /* leave */ ! 154: else { ! 155: if (framesize != 0) { ! 156: outab(0x8B); /* mov sp, bp */ ! 157: outab(0xE5); ! 158: } ! 159: outab(0x5D); /* pop bp */ ! 160: } ! 161: outab(0x5F); /* pop di */ ! 162: outab(0x5E); /* pop si */ ! 163: #if !ONLYSMALL ! 164: if (notvariant(VSMALL)) ! 165: outab(0xCB); /* ret far */ ! 166: else ! 167: #endif ! 168: outab(0xC3); /* ret near */ ! 169: } ! 170: } ! 171: ! 172: /* ! 173: * Generate the code for a BLOCK item. ! 174: * If in -S mode, output an assembly directive to get the space. ! 175: * If generating binary, either bump 'dot' (if compiling ! 176: * into BSS segment) or output a block of 0 bytes. ! 177: */ ! 178: genblock(n) ! 179: register sizeof_t n; ! 180: { ! 181: if (isvariant(VASM)) { ! 182: bput(BLOCK); zput(n); ! 183: } else if (dotseg == SBSS) ! 184: dot += n; ! 185: else ! 186: #if 0 /* i8086 outnzb() not implemented yet */ ! 187: outnzb(n); ! 188: #else ! 189: while (n--) ! 190: outab(0); ! 191: #endif ! 192: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.