|
|
1.1 root 1: /*
2: * This file contains a number of small, machine dependent output
3: * routines called from the main code output routines in 'out.c'.
4: * Most have something to do with function calls and argument lists.
5: */
6: #ifdef vax
7: #include "INC$LIB:cc1.h"
8: #else
9: #include "cc1.h"
10: #endif
11:
12: /*
13: * Output a call.
14: * Make the left subtree (the name) addressable if required.
15: * Take a quick look to see if the semantics of the indirect call will work.
16: * If this is not an indirect call (iflag==0), then the "nsef" flag is set
17: * in the call to "genadr", to supress the generation of escape prefix bytes.
18: */
19: outcall(tp, cxt, lab)
20: register TREE *tp;
21: {
22: register int nb;
23: register int iflag;
24: register int isalien;
25: register int isptr;
26: register int type;
27:
28: isalien = 0;
29: if (isvariant(VALIEN)) {
30: if (tp->t_lp->t_op == GID && tp->t_lp->t_seg == SALIEN) {
31: ++isalien;
32: type = tp->t_type;
33: isptr = ispoint(type);
34: /* Adjust types not adjusted in parser. */
35: if (type == S8)
36: tp->t_type = S16;
37: else if (type == U8)
38: tp->t_type = U16;
39: #if !OMF286
40: callfixup(tp->t_lp);
41: #endif
42: }
43: }
44: if (isalien) {
45: genr(ZPUSH, A_RSI);
46: genr(ZPUSH, A_RDI);
47: if (isvariant(VSMALL))
48: genr(ZPUSH, A_RES);
49: }
50: nb = outargs(tp->t_rp, isalien);
51: iflag = 0;
52: tp = tp->t_lp;
53: if (tp->t_op == STAR) {
54: iflag = 1;
55: tp = tp->t_lp;
56: if (!isadr(tp->t_flag)) {
57: while (tp->t_op == LEAF)
58: tp = tp->t_lp;
59: outofs(tp);
60: }
61: }
62: outopcall(iflag);
63: genadr(tp, iflag==0, 0, NULL);
64: if (isalien) {
65: if (isptr) {
66: genrr(ZMOV, A_RAX, A_RBX);
67: #if !ONLYSMALL
68: if (isvariant(VLARGE))
69: genrr(ZMOV, A_RDX, A_RES);
70: #endif
71: }
72: if (type == S8) {
73: bput(CODE); bput(ZCBW);
74: }
75: else if (type == U8)
76: genrr(ZSUBB, A_RAH, A_RAH);
77: if (isvariant(VSMALL))
78: genr(ZPOP, A_RES);
79: genr(ZPOP, A_RDI);
80: genr(ZPOP, A_RSI);
81: } else if (nb != 0)
82: genri(ZADD, A_RSP, nb);
83: }
84:
85: #if !OMF286
86: /* Remove the trailing '_' appended to GID's by cc0, for alien call. */
87: callfixup(tp)
88: TREE *tp;
89: {
90: register char *cp1, *cp2;
91:
92: cp1 = tp->t_sp->s_id;
93: cp2 = id;
94: while (*cp2++ = *cp1++)
95: ;
96: cp2[-2] = 0;
97: tp->t_sp = gidpool(id);
98: }
99: #endif
100:
101: /*
102: * Output the argument list of a function.
103: * The arguments are moved to the stack right to left.
104: * Structure arguments, marked by a PTB type, get block moved into place.
105: * If the function is "alien" we push in the opposite order.
106: */
107: outargs(atp, isalien)
108: TREE *atp;
109: {
110: register TREE *tp;
111: register s, n;
112: TYPE type;
113:
114: if ((tp=atp) == NULL)
115: return (0);
116: if (tp->t_op == ARGLST) {
117: s = 0;
118: if (isalien)
119: s += outargs(tp->t_lp, isalien);
120: s += outargs(tp->t_rp, isalien);
121: if ( ! isalien)
122: s += outargs(tp->t_lp, isalien);
123: return (s);
124: }
125: #if !ONLYSMALL
126: if ((type=tp->t_type)==LPTB || type==SPTB) {
127: #else
128: if ((type=tp->t_type) == SPTB) {
129: #endif
130: n = s = tp->t_size;
131: if (isvariant(VALIGN))
132: n = (s+1)&~01;
133: if (n != 0) {
134: if (isvariant(V80186)) {
135: genri(ZSUB, A_RSP, n);
136: geni(ZPUSH, s);
137: } else {
138: if (s == n) {
139: genri(ZMOV, A_RAX, s);
140: genrr(ZSUB, A_RSP, A_RAX);
141: } else {
142: genri(ZSUB, A_RSP, n);
143: genri(ZMOV, A_RAX, s);
144: }
145: genr(ZPUSH, A_RAX);
146: }
147: output(tp, MFNARG, 0, 0);
148: #if !ONLYSMALL
149: if (type == LPTB) {
150: genr(ZPUSH, A_RSS);
151: genrr(ZMOV, A_RAX, A_RSP);
152: genri(ZADD, A_RAX, 8);
153: genr(ZPUSH, A_RAX);
154: geng(ZXCALL, "blkmv");
155: genri(ZADD, A_RSP, 10);
156: } else {
157: #endif
158: genrr(ZMOV, A_RAX, A_RSP);
159: genri(ZADD, A_RAX, 4);
160: genr(ZPUSH, A_RAX);
161: geng(ZCALL, "blkmv");
162: genri(ZADD, A_RSP, 6);
163: #if !ONLYSMALL
164: }
165: #endif
166: }
167: return (n);
168: }
169: output(tp, MFNARG, 0, 0);
170: return (pertype[type].p_size);
171: }
172:
173: /*
174: * This routine does the work of the [TLOP0], [TLOP1] and [TLOP2] macros.
175: * It is given an opcode and returns the opcode that is used.
176: */
177: maptype(opvariant, opcode, tp)
178: int opvariant;
179: register int opcode;
180: register TREE *tp;
181: {
182: if (opvariant == M_TL)
183: tp = tp->t_lp;
184: else if (opvariant == M_TR)
185: tp = tp->t_rp;
186: else if (opvariant != M_TN)
187: return (opcode);
188: if (isbyte(tp->t_type)) {
189: if (opcode == ZADD)
190: opcode = ZADDB;
191: if (opcode == ZSUB)
192: opcode = ZSUBB;
193: if (opcode == ZINC)
194: opcode = ZINCB;
195: if (opcode == ZDEC)
196: opcode = ZDECB;
197: }
198: return (opcode);
199: }
200:
201: /*
202: * This routine does the ZLDES opcode mapping.
203: */
204: mapzldes(tp)
205: register TREE *tp;
206: {
207: if (hihalf(tp->t_treg) == DS)
208: return (ZLDS);
209: else if (hihalf(tp->t_treg) == ES)
210: return (ZLES);
211: else
212: cbotch("ldes");
213: }
214:
215: /*
216: * Emit call opcode.
217: */
218: outopcall(iflag)
219: {
220: register op;
221:
222: #if !ONLYSMALL
223: if (notvariant(VSMALL)) {
224: op = ZXCALL;
225: if (iflag)
226: op = ZIXCALL;
227: } else {
228: #endif
229: op = ZCALL;
230: if (iflag)
231: op = ZICALL;
232: #if !ONLYSMALL
233: }
234: #endif
235: bput(CODE);
236: bput(op);
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.