Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.18 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/arch/vax/code.c

Annotated File View

plunky
1.18
1 /*      $Id: code.c,v 1.18 2012/04/22 21:07:40 plunky Exp $     */
ragge
1.1
2 /*
3  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * Redistributions of source code and documentation must retain the above
10  * copyright notice, this list of conditions and the following disclaimer.
11  * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditionsand the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  *      This product includes software developed or owned by Caldera
17  *      International, Inc.
18  * Neither the name of Caldera International, Inc. nor the names of other
19  * contributors may be used to endorse or promote products derived from
20  * this software without specific prior written permission.
21  *
22  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
23  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
27  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
32  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
ragge
1.2
36 # include "pass1.h"
ragge
1.1
37
ragge
1.11
38 /*
39  * Print out assembler segment name.
40  */
ragge
1.2
41 void
ragge
1.11
42 setseg(int segchar *name)
43 {
44         switch (seg) {
45         case PROGname = ".text"break;
46         case DATA:
47         case LDATAname = ".data"break;
48         case STRNG:
ragge
1.13
49         case RDATAname = ".section .rodata"break;
ragge
1.11
50         case UDATAbreak;
51         case PICLDATA:
52         case PICDATA:
53         case PICRDATA:
54         case TLSDATA:
55         case TLSUDATA:
56         case CTORS:
57         case DTORS:
58                 uerror("FIXME: unsupported segment");
59         case NMSEG
60                 printf("\t.section %s,\"aw\",@progbits\n"name);
61                 return;
ragge
1.1
62         }
ragge
1.11
63         printf("\t%s\n"name);
64 }
ragge
1.1
65
ragge
1.2
66 /*
ragge
1.11
67  * Define everything needed to print out some data (or text).
68  * This means segment, alignment, visibility, etc.
ragge
1.2
69  */
70 void
ragge
1.11
71 defloc(struct symtab *sp)
ragge
1.2
72 {
ragge
1.11
73         char *name;
74
75         if ((name = sp->soname) == NULL)
76                 name = exname(sp->sname);
77
78         if (sp->sclass == EXTDEF) {
79                 printf("\t.globl %s\n"name);
80                 printf("\t.type %s,@%s\n"name,
81                     ISFTN(sp->stype)? "function" : "object");
82         }
83         if (sp->slevel == 0)
84                 printf("%s:\n"name);
85         else
86                 printf(LABFMT ":\n"sp->soffset);
ragge
1.2
87 }
ragge
1.1
88
ragge
1.12
89 static int strtemp;
ragge
1.11
90
ragge
1.12
91 void
plunky
1.18
92 efcode(void)
ragge
1.12
93 {
94         TWORD t;
95         NODE *p, *q;
ragge
1.11
96
ragge
1.1
97         /* code for the end of a function */
ragge
1.2
98         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
99                 return;
ragge
1.1
100
ragge
1.12
101         t = PTR+BTYPE(cftnsp->stype);
102         /* Create struct assignment */
103         q = tempnode(strtempt0cftnsp->sap);
104         q = buildtree(UMULqNIL);
105         p = block(REGNILNILt0cftnsp->sap);
106         regno(p) = R0;
107         p = buildtree(UMULpNIL);
108         p = buildtree(ASSIGNqp);
109         ecomp(p);
110
111         /* put hidden arg in r0 on return */
112         q = tempnode(strtempINT00);
113         p = block(REGNILNILINT00);
114         regno(p) = R0;
115         ecomp(buildtree(ASSIGNpq));
116 }
ragge
1.1
117
ragge
1.2
118 void
ragge
1.12
119 bfcode(struct symtab **spint n)
ragge
1.2
120 {
ragge
1.12
121         struct symtab *sp2;
122         NODE *p, *q;
ragge
1.2
123         int i;
ragge
1.1
124
ragge
1.12
125         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
126                 /* Move return address into temporary */
127                 p = tempnode(0INT00);
128                 strtemp = regno(p);
129                 q = block(REG00INT00);
130                 regno(q) = R1;
131                 ecomp(buildtree(ASSIGNpq));
132         }
133         if (xtemps == 0)
ragge
1.2
134                 return;
ragge
1.12
135
136         /* put arguments in temporaries */
137         for (i = 0i < ni++) {
138                 if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
139                     cisreg(sp[i]->stype) == 0)
140                         continue;
141                 if (cqual(sp[i]->stypesp[i]->squal) & VOL)
142                         continue;
143                 sp2 = sp[i];
144                 p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->sap);
145                 p = buildtree(ASSIGNpnametree(sp2));
146                 sp[i]->soffset = regno(p->n_left);
147                 sp[i]->sflags |= STNODE;
148                 ecomp(p);
149         }
150
ragge
1.2
151 }
ragge
1.1
152
ragge
1.2
153 void
plunky
1.18
154 ejobcode(int flag)
155 {
ragge
1.1
156         /* called just before final exit */
157         /* flag is 1 if errors, 0 if none */
plunky
1.18
158 }
ragge
1.1
159
ragge
1.2
160 void
plunky
1.18
161 bjobcode(void)
ragge
1.2
162 {
ragge
1.14
163         astypnames[INT] = astypnames[UNSIGNED] = "\t.long";
164         astypnames[SHORT] = astypnames[USHORT] = "\t.word";
ragge
1.2
165 }
166
167 #if 0
plunky
1.18
168 aobeg(void)
169 {
ragge
1.1
170         /* called before removing automatics from stab */
plunky
1.18
171 }
ragge
1.1
172
plunky
1.18
173 aocode(struct symtab *p)
174 {
ragge
1.1
175         /* called when automatic p removed from stab */
plunky
1.18
176 }
ragge
1.1
177
plunky
1.18
178 aoend(void)
179 {
ragge
1.1
180         /* called after removing all automatics from stab */
plunky
1.18
181 }
ragge
1.2
182 #endif
ragge
1.1
183
ragge
1.2
184 void
plunky
1.18
185 fldty(struct symtab *p)
186 {
187         /* fix up type of field p */
188 }
ragge
1.1
189
stefan
1.4
190 /*
ragge
1.2
191  * XXX - fix genswitch.
ragge
1.1
192  */
stefan
1.4
193 int
194 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
195 {
stefan
1.4
196         return 0;
ragge
1.1
197 }
198
ragge
1.2
199 #ifdef notyet
ragge
1.1
200 struct sw heapsw[SWITSZ];       /* heap for switches */
201
plunky
1.18
202 genswitch(register struct sw *pint n)
203 {
ragge
1.1
204         /*      p points to an array of structures, each consisting
205                 of a constant value and a label.
206                 The first is >=0 if there is a default label;
207                 its value is the label number
208                 The entries p[1] to p[n] are the nontrivial cases
209                 */
210         register i;
211         register CONSZ jrange;
212         register dlabswlab;
213
214         range = p[n].sval-p[1].sval;
215
216         ifrange>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */
217
218                 swlab = getlab();
219                 dlab = p->slab >= 0 ? p->slab : getlab();
220
221                 /* already in r0 */
222                 printf("        casel   r0,$%ld,$%ld\n"p[1].svalrange);
ragge
1.2
223                 deflab1(swlab);
ragge
1.1
224                 fori=1,j=p[1].svali<=nj++) {
ragge
1.2
225                         printf("        .word   " LABFMT "-" LABFMT "\n",
226                             (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
ragge
1.1
227                                 swlab);
228                         }
229
230                 ifp->slab >= 0 ) branchdlab );
ragge
1.2
231                 else deflab1(dlab);
ragge
1.1
232                 return;
233
234                 }
235
236         ifn>8 ) {     /* heap switch */
237
238                 heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
239                 makeheap(pn1);      /* build heap */
240
241                 walkheap(1n); /* produce code */
242
243                 ifp->slab >= 0 )
244                         branchdlab );
245                 else
ragge
1.2
246                         deflab1(dlab);
ragge
1.1
247                 return;
248         }
249
250         /* debugging code */
251
252         /* out for the moment
253         if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
254         */
255
256         /* simple switch code */
257
258         fori=1i<=n; ++i ){
259                 /* already in r0 */
260
261                 printf"       cmpl    r0,$" );
262                 printfCONFMTp[i].sval );
ragge
1.2
263                 printf"\n     jeql    " LBLFMT "\n"p[i].slab );
ragge
1.1
264                 }
265
266         ifp->slab>=0 ) branchp->slab );
plunky
1.18
267 }
ragge
1.1
268
plunky
1.18
269 makeheap(register struct sw *pint mint n)
ragge
1.1
270 {
271         register int q;
272
273         q = select(m);
274         heapsw[n] = p[q];
275         ifq>1 ) makeheap(pq-12*n);
276         ifq<m ) makeheap(p+qm-q2*n+1);
277 }
278
plunky
1.18
279 select(int m)
280 {
ragge
1.1
281         register int l,i,k;
282
283         for(i=1; ; i*=2)
284                 if( (i-1) > m ) break;
285         l = ((k = i/2 - 1) + 1)/2;
286         returnl + (m-k < l ? m-k : l));
287 }
288
plunky
1.18
289 walkheap(int startint limit)
ragge
1.1
290 {
291         int label;
292
293         ifstart > limit ) return;
294         printf("        cmpl    r0,$%d\n",  heapsw[start].sval);
ragge
1.2
295         printf("        jeql    " LBLFMT "\n"heapsw[start].slab);
ragge
1.1
296         if( (2*start) > limit ) {
ragge
1.2
297                 printf("        jbr     " LBLFMT "\n"heapsw[0].slab);
ragge
1.1
298                 return;
299         }
300         if( (2*start+1) <= limit ) {
301                 label = getlab();
ragge
1.2
302                 printf("        jgtr    " LBLFMT "\n"label);
ragge
1.1
303         } else
ragge
1.2
304                 printf("        jgtr    " LBLFMT "\n"heapsw[0].slab);
ragge
1.1
305         walkheap2*startlimit);
306         if( (2*start+1) <= limit ) {
ragge
1.2
307                 deflab1(label);
ragge
1.1
308                 walkheap2*start+1limit);
309         }
310 }
ragge
1.2
311 #endif
plunky
1.18
312
ragge
1.3
313 /*
314  * Called with a function call with arguments as argument.
315  * This is done early in buildtree() and only done once.
316  */
317 NODE *
318 funcode(NODE *p)
319 {
ragge
1.12
320         NODE *r, *l;
321
322         /* Fix function call arguments. On vax, just add funarg */
323         for (r = p->n_rightr->n_op == CMr = r->n_left) {
ragge
1.15
324                 if (r->n_right->n_op != STARG) {
325                         r->n_right = intprom(r->n_right);
ragge
1.12
326                         r->n_right = block(FUNARGr->n_rightNIL,
327                             r->n_right->n_typer->n_right->n_df,
328                             r->n_right->n_ap);
ragge
1.15
329                 }
ragge
1.12
330         }
331         if (r->n_op != STARG) {
332                 l = talloc();
333                 *l = *r;
ragge
1.15
334                 r->n_op = FUNARG;
335                 r->n_left = l;
336                 r->n_left = intprom(r->n_left);
337                 r->n_type = r->n_left->n_type;
ragge
1.12
338         }
ragge
1.3
339         return p;
340 }
ragge
1.16
341
342 /*
343  * Generate the builtin code for FFS.
344  */
345 NODE *
346 builtin_ffs(NODE *fNODE *aTWORD t)
347 {
348         NODE *p, *q, *r;
349
350         nfree(f);
351         p = tempnode(0t00);
352         r = block(XARGccopy(p), NILINT00);
353         r->n_name = "=&r";
354         q = block(XARGaNILINT00);
355         q->n_name = "g";
356         q = block(CMrqINT00);
357         q = block(XASMqblock(ICON00STRTY00), INT00);
358         q->n_name = "ffs $0,$32,%1,%0;bneq 1f;mnegl $1,%0;1:;incl %0";
359         p = block(COMOPqpt00);
360         return p;
361 }
362
363 NODE *
364 vax_builtin_return_address(NODE *fNODE *aTWORD t)
365 {
366
367         if (a == NULL || a->n_op != ICON)
368                 goto bad;
369
370         if (a->n_lval != 0)
371                 werror("unsupported argument");
372
373         tfree(f);
374         tfree(a);
375
376         f = block(REGNILNILINCREF(PTR+CHAR), 00);
377         regno(f) = FPREG;
378         f = block(UMUL,
379                 block(PLUSf,
380                     bcon(16), INCREF(PTR+CHAR), 00), NILPTR+CHAR00);
381         f = makety(fPTR+VOID000);
382
383         return f;
384 bad:
385         uerror("bad argument to __builtin_return_address");
386         return bcon(0);
387 }
388
389 NODE *
390 vax_builtin_frame_address(NODE *fNODE *aTWORD t)
391 {
392         int nframes;
393
394         if (a == NULL || a->n_op != ICON)
395                 goto bad;
396
397         nframes = a->n_lval;
398
399         tfree(f);
400         tfree(a);
401
ragge
1.17
402         f = block(REGNILNILPTR+CHAR00);
ragge
1.16
403         regno(f) = FPREG;
404
405         while (nframes--) {
406                 f = block(UMUL,
407                         block(PLUSf,
408                             bcon(12), INCREF(PTR+CHAR), 00),
409                                 NILPTR+CHAR00);
410                 f = makety(fPTR+CHAR000);
411         }
412
413         return f;
414 bad:
415         uerror("bad argument to __builtin_frame_address");
416         return bcon(0);
417 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-10-31 06:39 +0100