Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20060216164630

Diff

Diff from 1.60 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/common.c

Annotated File View

ragge
1.60
1 /*      $Id: common.c,v 1.60 2006/02/16 16:46:30 ragge Exp $    */
ragge
1.29
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
ragge
1.2
63 #include <stdarg.h>
64 #include <stdlib.h>
ragge
1.10
65 #include <stdio.h>
pj
1.54
66 #include <string.h>
ragge
1.2
67
ragge
1.32
68 #include "pass2.h"
ragge
1.1
69
70 # ifndef EXIT
71 # define EXIT exit
72 # endif
73
74 int nerrors = 0;  /* number of errors */
ragge
1.37
75 char *ftitle;
76 int lineno;
ragge
1.1
77
ragge
1.10
78 #ifndef WHERE
79 #define WHERE(ch) fprintf(stderr, "%s, line %d: ", ftitle, lineno);
80 #endif
ragge
1.1
81
ragge
1.2
82 /*
83  * nonfatal error message
84  * the routine where is different for pass 1 and pass 2;
85  * it tells where the error took place
86  */
87 void
88 uerror(char *s, ...)
89 {
90         va_list ap;
ragge
1.1
91
ragge
1.2
92         va_start(aps);
ragge
1.1
93         ++nerrors;
ragge
1.10
94         WHERE('u');
ragge
1.2
95         vfprintf(stderrsap);
96         fprintf(stderr"\n");
97         if (nerrors > 30)
98                 cerror("too many errors");
99         va_end(ap);
100 }
101
102 /*
103  * compiler error: die
104  */
105 void
106 cerror(char *s, ...)
107 {
108         va_list ap;
ragge
1.1
109
ragge
1.2
110         va_start(aps);
ragge
1.10
111         WHERE('c');
ragge
1.2
112
113         /* give the compiler the benefit of the doubt */
114         if (nerrors && nerrors <= 30) {
115                 fprintf(stderr,
116                     "cannot recover from earlier errors: goodbye!\n");
117         } else {
118                 fprintf(stderr"compiler error: ");
119                 vfprintf(stderrsap);
120                 fprintf(stderr"\n");
121         }
122         va_end(ap);
ragge
1.1
123         EXIT(1);
ragge
1.2
124 }
ragge
1.1
125
ragge
1.2
126 /*
127  * warning
128  */
129 void
130 werror(char *s, ...)
131 {
132         va_list ap;
133
134         va_start(aps);
ragge
1.10
135         WHERE('w');
ragge
1.2
136         fprintf(stderr"warning: ");
137         vfprintf(stderrsap);
138         fprintf(stderr"\n");
139 }
ragge
1.1
140
ragge
1.37
141 #ifndef MKEXT
ragge
1.22
142 static NODE *freelink;
ragge
1.24
143 static int usednodes;
ragge
1.22
144
ragge
1.1
145 NODE *
ragge
1.2
146 talloc()
147 {
ragge
1.24
148         extern int inlnodecntrecovernodes;
149         register NODE *p;
150
151         if ((usednodes++ - inlnodecnt) > TREESZ)
ragge
1.25
152                 cerror("out of tree space; usednodes %d inlnodecnt %d",
153                     usednodesinlnodecnt);
ragge
1.1
154
ragge
1.24
155         if (recovernodes)
156                 inlnodecnt++;
ragge
1.22
157         if (freelink != NULL) {
158                 p = freelink;
159                 freelink = p->next;
160                 if (p->n_op != FREE)
ragge
1.23
161                         cerror("node not FREE: %p"p);
162                 if (nflag)
163                         printf("alloc node %p from freelist\n"p);
ragge
1.22
164                 return p;
165         }
166
ragge
1.24
167         p = permalloc(sizeof(NODE));
168         p->n_op = FREE;
169         if (nflag)
170                 printf("alloc node %p from memory\n"p);
171         return p;
ragge
1.2
172 }
ragge
1.47
173
174 /*
175  * make a fresh copy of p
176  */
177 NODE *
178 tcopy(NODE *p)
179 {
180         NODE *q;
181
182         q = talloc();
183         *q = *p;
184
185         switch (optype(q->n_op)) {
186         case BITYPE:
187                 q->n_right = tcopy(p->n_right);
188         case UTYPE:
189                 q->n_left = tcopy(p->n_left);
190         }
191
192         return(q);
193 }
194
ragge
1.1
195
ragge
1.2
196 /*
197  * ensure that all nodes have been freed
198  */
199 void
200 tcheck()
201 {
ragge
1.24
202         extern int inlnodecnt;
ragge
1.1
203
ragge
1.24
204         if (nerrors)
205                 return;
206
207         if ((usednodes - inlnodecnt) != 0)
208                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
209 }
ragge
1.1
210
ragge
1.2
211 /*
212  * free the tree p
213  */
214 void
215 tfree(NODE *p)
216 {
ragge
1.12
217         if (p->n_op != FREE)
ragge
1.51
218                 walkf(p, (void (*)(NODE *))nfree);
ragge
1.2
219 }
ragge
1.1
220
ragge
1.51
221 /*
222  * Free a node, and return its left descendant.
223  * It is up to the caller to know whether the return value is usable.
224  */
225 NODE *
ragge
1.22
226 nfree(NODE *p)
ragge
1.2
227 {
ragge
1.24
228         extern int inlnodecntrecovernodes;
ragge
1.51
229         NODE *l;
ragge
1.38
230 #ifdef PCC_DEBUG_NODES
ragge
1.31
231         NODE *q;
ragge
1.36
232 #endif
ragge
1.22
233
ragge
1.51
234         if (p == NULL)
235                 cerror("freeing blank node!");
236                 
237         l = p->n_left;
238         if (p->n_op == FREE)
239                 cerror("freeing FREE node"p);
ragge
1.38
240 #ifdef PCC_DEBUG_NODES
ragge
1.51
241         q = freelink;
242         while (q != NULL) {
243                 if (q == p)
244                         cerror("freeing free node %p"p);
245                 q = q->next;
246         }
ragge
1.36
247 #endif
ragge
1.22
248
ragge
1.51
249         if (nflag)
250                 printf("freeing node %p\n"p);
251         p->n_op = FREE;
252         p->next = freelink;
253         freelink = p;
254         usednodes--;
255         if (recovernodes)
256                 inlnodecnt--;
257         return l;
ragge
1.2
258 }
ragge
1.37
259 #endif
260
261 #ifdef MKEXT
262 #define coptype(o)      (dope[o]&TYFLG)
263 #else
ragge
1.34
264 int cdope(int);
ragge
1.37
265 #define coptype(o)      (cdope(o)&TYFLG)
266 #endif
ragge
1.34
267
ragge
1.2
268 void
ragge
1.60
269 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
270 {
ragge
1.1
271
272         int down1down2;
273
274         more:
275         down1 = down2 = 0;
276
ragge
1.2
277         (*f)(tdown, &down1, &down2);
ragge
1.1
278
ragge
1.34
279         switch (coptypet->n_op )) {
ragge
1.1
280
281         case BITYPE:
ragge
1.12
282                 fwalkt->n_leftfdown1 );
283                 t = t->n_right;
ragge
1.1
284                 down = down2;
285                 goto more;
286
287         case UTYPE:
ragge
1.12
288                 t = t->n_left;
ragge
1.1
289                 down = down1;
290                 goto more;
291
292         }
ragge
1.2
293 }
ragge
1.1
294
ragge
1.2
295 void
296 walkf(NODE *tvoid (*f)(NODE *))
297 {
298         int opty;
ragge
1.1
299
ragge
1.34
300         opty = coptype(t->n_op);
ragge
1.1
301
ragge
1.2
302         if (opty != LTYPE)
ragge
1.12
303                 walkft->n_leftf );
ragge
1.2
304         if (opty == BITYPE)
ragge
1.12
305                 walkft->n_rightf );
ragge
1.2
306         (*f)(t);
307 }
ragge
1.1
308
ragge
1.11
309 int dope[DSIZE];
ragge
1.1
310 char *opst[DSIZE];
311
ragge
1.2
312 struct dopest {
313         int dopeop;
314         char opst[8];
315         int dopeval;
316 indope[] = {
317         { NAME"NAME"LTYPE, },
318         { REG"REG"LTYPE, },
319         { OREG"OREG"LTYPE, },
ragge
1.52
320         { TEMP"TEMP"LTYPE, },
ragge
1.46
321         { MOVE"MOVE"UTYPE, },
ragge
1.2
322         { ICON"ICON"LTYPE, },
323         { FCON"FCON"LTYPE, },
324         { CCODES"CCODES"LTYPE, },
ragge
1.41
325         { UMINUS"U-"UTYPE, },
326         { UMUL"U*"UTYPE, },
ragge
1.44
327         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
328         { UCALL"UCALL"UTYPE|CALLFLG, },
329         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
330         { COMPL"~"UTYPE, },
331         { FORCE"FORCE"UTYPE, },
332         { INIT"INIT"UTYPE, },
333         { SCONV"SCONV"UTYPE, },
334         { PCONV"PCONV"UTYPE, },
335         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
336         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
337         { MUL"*"BITYPE|FLOFLG|MULFLG, },
338         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
339         { CM","BITYPE, },
340         { ASSIGN"="BITYPE|ASGFLG, },
341         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
342         { MOD"%"BITYPE|DIVFLG, },
343         { LS"<<"BITYPE|SHFFLG, },
344         { RS">>"BITYPE|SHFFLG, },
345         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
346         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
347         { INCR"++"BITYPE|ASGFLG, },
348         { DECR"--"BITYPE|ASGFLG, },
349         { STREF"->"BITYPE, },
350         { CALL"CALL"BITYPE|CALLFLG, },
351         { FORTCALL"FCALL"BITYPE|CALLFLG, },
352         { EQ"=="BITYPE|LOGFLG, },
353         { NE"!="BITYPE|LOGFLG, },
354         { LE"<="BITYPE|LOGFLG, },
355         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
356         { GE">="BITYPE|LOGFLG, },
ragge
1.2
357         { GT">"BITYPE|LOGFLG, },
358         { UGT"UGT"BITYPE|LOGFLG, },
359         { UGE"UGE"BITYPE|LOGFLG, },
360         { ULT"ULT"BITYPE|LOGFLG, },
361         { ULE"ULE"BITYPE|LOGFLG, },
362         { CBRANCH"CBRANCH"BITYPE, },
363         { FLD"FLD"UTYPE, },
364         { PMCONV"PMCONV"BITYPE, },
365         { PVCONV"PVCONV"BITYPE, },
366         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
367         { GOTO"GOTO"UTYPE, },
368         { STASG"STASG"BITYPE|ASGFLG, },
369         { STARG"STARG"UTYPE, },
370         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
371         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
372         { ADDROF"U&"UTYPE, },
ragge
1.1
373
ragge
1.2
374         { -1,   "",     0 },
ragge
1.1
375 };
376
ragge
1.2
377 void
378 mkdope()
379 {
380         struct dopest *q;
ragge
1.1
381
382         forq = indopeq->dopeop >= 0; ++q ){
383                 dope[q->dopeop] = q->dopeval;
384                 opst[q->dopeop] = q->opst;
385         }
ragge
1.2
386 }
387
388 /*
389  * output a nice description of the type of t
390  */
391 void
ragge
1.45
392 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
393 {
ragge
1.1
394         static char * tnames[] = {
395                 "undef",
396                 "farg",
397                 "char",
ragge
1.29
398                 "uchar",
ragge
1.1
399                 "short",
ragge
1.29
400                 "ushort",
ragge
1.1
401                 "int",
ragge
1.29
402                 "unsigned",
ragge
1.1
403                 "long",
ragge
1.29
404                 "ulong",
ragge
1.9
405                 "longlong",
ragge
1.29
406                 "ulonglong",
ragge
1.1
407                 "float",
408                 "double",
ragge
1.29
409                 "ldouble",
ragge
1.1
410                 "strty",
411                 "unionty",
412                 "enumty",
413                 "moety",
ragge
1.29
414                 "void",
ragge
1.1
415                 "?""?"
416                 };
417
ragge
1.35
418         for(;; t = DECREF(t), q = DECREF(q)) {
419                 if (ISCON(q))
ragge
1.45
420                         fputc('C'fp);
ragge
1.35
421                 if (ISVOL(q))
ragge
1.45
422                         fputc('V'fp);
ragge
1.1
423
ragge
1.2
424                 if (ISPTR(t))
ragge
1.45
425                         fprintf(fp"PTR ");
ragge
1.2
426                 else if (ISFTN(t))
ragge
1.45
427                         fprintf(fp"FTN ");
ragge
1.2
428                 else if (ISARY(t))
ragge
1.45
429                         fprintf(fp"ARY ");
ragge
1.1
430                 else {
ragge
1.45
431                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
432                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
433                         return;
434                 }
435         }
ragge
1.2
436 }
ragge
1.13
437
ragge
1.57
438 int crslab = 10;
ragge
1.13
439 /*
ragge
1.14
440  * Return a number for internal labels.
441  */
442 int 
443 getlab()
444 {
445         return crslab++;
446 }
447
448 /*
ragge
1.13
449  * Memory allocation routines.
450  * Memory are allocated from the system in MEMCHUNKSZ blocks.
451  * permalloc() returns a bunch of memory that is never freed.
452  * Memory allocated through tmpalloc() will be released the
453  * next time a function is ended (via tmpfree()).
454  */
455
456 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.56
457 #define ROUNDUP(x) ((x) + (sizeof(ALIGNMENT)-1)) & ~(sizeof(ALIGNMENT)-1)
ragge
1.13
458
459 static char *allocpole;
460 static int allocleft;
ragge
1.17
461 static char *tmppole;
462 static int tmpleft;
ragge
1.18
463 int permallocsizetmpallocsizelostmem;
ragge
1.13
464
465 void *
466 permalloc(int size)
467 {
468         void *rv;
469
470 //printf("permalloc: allocpole %p allocleft %d size %d ", allocpole, allocleft, size);
471         if (size > MEMCHUNKSZ)
472                 cerror("permalloc");
ragge
1.20
473         if (size <= 0)
474                 cerror("permalloc2");
ragge
1.18
475         if (allocleft < size) {
ragge
1.13
476                 /* looses unused bytes */
ragge
1.18
477                 lostmem += allocleft;
ragge
1.17
478 //fprintf(stderr, "allocating perm\n");
ragge
1.13
479                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
480                         cerror("permalloc: out of memory");
481                 allocleft = MEMCHUNKSZ;
482         }
ragge
1.16
483         size = ROUNDUP(size);
ragge
1.13
484         rv = &allocpole[MEMCHUNKSZ-allocleft];
485 //printf("rv %p\n", rv);
486         allocleft -= size;
ragge
1.17
487         permallocsize += size;
ragge
1.13
488         return rv;
489 }
490
ragge
1.17
491 static char *tmplink;
492
ragge
1.13
493 void *
pj
1.54
494 tmpcalloc(int size)
495 {
496         void *rv;
497
498         rv = tmpalloc(size);
499         memset(rv0size);
500         return rv;
501 }
502
503 void *
ragge
1.13
504 tmpalloc(int size)
505 {
ragge
1.17
506         void *rv;
507
ragge
1.59
508         if (size > MEMCHUNKSZ) {
509                 return malloc(size);
510         //      cerror("tmpalloc %d", size);
511         }
ragge
1.20
512         if (size <= 0)
513                 cerror("tmpalloc2");
ragge
1.17
514 //printf("tmpalloc: tmppole %p tmpleft %d size %d ", tmppole, tmpleft, size);
515         if (tmpleft < size) {
516                 if ((tmppole = malloc(MEMCHUNKSZ)) == NULL)
517                         cerror("tmpalloc: out of memory");
518 //fprintf(stderr, "allocating tmp\n");
ragge
1.53
519                 tmpleft = MEMCHUNKSZ - (ROUNDUP(sizeof(char *)));
ragge
1.17
520                 *(char **)tmppole = tmplink;
521                 tmplink = tmppole;
522         }
523         size = ROUNDUP(size);
524         rv = &tmppole[MEMCHUNKSZ-tmpleft];
525 //printf("rv %p\n", rv);
526         tmpleft -= size;
527         tmpallocsize += size;
528         return rv;
ragge
1.13
529 }
530
531 void
532 tmpfree()
533 {
ragge
1.18
534         char *f, *of;
535
536         f = tmplink;
ragge
1.19
537         if (f == NULL)
538                 return;
539         if (*(char **)f == NULL) {
ragge
1.55
540                 tmpleft = MEMCHUNKSZ - (ROUNDUP(sizeof(char *)));
ragge
1.19
541                 return;
542         }
ragge
1.18
543         while (f != NULL) {
544                 of = f;
545                 f = *(char **)f;
546                 free(of);
547         }
548         tmplink = tmppole = NULL;
549         tmpleft = 0;
ragge
1.17
550 //fprintf(stderr, "freeing tmp\n");
ragge
1.13
551         /* XXX - nothing right now */
ragge
1.16
552 }
553
554 /*
555  * Allocate space on the permanent stack for a string of length len+1
556  * and copy it there.
557  * Return the new address.
558  */
559 char *
560 newstring(char *sint len)
561 {
562         char *u, *c;
563
564         len++;
565         if (allocleft < len) {
566                 u = c = permalloc(len);
567         } else {
568                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
569                 allocleft -= ROUNDUP(len+1);
570         }
571         while (len--)
572                 *c++ = *s++;
573         return u;
ragge
1.13
574 }
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 00:41 +0100