Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20151012180713

Diff

Diff from 1.27 to:

Annotations

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

Annotated File View

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