|
|
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.