|
|
1.1 ! root 1: /* ! 2: * n2/i386/emit1.c ! 3: * Prologs, etc. ! 4: * i386. ! 5: */ ! 6: ! 7: #ifdef vax ! 8: #include "INC$LIB:cc2.h" ! 9: #else ! 10: #include "cc2.h" ! 11: #endif ! 12: ! 13: /* Globals. */ ! 14: static SYM *countp; ! 15: ival_t framesize; ! 16: PREGSET usedregs; ! 17: int hasfloat; ! 18: ! 19: /* ! 20: * Generate code for the ALIGN operation. ! 21: * In BSS, just bump the location counter. ! 22: * Otherwise, write 0 bytes; note that this does not write nops, ! 23: * it would not work right if the alignment bytes were executed. ! 24: */ ! 25: genalign(align) register int align; ! 26: { ! 27: register int n; ! 28: ! 29: if (align == 0) ! 30: return; /* ignore ALIGN 0 */ ! 31: if (isvariant(VASM)) { ! 32: bput(ALIGN); bput(align); ! 33: return; ! 34: } ! 35: n = dot & (align-1); /* excess past alignment boundary */ ! 36: if (n == 0) ! 37: return; ! 38: n = align - n; /* bump to next boundary */ ! 39: if (dotseg == SBSS) ! 40: dot += n; ! 41: else ! 42: outnzb((sizeof_t)n, (dotseg == SCODE)); ! 43: } ! 44: ! 45: /* ! 46: * Generate code for a function prolog. ! 47: * The prolog is generally of the form ! 48: * mov ebp, esp ! 49: * sub ebp, $framesize ! 50: * push esi ! 51: * push edi ! 52: * push ebx ! 53: * with variations for profiling and framesize. ! 54: * Saving the registers after the local adjust allows suppressing the ! 55: * register save/restore if the function does not touch the register. ! 56: */ ! 57: genprolog() ! 58: { ! 59: register int lab; ! 60: register SYM *labp; ! 61: ! 62: hasfloat = 0; ! 63: if (isvariant(VASM)) { ! 64: /* Write assembler. */ ! 65: if ((framesize == 0) || (framesize >= 65536L) || isvariant(VPROF)) { ! 66: genone(ZPUSH, A_REBP); ! 67: gentwo(ZMOV, A_REBP, A_RESP); ! 68: } ! 69: if (isvariant(VPROF)) { ! 70: genseg(SBSS); ! 71: bput(LLABEL); iput((ival_t)(lab=newlab())); ! 72: genblock((sizeof_t)12); ! 73: genseg(SCODE); ! 74: gentwo(ZMOV, A_RECX, A_IMM|A_LID, lab); ! 75: genone(ZCALL, A_GID|A_DIR, "_scount"); ! 76: } ! 77: if (framesize != 0) { ! 78: if (notvariant(VPROF) && framesize < 65536L) ! 79: gentwo(ZENTER, A_IMM|A_OFFS, framesize, A_IMM|A_OFFS, (ival_t)0); ! 80: else { ! 81: if (framesize <= 4) ! 82: genone(ZPUSH, A_REAX); ! 83: else ! 84: gentwo(ZSUB, A_RESP, A_OFFS|A_IMM, framesize); ! 85: } ! 86: } ! 87: if ((usedregs & BESI) != 0) ! 88: genone(ZPUSH, A_RESI); ! 89: if ((usedregs & BEDI) != 0) ! 90: genone(ZPUSH, A_REDI); ! 91: if ((usedregs & BEBX) != 0) ! 92: genone(ZPUSH, A_REBX); ! 93: } else { ! 94: /* Write bits. */ ! 95: if ((framesize == 0) || (framesize >= 65536L) || isvariant(VPROF)) { ! 96: outab(0x55); /* push ebp */ ! 97: outab(0x8B); outab(0xEC); /* mov ebp, esp */ ! 98: } ! 99: if (isvariant(VPROF)) { ! 100: genseg(SBSS); ! 101: labp = llookup(newlab(), 1); ! 102: labp->s_seg = dotseg; ! 103: labp->s_value = dot; ! 104: genblock((sizeof_t)12); ! 105: genseg(SCODE); ! 106: outab(0xB9); /* mov ecx, offset lab */ ! 107: outxl(labp, 0, 0); ! 108: if (countp == NULL) ! 109: countp = glookup("_scount", 0); ! 110: outab(0xE8); /* call _scount */ ! 111: outxl(countp, 0, 1); ! 112: } ! 113: if (framesize != 0) { ! 114: if (notvariant(VPROF) && framesize < 65536L) { ! 115: outab(0xC8); /* enter framesize,0 */ ! 116: outaw(framesize); ! 117: outab(0); ! 118: } else { ! 119: if (framesize == 4) ! 120: outab(0x50); /* push eax */ ! 121: else { ! 122: if (framesize >= 128) ! 123: outab(0x81); /* sub, sw=01 */ ! 124: else ! 125: outab(0x83); /* sub, sw=11 */ ! 126: outab(0xEC); /* esp, */ ! 127: if (framesize < 128) ! 128: outab(framesize); /* value */ ! 129: else ! 130: outal(framesize); ! 131: } ! 132: } ! 133: } ! 134: if ((usedregs & BESI) != 0) ! 135: outab(0x56); /* push esi */ ! 136: if ((usedregs & BEDI) != 0) ! 137: outab(0x57); /* push edi */ ! 138: if ((usedregs & BEBX) != 0) ! 139: outab(0x53); /* push ebx */ ! 140: } ! 141: } ! 142: ! 143: /* ! 144: * Generate code for a function epilog. ! 145: * If NDP, the variable 'hasfloat' keeps track of whether the function performs ! 146: * floating point operations. ! 147: * If it does, the epilogue includes an FWAIT to assure completion; ! 148: * otherwise, a store into a local variable could complete after the exit, ! 149: * when the allocated stack space has been reused for something else. ! 150: * The peephole optimizer knows the details of epilogue code generation, ! 151: * because it suppresses a stack adjust which immediately precedes LEAVE; ! 152: * if the generated code here changes, change i386/peep.c/noeffect() too. ! 153: */ ! 154: genepilog() ! 155: { ! 156: if (isvariant(VASM)) { ! 157: if (isvariant(VNDP) && hasfloat) { ! 158: #if 0 ! 159: if (isvariant(VEMU87)) ! 160: genone(ZCALL, A_GID|A_DIR, "emu87"); ! 161: else { ! 162: #endif ! 163: bput(CODE); bput(ZFWAIT); ! 164: #if 0 ! 165: } ! 166: #endif ! 167: } ! 168: if ((usedregs & BEBX) != 0) ! 169: genone(ZPOP, A_REBX); ! 170: if ((usedregs & BEDI) != 0) ! 171: genone(ZPOP, A_REDI); ! 172: if ((usedregs & BESI) != 0) ! 173: genone(ZPOP, A_RESI); ! 174: bput(CODE); bput(ZLEAVE); ! 175: bput(CODE); bput(ZRET); ! 176: } else { ! 177: if (isvariant(VNDP) && hasfloat) { ! 178: #if 0 ! 179: if (isvariant(VEMU87)) ! 180: outemucall(); /* call emu87 */ ! 181: else ! 182: #endif ! 183: outfb(0x9B); /* fwait */ ! 184: } ! 185: if ((usedregs & BEBX) != 0) ! 186: outab(0x5B); /* pop ebx */ ! 187: if ((usedregs & BEDI) != 0) ! 188: outab(0x5F); /* pop edi */ ! 189: if ((usedregs & BESI) != 0) ! 190: outab(0x5E); /* pop esi */ ! 191: outab(0xC9); /* leave */ ! 192: outab(0xC3); /* ret */ ! 193: } ! 194: genalign(4); ! 195: } ! 196: ! 197: /* ! 198: * Generate the code for a BLOCK item. ! 199: * If in -S mode, output an assembly directive to get the space. ! 200: * If generating binary, bump 'dot' if compiling into BSS; ! 201: * otherwise, output a block of 0 bytes. ! 202: */ ! 203: genblock(n) register sizeof_t n; ! 204: { ! 205: if (isvariant(VASM)) { ! 206: bput(BLOCK); zput(n); ! 207: } else if (dotseg == SBSS) ! 208: dot += n; ! 209: else ! 210: outnzb(n, 0); ! 211: } ! 212: ! 213: /* end of n2/i386/emit1.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.