Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040509182657

Diff

Diff from 1.48 to:

Annotations

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

Annotated File View

ragge
1.48
1 /*      $Id: common.c,v 1.48 2004/05/09 18:26:57 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>
ragge
1.2
66
ragge
1.32
67 #include "pass2.h"
ragge
1.1
68
69 # ifndef EXIT
70 # define EXIT exit
71 # endif
72
73 int nerrors = 0;  /* number of errors */
ragge
1.37
74 char *ftitle;
75 int lineno;
ragge
1.1
76
ragge
1.10
77 #ifndef WHERE
78 #define WHERE(ch) fprintf(stderr, "%s, line %d: ", ftitle, lineno);
79 #endif
ragge
1.1
80
ragge
1.2
81 /*
82  * nonfatal error message
83  * the routine where is different for pass 1 and pass 2;
84  * it tells where the error took place
85  */
86 void
87 uerror(char *s, ...)
88 {
89         va_list ap;
ragge
1.1
90
ragge
1.2
91         va_start(aps);
ragge
1.1
92         ++nerrors;
ragge
1.10
93         WHERE('u');
ragge
1.2
94         vfprintf(stderrsap);
95         fprintf(stderr"\n");
96         if (nerrors > 30)
97                 cerror("too many errors");
98         va_end(ap);
99 }
100
101 /*
102  * compiler error: die
103  */
104 void
105 cerror(char *s, ...)
106 {
107         va_list ap;
ragge
1.1
108
ragge
1.2
109         va_start(aps);
ragge
1.10
110         WHERE('c');
ragge
1.2
111
112         /* give the compiler the benefit of the doubt */
113         if (nerrors && nerrors <= 30) {
114                 fprintf(stderr,
115                     "cannot recover from earlier errors: goodbye!\n");
116         } else {
117                 fprintf(stderr"compiler error: ");
118                 vfprintf(stderrsap);
119                 fprintf(stderr"\n");
120         }
121         va_end(ap);
ragge
1.1
122         EXIT(1);
ragge
1.2
123 }
ragge
1.1
124
ragge
1.2
125 /*
126  * warning
127  */
128 void
129 werror(char *s, ...)
130 {
131         va_list ap;
132
133         va_start(aps);
ragge
1.10
134         WHERE('w');
ragge
1.2
135         fprintf(stderr"warning: ");
136         vfprintf(stderrsap);
137         fprintf(stderr"\n");
138 }
ragge
1.1
139
ragge
1.37
140 #ifndef MKEXT
ragge
1.22
141 static NODE *freelink;
ragge
1.24
142 static int usednodes;
ragge
1.22
143
ragge
1.1
144 NODE *
ragge
1.2
145 talloc()
146 {
ragge
1.24
147         extern int inlnodecntrecovernodes;
148         register NODE *p;
149
150         if ((usednodes++ - inlnodecnt) > TREESZ)
ragge
1.25
151                 cerror("out of tree space; usednodes %d inlnodecnt %d",
152                     usednodesinlnodecnt);
ragge
1.1
153
ragge
1.24
154         if (recovernodes)
155                 inlnodecnt++;
ragge
1.22
156         if (freelink != NULL) {
157                 p = freelink;
158                 freelink = p->next;
159                 if (p->n_op != FREE)
ragge
1.23
160                         cerror("node not FREE: %p"p);
161                 if (nflag)
162                         printf("alloc node %p from freelist\n"p);
ragge
1.22
163                 return p;
164         }
165
ragge
1.24
166         p = permalloc(sizeof(NODE));
167         p->n_op = FREE;
168         if (nflag)
169                 printf("alloc node %p from memory\n"p);
170         return p;
ragge
1.2
171 }
ragge
1.47
172
173 /*
174  * make a fresh copy of p
175  */
176 NODE *
177 tcopy(NODE *p)
178 {
179         NODE *q;
180
181         q = talloc();
182         *q = *p;
183
184         switch (optype(q->n_op)) {
185         case BITYPE:
186                 q->n_right = tcopy(p->n_right);
187         case UTYPE:
188                 q->n_left = tcopy(p->n_left);
189         }
190
191         return(q);
192 }
193
ragge
1.1
194
ragge
1.2
195 /*
196  * ensure that all nodes have been freed
197  */
198 void
199 tcheck()
200 {
ragge
1.24
201         extern int inlnodecnt;
ragge
1.1
202
ragge
1.24
203         if (nerrors)
204                 return;
205
206         if ((usednodes - inlnodecnt) != 0)
207                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
208 }
ragge
1.1
209
ragge
1.2
210 /*
211  * free the tree p
212  */
213 void
214 tfree(NODE *p)
215 {
ragge
1.12
216         if (p->n_op != FREE)
ragge
1.22
217                 walkf(pnfree);
ragge
1.2
218 }
ragge
1.1
219
ragge
1.2
220 void
ragge
1.22
221 nfree(NODE *p)
ragge
1.2
222 {
ragge
1.24
223         extern int inlnodecntrecovernodes;
ragge
1.38
224 #ifdef PCC_DEBUG_NODES
ragge
1.31
225         NODE *q;
ragge
1.36
226 #endif
ragge
1.22
227
228         if (p != NULL) {
229                 if (p->n_op == FREE)
230                         cerror("freeing FREE node"p);
ragge
1.38
231 #ifdef PCC_DEBUG_NODES
ragge
1.22
232                 q = freelink;
233                 while (q != NULL) {
234                         if (q == p)
235                                 cerror("freeing free node %p"p);
236                         q = q->next;
237                 }
ragge
1.36
238 #endif
ragge
1.22
239
ragge
1.23
240                 if (nflag)
241                         printf("freeing node %p\n"p);
ragge
1.12
242                 p->n_op = FREE;
ragge
1.24
243                 p->next = freelink;
244                 freelink = p;
245                 usednodes--;
246                 if (recovernodes)
247                         inlnodecnt--;
ragge
1.22
248         } else
249                 cerror("freeing blank node!");
ragge
1.2
250 }
ragge
1.37
251 #endif
252
253 #ifdef MKEXT
254 #define coptype(o)      (dope[o]&TYFLG)
255 #else
ragge
1.34
256 int cdope(int);
ragge
1.37
257 #define coptype(o)      (cdope(o)&TYFLG)
258 #endif
ragge
1.34
259
ragge
1.2
260 void
261 fwalk(NODE *tint (*f)(NODE *, intint *, int *), int down)
262 {
ragge
1.1
263
264         int down1down2;
265
266         more:
267         down1 = down2 = 0;
268
ragge
1.2
269         (*f)(tdown, &down1, &down2);
ragge
1.1
270
ragge
1.34
271         switch (coptypet->n_op )) {
ragge
1.1
272
273         case BITYPE:
ragge
1.12
274                 fwalkt->n_leftfdown1 );
275                 t = t->n_right;
ragge
1.1
276                 down = down2;
277                 goto more;
278
279         case UTYPE:
ragge
1.12
280                 t = t->n_left;
ragge
1.1
281                 down = down1;
282                 goto more;
283
284         }
ragge
1.2
285 }
ragge
1.1
286
ragge
1.2
287 void
288 walkf(NODE *tvoid (*f)(NODE *))
289 {
290         int opty;
ragge
1.1
291
ragge
1.34
292         opty = coptype(t->n_op);
ragge
1.1
293
ragge
1.2
294         if (opty != LTYPE)
ragge
1.12
295                 walkft->n_leftf );
ragge
1.2
296         if (opty == BITYPE)
ragge
1.12
297                 walkft->n_rightf );
ragge
1.2
298         (*f)(t);
299 }
ragge
1.1
300
ragge
1.11
301 int dope[DSIZE];
ragge
1.1
302 char *opst[DSIZE];
303
ragge
1.2
304 struct dopest {
305         int dopeop;
306         char opst[8];
307         int dopeval;
308 indope[] = {
309         { NAME"NAME"LTYPE, },
310         { REG"REG"LTYPE, },
311         { OREG"OREG"LTYPE, },
ragge
1.31
312         { TEMP"TEMP"LTYPE, },
ragge
1.46
313         { MOVE"MOVE"UTYPE, },
ragge
1.2
314         { ICON"ICON"LTYPE, },
315         { FCON"FCON"LTYPE, },
316         { CCODES"CCODES"LTYPE, },
ragge
1.41
317         { UMINUS"U-"UTYPE, },
318         { UMUL"U*"UTYPE, },
ragge
1.44
319         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
320         { UCALL"UCALL"UTYPE|CALLFLG, },
321         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
322         { COMPL"~"UTYPE, },
323         { FORCE"FORCE"UTYPE, },
324         { INIT"INIT"UTYPE, },
325         { SCONV"SCONV"UTYPE, },
326         { PCONV"PCONV"UTYPE, },
327         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
328         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
329         { MUL"*"BITYPE|FLOFLG|MULFLG, },
330         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
331         { CM","BITYPE, },
332         { ASSIGN"="BITYPE|ASGFLG, },
333         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
334         { MOD"%"BITYPE|DIVFLG, },
335         { LS"<<"BITYPE|SHFFLG, },
336         { RS">>"BITYPE|SHFFLG, },
337         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
338         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
339         { INCR"++"BITYPE|ASGFLG, },
340         { DECR"--"BITYPE|ASGFLG, },
341         { STREF"->"BITYPE, },
342         { CALL"CALL"BITYPE|CALLFLG, },
343         { FORTCALL"FCALL"BITYPE|CALLFLG, },
344         { EQ"=="BITYPE|LOGFLG, },
345         { NE"!="BITYPE|LOGFLG, },
346         { LE"<="BITYPE|LOGFLG, },
347         { LT"<"BITYPE|LOGFLG, },
348         { GE">"BITYPE|LOGFLG, },
349         { GT">"BITYPE|LOGFLG, },
350         { UGT"UGT"BITYPE|LOGFLG, },
351         { UGE"UGE"BITYPE|LOGFLG, },
352         { ULT"ULT"BITYPE|LOGFLG, },
353         { ULE"ULE"BITYPE|LOGFLG, },
354         { CBRANCH"CBRANCH"BITYPE, },
355         { FLD"FLD"UTYPE, },
356         { PMCONV"PMCONV"BITYPE, },
357         { PVCONV"PVCONV"BITYPE, },
358         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
359         { GOTO"GOTO"UTYPE, },
360         { STASG"STASG"BITYPE|ASGFLG, },
361         { STARG"STARG"UTYPE, },
362         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
363         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
364         { ADDROF"U&"UTYPE, },
ragge
1.1
365
ragge
1.2
366         { -1,   "",     0 },
ragge
1.1
367 };
368
ragge
1.2
369 void
370 mkdope()
371 {
372         struct dopest *q;
ragge
1.1
373
374         forq = indopeq->dopeop >= 0; ++q ){
375                 dope[q->dopeop] = q->dopeval;
376                 opst[q->dopeop] = q->opst;
377         }
ragge
1.2
378 }
379
380 /*
381  * output a nice description of the type of t
382  */
383 void
ragge
1.45
384 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
385 {
ragge
1.1
386         static char * tnames[] = {
387                 "undef",
388                 "farg",
389                 "char",
ragge
1.29
390                 "uchar",
ragge
1.1
391                 "short",
ragge
1.29
392                 "ushort",
ragge
1.1
393                 "int",
ragge
1.29
394                 "unsigned",
ragge
1.1
395                 "long",
ragge
1.29
396                 "ulong",
ragge
1.9
397                 "longlong",
ragge
1.29
398                 "ulonglong",
ragge
1.1
399                 "float",
400                 "double",
ragge
1.29
401                 "ldouble",
ragge
1.1
402                 "strty",
403                 "unionty",
404                 "enumty",
405                 "moety",
ragge
1.29
406                 "void",
ragge
1.1
407                 "?""?"
408                 };
409
ragge
1.35
410         for(;; t = DECREF(t), q = DECREF(q)) {
411                 if (ISCON(q))
ragge
1.45
412                         fputc('C'fp);
ragge
1.35
413                 if (ISVOL(q))
ragge
1.45
414                         fputc('V'fp);
ragge
1.1
415
ragge
1.2
416                 if (ISPTR(t))
ragge
1.45
417                         fprintf(fp"PTR ");
ragge
1.2
418                 else if (ISFTN(t))
ragge
1.45
419                         fprintf(fp"FTN ");
ragge
1.2
420                 else if (ISARY(t))
ragge
1.45
421                         fprintf(fp"ARY ");
ragge
1.1
422                 else {
ragge
1.45
423                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
424                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
425                         return;
426                 }
427         }
ragge
1.2
428 }
ragge
1.13
429
430 /*
ragge
1.14
431  * Return a number for internal labels.
432  */
433 int 
434 getlab()
435 {
436         static int crslab = 10;
437         return crslab++;
438 }
439
440 /*
ragge
1.13
441  * Memory allocation routines.
442  * Memory are allocated from the system in MEMCHUNKSZ blocks.
443  * permalloc() returns a bunch of memory that is never freed.
444  * Memory allocated through tmpalloc() will be released the
445  * next time a function is ended (via tmpfree()).
446  */
447
448 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.16
449 #define ROUNDUP(x) ((x) + (sizeof(int)-1)) & ~(sizeof(int)-1)
ragge
1.13
450
451 static char *allocpole;
452 static int allocleft;
ragge
1.17
453 static char *tmppole;
454 static int tmpleft;
ragge
1.18
455 int permallocsizetmpallocsizelostmem;
ragge
1.13
456
457 void *
458 permalloc(int size)
459 {
460         void *rv;
461
462 //printf("permalloc: allocpole %p allocleft %d size %d ", allocpole, allocleft, size);
463         if (size > MEMCHUNKSZ)
464                 cerror("permalloc");
ragge
1.20
465         if (size <= 0)
466                 cerror("permalloc2");
ragge
1.18
467         if (allocleft < size) {
ragge
1.13
468                 /* looses unused bytes */
ragge
1.18
469                 lostmem += allocleft;
ragge
1.17
470 //fprintf(stderr, "allocating perm\n");
ragge
1.13
471                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
472                         cerror("permalloc: out of memory");
473                 allocleft = MEMCHUNKSZ;
474         }
ragge
1.16
475         size = ROUNDUP(size);
ragge
1.13
476         rv = &allocpole[MEMCHUNKSZ-allocleft];
477 //printf("rv %p\n", rv);
478         allocleft -= size;
ragge
1.17
479         permallocsize += size;
ragge
1.13
480         return rv;
481 }
482
ragge
1.17
483 static char *tmplink;
484
ragge
1.13
485 void *
486 tmpalloc(int size)
487 {
ragge
1.17
488         void *rv;
489
490         if (size > MEMCHUNKSZ)
491                 cerror("tmpalloc");
ragge
1.20
492         if (size <= 0)
493                 cerror("tmpalloc2");
ragge
1.17
494 //printf("tmpalloc: tmppole %p tmpleft %d size %d ", tmppole, tmpleft, size);
495         if (tmpleft < size) {
496                 if ((tmppole = malloc(MEMCHUNKSZ)) == NULL)
497                         cerror("tmpalloc: out of memory");
498 //fprintf(stderr, "allocating tmp\n");
499                 tmpleft = MEMCHUNKSZ - sizeof(char *);
500                 *(char **)tmppole = tmplink;
501                 tmplink = tmppole;
502         }
503         size = ROUNDUP(size);
504         rv = &tmppole[MEMCHUNKSZ-tmpleft];
505 //printf("rv %p\n", rv);
506         tmpleft -= size;
507         tmpallocsize += size;
508         return rv;
ragge
1.13
509 }
510
511 void
512 tmpfree()
513 {
ragge
1.18
514         char *f, *of;
515
516         f = tmplink;
ragge
1.19
517         if (f == NULL)
518                 return;
519         if (*(char **)f == NULL) {
520                 tmpleft = MEMCHUNKSZ - sizeof(char *);
521                 return;
522         }
ragge
1.18
523         while (f != NULL) {
524                 of = f;
525                 f = *(char **)f;
526                 free(of);
527         }
528         tmplink = tmppole = NULL;
529         tmpleft = 0;
ragge
1.17
530 //fprintf(stderr, "freeing tmp\n");
ragge
1.13
531         /* XXX - nothing right now */
ragge
1.16
532 }
533
534 /*
535  * Allocate space on the permanent stack for a string of length len+1
536  * and copy it there.
537  * Return the new address.
538  */
539 char *
540 newstring(char *sint len)
541 {
542         char *u, *c;
543
544         len++;
545         if (allocleft < len) {
546                 u = c = permalloc(len);
547         } else {
548                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
549                 allocleft -= ROUNDUP(len+1);
550         }
551         while (len--)
552                 *c++ = *s++;
553         return u;
ragge
1.13
554 }
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-10-30 18:35 +0100