Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20141012091818

Diff

Diff from 1.26 to:

Annotations

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

Annotated File View

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