Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060618101745

Diff

Diff from 1.1 to:

Annotations

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

Annotated File View

ragge
1.1
1 /*      $Id: code.c,v 1.1 2006/06/18 10:17:45 ragge Exp $       */
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
36 # include "mfile1"
37 #include <a.out.h>
38
39 int proflg = 0/* are we generating profiling code? */
40 int strftn = 0;  /* is the current function one which returns a value */
41 int gdebug;
42 int fdefflag;  /* are we within a function definition ? */
43 char NULLNAME[8];
44 int labelno;
45
46 branchn ){
47         /* output a branch to label n */
48         /* exception is an ordinary function branching to retlab: then, return */
49         ifn == retlab && !strftn ){
50                 printf"       ret\n" );
51                 }
52         else printf"  jbr     L%d\n"n );
53         }
54
55 int lastloc = { -1 };
56
57 short log2tab[] = {001223333};
58 #define LOG2SZ 9
59
60 defalign(n) {
61         /* cause the alignment to become a multiple of n */
62         n /= SZCHAR;
63         iflastloc != PROG && n > 1 ) printf"        .align  %d\n"n >= 0 && n < LOG2SZ ? log2tab[n] : 0 );
64         }
65
66 locctrl ){
67         register temp;
68         /* l is PROG, ADATA, DATA, STRNG, ISTRNG, or STAB */
69
70         ifl == lastloc ) return(l);
71         temp = lastloc;
72         lastloc = l;
73         switchl ){
74
75         case PROG:
76                 printf"       .text\n" );
77                 psline();
78                 break;
79
80         case DATA:
81         case ADATA:
82                 printf"       .data\n" );
83                 break;
84
85         case STRNG:
86                 printf"       .data   1\n" );
87                 break;
88
89         case ISTRNG:
90                 printf"       .data   2\n" );
91                 break;
92
93         case STAB:
94                 printf"       .stab\n" );
95                 break;
96
97         default:
98                 cerror"illegal location counter" );
99                 }
100
101         returntemp );
102         }
103
104 deflabn ){
105         /* output something to define the current position as label n */
106         printf"L%d:\n"n );
107         }
108
109 int crslab = 10;
110
111 getlab(){
112         /* return a number usable for a label */
113         return( ++crslab );
114         }
115
116
117 int ent_mask[] = {
118         0,0,0,0,00xfc00xf800xf000xe000xc000x8000};
119
120 int reg_use = 11;
121
122 efcode(){
123         /* code for the end of a function */
124
125         ifstrftn ){  /* copy output (in R2) to caller */
126                 register NODE *l, *r;
127                 register struct symtab *p;
128                 register TWORD t;
129                 register int j;
130                 int i;
131
132                 p = &stab[curftn];
133                 t = p->stype;
134                 t = DECREF(t);
135
136                 deflabretlab );
137
138                 i = getlab();   /* label for return area */
139                 printf("        .data\n" );
140                 printf("        .align  2\n" );
141                 printf("L%d:    .space  %d\n"itsize(tp->dimoffp->sizoff)/SZCHAR );
142                 printf("        .text\n" );
143                 psline();
144                 printf("        movab   L%d,r1\n"i);
145
146                 reached = 1;
147                 l = blockREGNILNILPTR|tp->dimoffp->sizoff );
148                 l->rval = 1;  /* R1 */
149                 l->lval = 0;  /* no offset */
150                 r = blockREGNILNILPTR|tp->dimoffp->sizoff );
151                 r->rval = 0;  /* R0 */
152                 r->lval = 0;
153                 l = buildtreeUNARY MULlNIL );
154                 r = buildtreeUNARY MULrNIL );
155                 l = buildtreeASSIGNlr );
156                 l->op = FREE;
157                 ecompl->left );
158                 printf"       movab   L%d,r0\n"i );
159                 /* turn off strftn flag, so return sequence will be generated */
160                 strftn = 0;
161                 }
162         branchretlab );
163         printf"       .set    .R%d,0x%x\n"ftnnoent_mask[reg_use] );
164         reg_use = 11;
165         p2bend();
166         fdefflag = 0;
167         }
168
169 bfcodean ) int a[]; {
170         /* code for the beginning of a function; a is an array of
171                 indices in stab for the arguments; n is the number */
172         register i;
173         register temp;
174         register struct symtab *p;
175         int off;
176         char *toreg();
177
178         locctrPROG );
179         p = &stab[curftn];
180         printf"       .align  1\n");
181         defnamp );
182         temp = p->stype;
183         temp = DECREF(temp);
184         strftn = (temp==STRTY) || (temp==UNIONTY);
185
186         retlab = getlab();
187
188         /* routine prolog */
189
190         printf"       .word   .R%d\n"ftnno);
191         if (gdebug) {
192                 pstab(NULLNAMEN_SLINE);
193                 printf("0,%d,LL%d\n"linenolabelno);
194                 printf("LL%d:\n"labelno++);
195         }
196         printf"       subl2   $.F%d,sp\n"ftnno);
197         ifproflg ) {  /* profile code */
198                 i = getlab();
199                 printf("        movab   L%d,r0\n"i);
200                 printf("        jsb     mcount\n");
201                 printf("        .data\n");
202                 printf("        .align  2\n");
203                 printf("L%d:    .long   0\n"i);
204                 printf("        .text\n");
205                 psline();
206                 }
207
208         off = ARGINIT;
209
210         fori=0i<n; ++i ){
211                 p = &stab[a[i]];
212                 ifp->sclass == REGISTER ){
213                         temp = p->offset;  /* save register number */
214                         p->sclass = PARAM;  /* forget that it is a register */
215                         p->offset = NOOFFSET;
216                         oallocp, &off );
217 /*tbl*/         printf"       %s      %d(ap),r%d\n"toreg(p->stype), p->offset/SZCHARtemp );
218                         p->offset = temp;  /* remember register number */
219                         p->sclass = REGISTER;   /* remember that it is a register */
220                         }
221                 else {
222                         ifoallocp, &off ) ) cerror"bad argument" );
223                         }
224
225                 }
226         fdefflag = 1;
227         }
228
229 bccode(){ /* called just before the first executable statment */
230                 /* by now, the automatics and register variables are allocated */
231         SETOFFautooffSZINT );
232         /* set aside store area offset */
233         p2bbegautooffregvar );
234         reg_use = (reg_use > regvar ? regvar : reg_use);
235         }
236
237 ejobcodeflag ){
238         /* called just before final exit */
239         /* flag is 1 if errors, 0 if none */
240         }
241
242 aobeg(){
243         /* called before removing automatics from stab */
244         }
245
246 aocode(pstruct symtab *p; {
247         /* called when automatic p removed from stab */
248         }
249
250 aoend(){
251         /* called after removing all automatics from stab */
252         }
253
254 defnamp ) register struct symtab *p; {
255         /* define the current location as the name p->sname */
256
257         ifp->sclass == EXTDEF ){
258                 printf"       .globl  %s\n"exnamep->sname ) );
259                 }
260         ifp->sclass == STATIC && p->slevel>1 ) deflabp->offset );
261         else printf"%s:\n"exnamep->sname ) );
262
263         }
264
265 bycodeti ){
266         /* put byte i+1 in a string */
267
268         i &= 07;
269         ift < 0 ){ /* end of the string */
270                 ifi != 0 ) printf"\n" );
271                 }
272
273         else { /* stash byte t into string */
274                 ifi == 0 ) printf"  .byte   " );
275                 else printf"," );
276                 printf"0x%x"t );
277                 ifi == 07 ) printf"\n" );
278                 }
279         }
280
281 zecoden ){
282         /* n integer words of zeros */
283         OFFSZ temp;
284         ifn <= 0 ) return;
285         printf"       .space  %d\n", (SZINT/SZCHAR)*n );
286         temp = n;
287         inoff += temp*SZINT;
288         }
289
290 fldalt ) unsigned t; { /* return the alignment of field of type t */
291         uerror"illegal field type" );
292         returnALINT );
293         }
294
295 fldtyp ) struct symtab *p; { /* fix up type of field p */
296         ;
297         }
298
299 where(c){ /* print location of error  */
300         /* c is either 'u', 'c', or 'w' */
301         /* GCOS version */
302         fprintfstderr"%s, line %d: "ftitlelineno );
303         }
304
305
306 /* tbl - toreg() returns a pointer to a char string
307                   which is the correct  "register move" for the passed type 
308  */
309 struct type_move {TWORD fromtypechar tostrng[8];} toreg_strs[] =
310         {
311         CHAR"cvtbl",
312         SHORT"cvtwl",
313         INT"movl",
314         LONG"movl",
315         FLOAT"movf",
316         DOUBLE"movd",
317         UCHAR,  "movzbl",
318         USHORT"movzwl",
319         UNSIGNED,       "movl",
320         ULONG,  "movl",
321         -1""
322         };
323
324 char
325 *toreg(type)
326         TWORD type;
327 {
328         struct type_move *p;
329
330         for ( p=toreg_strsp->fromtype > 0p++)
331                 if (p->fromtype == typereturn(p->tostrng);
332
333         /* type not found, must be a pointer type */
334         return("movl");
335 }
336 /* tbl */
337
338
339 mainargcargv ) char *argv[]; {
340         return(mainp1argcargv ));
341         }
342
343 struct sw heapsw[SWITSZ];       /* heap for switches */
344
345 genswitch(p,nregister struct sw *p;{
346         /*      p points to an array of structures, each consisting
347                 of a constant value and a label.
348                 The first is >=0 if there is a default label;
349                 its value is the label number
350                 The entries p[1] to p[n] are the nontrivial cases
351                 */
352         register i;
353         register CONSZ jrange;
354         register dlabswlab;
355
356         range = p[n].sval-p[1].sval;
357
358         ifrange>0 && range <= 3*n && n>=4 ){ /* implement a direct switch */
359
360                 swlab = getlab();
361                 dlab = p->slab >= 0 ? p->slab : getlab();
362
363                 /* already in r0 */
364                 printf("        casel   r0,$%ld,$%ld\n"p[1].svalrange);
365                 printf("L%d:\n"swlab);
366                 fori=1,j=p[1].svali<=nj++) {
367                         printf("        .word   L%d-L%d\n", (j == p[i].sval ? ((j=p[i++].sval), p[i-1].slab) : dlab),
368                                 swlab);
369                         }
370
371                 ifp->slab >= 0 ) branchdlab );
372                 else printf("L%d:\n"dlab);
373                 return;
374
375                 }
376
377         ifn>8 ) {     /* heap switch */
378
379                 heapsw[0].slab = dlab = p->slab >= 0 ? p->slab : getlab();
380                 makeheap(pn1);      /* build heap */
381
382                 walkheap(1n); /* produce code */
383
384                 ifp->slab >= 0 )
385                         branchdlab );
386                 else
387                         printf("L%d:\n"dlab);
388                 return;
389         }
390
391         /* debugging code */
392
393         /* out for the moment
394         if( n >= 4 ) werror( "inefficient switch: %d, %d", n, (int) (range/n) );
395         */
396
397         /* simple switch code */
398
399         fori=1i<=n; ++i ){
400                 /* already in r0 */
401
402                 printf"       cmpl    r0,$" );
403                 printfCONFMTp[i].sval );
404                 printf"\n     jeql    L%d\n"p[i].slab );
405                 }
406
407         ifp->slab>=0 ) branchp->slab );
408         }
409
410 makeheap(pmn)
411 register struct sw *p;
412 {
413         register int q;
414
415         q = select(m);
416         heapsw[n] = p[q];
417         ifq>1 ) makeheap(pq-12*n);
418         ifq<m ) makeheap(p+qm-q2*n+1);
419 }
420
421 select(m) {
422         register int l,i,k;
423
424         for(i=1; ; i*=2)
425                 if( (i-1) > m ) break;
426         l = ((k = i/2 - 1) + 1)/2;
427         returnl + (m-k < l ? m-k : l));
428 }
429
430 walkheap(startlimit)
431 {
432         int label;
433
434
435         ifstart > limit ) return;
436         printf("        cmpl    r0,$%d\n",  heapsw[start].sval);
437         printf("        jeql    L%d\n"heapsw[start].slab);
438         if( (2*start) > limit ) {
439                 printf("        jbr     L%d\n"heapsw[0].slab);
440                 return;
441         }
442         if( (2*start+1) <= limit ) {
443                 label = getlab();
444                 printf("        jgtr    L%d\n"label);
445         } else
446                 printf("        jgtr    L%d\n"heapsw[0].slab);
447         walkheap2*startlimit);
448         if( (2*start+1) <= limit ) {
449                 printf("L%d:\n"label);
450                 walkheap2*start+1limit);
451         }
452 }
FishEye: Open Source License registered to PCC.
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-12-21 07:55 +0100