|
|
1.1 root 1: /*
2: * n1/i386/outmch.c
3: * This file contains a number of small, machine dependent output
4: * routines called from the main code output routines in 'out.c'.
5: * Most have something to do with function calls and argument lists.
6: * i386.
7: */
8:
9: #ifdef vax
10: #include "INC$LIB:cc1.h"
11: #else
12: #include "cc1.h"
13: #endif
14:
15: extern ival_t outargs();
16:
17: /*
18: * Output a call.
19: * Make the left subtree (the name) addressable if required.
20: * Take a quick look to see if the semantics of the indirect call will work.
21: * If this is not an indirect call (iflag==0), then the "nsef" flag is set
22: * in the call to "genadr", to supress the generation of escape prefix bytes.
23: */
24: outcall(tp, cxt, lab) register TREE *tp;
25: {
26: register ival_t nb;
27: register int iflag;
28:
29: nb = outargs(tp->t_rp);
30: iflag = 0;
31: tp = tp->t_lp;
32: if (tp->t_op == STAR) {
33: iflag = 1;
34: tp = tp->t_lp;
35: if (!isadr(tp->t_flag)) {
36: while (tp->t_op == LEAF)
37: tp = tp->t_lp;
38: outofs(tp);
39: }
40: }
41: outopcall(iflag);
42: genadr(tp, iflag==0, 0, NULL);
43: if (nb != 0) {
44: if (nb == 4)
45: genr(ZPOP, A_RECX);
46: else
47: genri(ZADD, A_RESP, nb);
48: }
49: }
50:
51: /*
52: * Output the argument list of a function.
53: * The arguments are moved to the stack right to left.
54: * Structure arguments, marked by a PTB type, get block moved into place.
55: * If the function is "alien" we push in the opposite order.
56: */
57: ival_t
58: outargs(atp) TREE *atp;
59: {
60: register TREE *tp;
61: register ival_t s, n;
62: TYPE type;
63:
64: if ((tp=atp) == NULL)
65: return (ival_t)0;
66: if (tp->t_op == ARGLST) {
67: s = 0;
68: s += outargs(tp->t_rp);
69: s += outargs(tp->t_lp);
70: return s;
71: }
72: if ((type=tp->t_type)==PTB) {
73: /* UNDONE: fix for BCS struct passing! */
74: n = s = tp->t_size;
75: n = (s+3)&~03;
76: if (n != 0) {
77: genri(ZSUB, A_RESP, n); /* grab dest space */
78: geni(ZPUSH, s); /* count */
79: output(tp, MFNARG, 0, 0); /* src */
80: genrr(ZMOV, A_REAX, A_RESP);
81: genri(ZADD, A_REAX, (ival_t)8);
82: genr(ZPUSH, A_REAX); /* dest */
83: geng(ZCALL, "memcpy");
84: genri(ZADD, A_RESP, (ival_t)12);
85: }
86: return n;
87: }
88: output(tp, MFNARG, 0, 0);
89: return (ival_t)pertype[type].p_size;
90: }
91:
92: /*
93: * This routine does the work of the [TL OP0], [TL OP1] and [TL OP2] macros.
94: * It is given an opcode and returns the opcode that is used.
95: * Allows collapsing of code table entries which differ only slightly,
96: * based on signed/unsigned and byte/word/dword differences.
97: */
98: maptype(opvariant, opcode, tp)
99: int opvariant;
100: register int opcode;
101: register TREE *tp;
102: {
103: int type, byteflag, wordflag, unsflag;
104: int fltflag;
105:
106: fltflag = is_ndp_op(opcode);
107: if (opvariant == M_TL)
108: tp = tp->t_lp; /* use left type */
109: else if (opvariant == M_TR)
110: tp = tp->t_rp; /* use right type */
111: else if (opvariant != M_TN) /* use node type or */
112: return opcode; /* return opcode unchanged */
113: type = tp->t_type;
114: byteflag = isbyte(type);
115: wordflag = isword(type);
116: unsflag = isuns(type);
117: if (unsflag) {
118: /*
119: * Replace opcode by unsigned variant.
120: * ZSAL -> ZSHL is unnecessary because SAL == SHL.
121: */
122: switch (opcode) {
123: case ZMOVSX: opcode = ZMOVZX; break;
124: case ZSAR: opcode = ZSHR; break;
125: case ZIDIV: opcode = ZDIV; break;
126: case ZIMUL: opcode = ZMUL; break;
127: }
128: }
129: if (byteflag || wordflag) {
130: /*
131: * Replace opcode by byte or word variant.
132: * This assumes a fixed order for variants
133: * in h/i386/opcode.h: [dword, byte, word].
134: */
135: switch (opcode) {
136: case ZADD:
137: case ZAND:
138: case ZCMP:
139: case ZDEC:
140: case ZINC:
141: case ZMOV:
142: case ZOR:
143: case ZSAL:
144: case ZSAR:
145: case ZSHR:
146: case ZSUB:
147: case ZTEST:
148: case ZXOR:
149: return (byteflag) ? opcode + 1 : opcode + 2;
150: case ZMOVSX: return (byteflag) ? ZMOVSXB : ZMOVSX;
151: case ZMOVZX: return (byteflag) ? ZMOVZXB : ZMOVZX;
152: }
153: } else {
154: /* ZMOVSX or ZMOVZX with 32-bit operand just means ZMOV. */
155: switch (opcode) {
156: case ZMOVSX:
157: case ZMOVZX: return ZMOV;
158: }
159: }
160: if (fltflag) {
161: /*
162: * Replace opcode by type-dependent variant.
163: * This assumes a fixed order for variants
164: * in h/i386/opcode.h: [double, float, dword, word].
165: */
166: switch(opcode) {
167: case ZFADDD:
168: case ZFCOMPD:
169: case ZFDIVD:
170: case ZFLDD:
171: case ZFMULD:
172: case ZFRDIVD:
173: case ZFRSUBD:
174: case ZFSTD:
175: case ZFSTPD:
176: case ZFSUBD:
177: switch(type) {
178: case F64: return opcode;
179: case F32: return opcode + 1;
180: case S32: return opcode + 2;
181: case S16: return opcode + 3;
182: }
183: }
184: }
185: return opcode; /* return opcode unchanged */
186: }
187:
188: /*
189: * Generate output prefix bytes
190: * (none for dword operands, LO for word operands, LO LO for byte operands)
191: * depending on the supplied type.
192: * Makes the code tables much more concise.
193: */
194: mappfx(tp, opv, pfx, npfxp) TREE *tp; int opv; unsigned char *pfx; int *npfxp;
195: {
196: register int type;
197:
198: if (opv == M_TL)
199: tp = tp->t_lp;
200: else if (opv == M_TR)
201: tp = tp->t_rp;
202: else if (opv != M_TN)
203: return;
204: type = tp->t_type;
205: if (isbyte(type) || isword(type)) {
206: pfx[*npfxp] = M_LO;
207: ++*npfxp;
208: if (isbyte(type)) {
209: pfx[*npfxp] = M_LO;
210: ++*npfxp;
211: }
212: }
213:
214: }
215:
216: /*
217: * Emit call opcode.
218: */
219: outopcall(iflag)
220: {
221: bput(CODE);
222: bput((iflag) ? ZICALL : ZCALL);
223: }
224:
225: /* end of n1/i386/outmch.c */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.