Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120818201800

Diff

Diff from 1.21 to:

Annotations

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

Annotated File View

ragge
1.21
1 /*      $Id: code.c,v 1.21 2012/08/18 20:18:00 ragge 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;
ragge
1.20
46
ragge
1.11
47         case DATA:
48         case LDATAname = ".data"break;
ragge
1.20
49
ragge
1.11
50         case STRNG:
ragge
1.13
51         case RDATAname = ".section .rodata"break;
ragge
1.20
52
ragge
1.11
53         case UDATAbreak;
ragge
1.20
54
55         case CTORS:
56                 name = ".section .ctors,\"aw\",@progbits";
57                 break;
58
59         case DTORS:
ragge
1.11
60         case PICRDATA:
61         case TLSDATA:
62         case TLSUDATA:
ragge
1.20
63                 uerror("FIXME: unsupported segment %d"seg);
64                 break;
65
66         case PICLDATA:
67         case PICDATA:
68                 name = ".section .data.rel.local,\"aw\",@progbits";
69                 break;
70
ragge
1.11
71         case NMSEG
72                 printf("\t.section %s,\"aw\",@progbits\n"name);
73                 return;
ragge
1.1
74         }
ragge
1.11
75         printf("\t%s\n"name);
76 }
ragge
1.1
77
ragge
1.2
78 /*
ragge
1.11
79  * Define everything needed to print out some data (or text).
80  * This means segment, alignment, visibility, etc.
ragge
1.2
81  */
82 void
ragge
1.11
83 defloc(struct symtab *sp)
ragge
1.2
84 {
ragge
1.11
85         char *name;
86
87         if ((name = sp->soname) == NULL)
88                 name = exname(sp->sname);
89
90         if (sp->sclass == EXTDEF) {
91                 printf("\t.globl %s\n"name);
92                 printf("\t.type %s,@%s\n"name,
93                     ISFTN(sp->stype)? "function" : "object");
94         }
95         if (sp->slevel == 0)
96                 printf("%s:\n"name);
97         else
98                 printf(LABFMT ":\n"sp->soffset);
ragge
1.2
99 }
ragge
1.1
100
ragge
1.12
101 static int strtemp;
ragge
1.11
102
ragge
1.12
103 void
plunky
1.18
104 efcode(void)
ragge
1.12
105 {
106         TWORD t;
107         NODE *p, *q;
ragge
1.11
108
ragge
1.1
109         /* code for the end of a function */
ragge
1.2
110         if (cftnsp->stype != STRTY+FTN && cftnsp->stype != UNIONTY+FTN)
111                 return;
ragge
1.1
112
ragge
1.12
113         t = PTR+BTYPE(cftnsp->stype);
114         /* Create struct assignment */
115         q = tempnode(strtempt0cftnsp->sap);
116         q = buildtree(UMULqNIL);
117         p = block(REGNILNILt0cftnsp->sap);
118         regno(p) = R0;
119         p = buildtree(UMULpNIL);
120         p = buildtree(ASSIGNqp);
121         ecomp(p);
122
123         /* put hidden arg in r0 on return */
124         q = tempnode(strtempINT00);
125         p = block(REGNILNILINT00);
126         regno(p) = R0;
127         ecomp(buildtree(ASSIGNpq));
128 }
ragge
1.1
129
ragge
1.2
130 void
ragge
1.12
131 bfcode(struct symtab **spint n)
ragge
1.2
132 {
ragge
1.12
133         struct symtab *sp2;
134         NODE *p, *q;
ragge
1.2
135         int i;
ragge
1.1
136
ragge
1.12
137         if (cftnsp->stype == STRTY+FTN || cftnsp->stype == UNIONTY+FTN) {
138                 /* Move return address into temporary */
139                 p = tempnode(0INT00);
140                 strtemp = regno(p);
141                 q = block(REG00INT00);
142                 regno(q) = R1;
143                 ecomp(buildtree(ASSIGNpq));
144         }
145         if (xtemps == 0)
ragge
1.2
146                 return;
ragge
1.12
147
148         /* put arguments in temporaries */
149         for (i = 0i < ni++) {
150                 if (sp[i]->stype == STRTY || sp[i]->stype == UNIONTY ||
151                     cisreg(sp[i]->stype) == 0)
152                         continue;
153                 if (cqual(sp[i]->stypesp[i]->squal) & VOL)
154                         continue;
155                 sp2 = sp[i];
156                 p = tempnode(0sp[i]->stypesp[i]->sdfsp[i]->sap);
157                 p = buildtree(ASSIGNpnametree(sp2));
158                 sp[i]->soffset = regno(p->n_left);
159                 sp[i]->sflags |= STNODE;
160                 ecomp(p);
161         }
162
ragge
1.2
163 }
ragge
1.1
164
ragge
1.2
165 void
plunky
1.18
166 ejobcode(int flag)
167 {
ragge
1.1
168         /* called just before final exit */
169         /* flag is 1 if errors, 0 if none */
plunky
1.18
170 }
ragge
1.1
171
ragge
1.2
172 void
plunky
1.18
173 bjobcode(void)
ragge
1.2
174 {
ragge
1.14
175         astypnames[INT] = astypnames[UNSIGNED] = "\t.long";
176         astypnames[SHORT] = astypnames[USHORT] = "\t.word";
ragge
1.2
177 }
178
179 #if 0
plunky
1.18
180 aobeg(void)
181 {
ragge
1.1
182         /* called before removing automatics from stab */
plunky
1.18
183 }
ragge
1.1
184
plunky
1.18
185 aocode(struct symtab *p)
186 {
ragge
1.1
187         /* called when automatic p removed from stab */
plunky
1.18
188 }
ragge
1.1
189
plunky
1.18
190 aoend(void)
191 {
ragge
1.1
192         /* called after removing all automatics from stab */
plunky
1.18
193 }
ragge
1.2
194 #endif
ragge
1.1
195
ragge
1.2
196 void
plunky
1.18
197 fldty(struct symtab *p)
198 {
199         /* fix up type of field p */
200 }
ragge
1.1
201
stefan
1.4
202 /*
ragge
1.2
203  * XXX - fix genswitch.
ragge
1.1
204  */
stefan
1.4
205 int
206 mygenswitch(int numTWORD typestruct swents **pint n)
ragge
1.1
207 {
stefan
1.4
208         return 0;
ragge
1.1
209 }
210
ragge
1.2
211 #ifdef notyet
ragge
1.1
212 struct sw heapsw[SWITSZ];       /* heap for switches */
213
plunky
1.18
214 genswitch(register struct sw *pint n)
215 {
ragge
1.1
216         /*      p points to an array of structures, each consisting
217                 of a constant value and a label.
218                 The first is >=0 if there is a default label;
219                 its value is the label number
220                 The entries p[1] to p[n] are the nontrivial cases
221                 */
222         register i;
223         register CONSZ jrange;
224         register dlabswlab;
225
226         range = p[n].sval-p[1].sval;
227
228         ifrange>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */
229
230                 swlab = getlab();
231                 dlab = p->slab >= 0 ? p->slab : getlab();
232
233                 /* already in r0 */
234                 printf("        casel   r0,$%ld,$%ld\n"p[1].svalrange);
ragge
1.2
235                 deflab1(swlab);
ragge
1.1
236                 fori=1,j=p[1].svali<=nj++) {
ragge
1.2
237                         printf("        .word   " LABFMT "-" LABFMT "\n",
238                             (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
ragge
1.1
239                                 swlab);
240                         }
241
242                 ifp->slab >= 0 ) branchdlab );
ragge
1.2
243                 else deflab1(dlab);
ragge
1.1
244                 return;
245
246                 }
247
248         ifn>8 ) {     /* heap switch */
249
250                 heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
251                 makeheap(pn1);      /* build heap */
252
253                 walkheap(1n); /* produce code */
254
255                 ifp->slab >= 0 )
256                         branchdlab );
257                 else
ragge
1.2
258                         deflab1(dlab);
ragge
1.1
259                 return;
260         }
261
262         /* debugging code */
263
264         /* out for the moment
265         if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
266         */
267
268         /* simple switch code */
269
270         fori=1i<=n; ++i ){
271                 /* already in r0 */
272
273                 printf"       cmpl    r0,$" );
274                 printfCONFMTp[i].sval );
ragge
1.2
275                 printf"\n     jeql    " LBLFMT "\n"p[i].slab );
ragge
1.1
276                 }
277
278         ifp->slab>=0 ) branchp->slab );
plunky
1.18
279 }
ragge
1.1
280
plunky
1.18
281 makeheap(register struct sw *pint mint n)
ragge
1.1
282 {
283         register int q;
284
285         q = select(m);
286         heapsw[n] = p[q];
287         ifq>1 ) makeheap(pq-12*n);
288         ifq<m ) makeheap(p+qm-q2*n+1);
289 }
290
plunky
1.18
291 select(int m)
292 {
ragge
1.1
293         register int l,i,k;
294
295         for(i=1; ; i*=2)
296                 if( (i-1) > m ) break;
297         l = ((k = i/2 - 1) + 1)/2;
298         returnl + (m-k < l ? m-k : l));
299 }
300
plunky
1.18
301 walkheap(int startint limit)
ragge
1.1
302 {
303         int label;
304
305         ifstart > limit ) return;
306         printf("        cmpl    r0,$%d\n",  heapsw[start].sval);
ragge
1.2
307         printf("        jeql    " LBLFMT "\n"heapsw[start].slab);
ragge
1.1
308         if( (2*start) > limit ) {
ragge
1.2
309                 printf("        jbr     " LBLFMT "\n"heapsw[0].slab);
ragge
1.1
310                 return;
311         }
312         if( (2*start+1) <= limit ) {
313                 label = getlab();
ragge
1.2
314                 printf("        jgtr    " LBLFMT "\n"label);
ragge
1.1
315         } else
ragge
1.2
316                 printf("        jgtr    " LBLFMT "\n"heapsw[0].slab);
ragge
1.1
317         walkheap2*startlimit);
318         if( (2*start+1) <= limit ) {
ragge
1.2
319                 deflab1(label);
ragge
1.1
320                 walkheap2*start+1limit);
321         }
322 }
ragge
1.2
323 #endif
plunky
1.18
324
ragge
1.3
325 /*
326  * Called with a function call with arguments as argument.
327  * This is done early in buildtree() and only done once.
328  */
329 NODE *
330 funcode(NODE *p)
331 {
ragge
1.12
332         NODE *r, *l;
333
334         /* Fix function call arguments. On vax, just add funarg */
335         for (r = p->n_rightr->n_op == CMr = r->n_left) {
ragge
1.15
336                 if (r->n_right->n_op != STARG) {
337                         r->n_right = intprom(r->n_right);
ragge
1.12
338                         r->n_right = block(FUNARGr->n_rightNIL,
339                             r->n_right->n_typer->n_right->n_df,
340                             r->n_right->n_ap);
ragge
1.15
341                 }
ragge
1.12
342         }
343         if (r->n_op != STARG) {
344                 l = talloc();
345                 *l = *r;
ragge
1.15
346                 r->n_op = FUNARG;
347                 r->n_left = l;
348                 r->n_left = intprom(r->n_left);
349                 r->n_type = r->n_left->n_type;
ragge
1.12
350         }
ragge
1.3
351         return p;
352 }
ragge
1.16
353
354 /*
355  * Generate the builtin code for FFS.
356  */
357 NODE *
ragge
1.21
358 builtin_ffs(const struct bitable *btNODE *a)
ragge
1.16
359 {
360         NODE *p, *q, *r;
361
ragge
1.21
362         p = tempnode(0bt->rt00);
ragge
1.16
363         r = block(XARGccopy(p), NILINT00);
364         r->n_name = "=&r";
365         q = block(XARGaNILINT00);
366         q->n_name = "g";
367         q = block(CMrqINT00);
368         q = block(XASMqblock(ICON00STRTY00), INT00);
369         q->n_name = "ffs $0,$32,%1,%0;bneq 1f;mnegl $1,%0;1:;incl %0";
ragge
1.21
370         p = block(COMOPqpbt->rt00);
ragge
1.16
371         return p;
372 }
373
ragge
1.19
374 NODE *  
ragge
1.21
375 builtin_ffsl(const struct bitable *btNODE *a)
ragge
1.19
376 {       
ragge
1.21
377         return builtin_ffs(bta);
ragge
1.19
378 }
379
380 NODE *  
ragge
1.21
381 builtin_ffsll(const struct bitable *btNODE *a)
ragge
1.19
382 {
383         cerror("builtin_ffsll unimplemented");
384         return NIL;
385 }
386
ragge
1.16
387 NODE *
ragge
1.21
388 vax_builtin_return_address(const struct bitable *btNODE *a)
ragge
1.16
389 {
ragge
1.21
390         NODE *f;
ragge
1.16
391
392         if (a == NULL || a->n_op != ICON)
393                 goto bad;
394
395         if (a->n_lval != 0)
396                 werror("unsupported argument");
397
398         tfree(a);
399
400         f = block(REGNILNILINCREF(PTR+CHAR), 00);
401         regno(f) = FPREG;
402         f = block(UMUL,
403                 block(PLUSf,
404                     bcon(16), INCREF(PTR+CHAR), 00), NILPTR+CHAR00);
405         f = makety(fPTR+VOID000);
406
407         return f;
408 bad:
409         uerror("bad argument to __builtin_return_address");
410         return bcon(0);
411 }
412
413 NODE *
ragge
1.21
414 vax_builtin_frame_address(const struct bitable *btNODE *a)
ragge
1.16
415 {
416         int nframes;
ragge
1.21
417         NODE *f;
ragge
1.16
418
419         if (a == NULL || a->n_op != ICON)
420                 goto bad;
421
422         nframes = a->n_lval;
423
424         tfree(a);
425
ragge
1.17
426         f = block(REGNILNILPTR+CHAR00);
ragge
1.16
427         regno(f) = FPREG;
428
429         while (nframes--) {
430                 f = block(UMUL,
431                         block(PLUSf,
432                             bcon(12), INCREF(PTR+CHAR), 00),
433                                 NILPTR+CHAR00);
434                 f = makety(fPTR+CHAR000);
435         }
436
437         return f;
438 bad:
439         uerror("bad argument to __builtin_frame_address");
440         return bcon(0);
441 }
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-08-27 20:58 +0200