Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20040429163048

Diff

Diff from 1.47 to:

Annotations

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

Annotated File View

ragge
1.47
1 /*      $Id: common.c,v 1.47 2004/04/29 16:30:49 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.1
364
ragge
1.2
365         { -1,   "",     0 },
ragge
1.1
366 };
367
ragge
1.2
368 void
369 mkdope()
370 {
371         struct dopest *q;
ragge
1.1
372
373         forq = indopeq->dopeop >= 0; ++q ){
374                 dope[q->dopeop] = q->dopeval;
375                 opst[q->dopeop] = q->opst;
376         }
ragge
1.2
377 }
378
379 /*
380  * output a nice description of the type of t
381  */
382 void
ragge
1.45
383 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
384 {
ragge
1.1
385         static char * tnames[] = {
386                 "undef",
387                 "farg",
388                 "char",
ragge
1.29
389                 "uchar",
ragge
1.1
390                 "short",
ragge
1.29
391                 "ushort",
ragge
1.1
392                 "int",
ragge
1.29
393                 "unsigned",
ragge
1.1
394                 "long",
ragge
1.29
395                 "ulong",
ragge
1.9
396                 "longlong",
ragge
1.29
397                 "ulonglong",
ragge
1.1
398                 "float",
399                 "double",
ragge
1.29
400                 "ldouble",
ragge
1.1
401                 "strty",
402                 "unionty",
403                 "enumty",
404                 "moety",
ragge
1.29
405                 "void",
ragge
1.1
406                 "?""?"
407                 };
408
ragge
1.35
409         for(;; t = DECREF(t), q = DECREF(q)) {
410                 if (ISCON(q))
ragge
1.45
411                         fputc('C'fp);
ragge
1.35
412                 if (ISVOL(q))
ragge
1.45
413                         fputc('V'fp);
ragge
1.1
414
ragge
1.2
415                 if (ISPTR(t))
ragge
1.45
416                         fprintf(fp"PTR ");
ragge
1.2
417                 else if (ISFTN(t))
ragge
1.45
418                         fprintf(fp"FTN ");
ragge
1.2
419                 else if (ISARY(t))
ragge
1.45
420                         fprintf(fp"ARY ");
ragge
1.1
421                 else {
ragge
1.45
422                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
423                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
424                         return;
425                 }
426         }
ragge
1.2
427 }
ragge
1.13
428
429 /*
ragge
1.14
430  * Return a number for internal labels.
431  */
432 int 
433 getlab()
434 {
435         static int crslab = 10;
436         return crslab++;
437 }
438
439 /*
ragge
1.13
440  * Memory allocation routines.
441  * Memory are allocated from the system in MEMCHUNKSZ blocks.
442  * permalloc() returns a bunch of memory that is never freed.
443  * Memory allocated through tmpalloc() will be released the
444  * next time a function is ended (via tmpfree()).
445  */
446
447 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.16
448 #define ROUNDUP(x) ((x) + (sizeof(int)-1)) & ~(sizeof(int)-1)
ragge
1.13
449
450 static char *allocpole;
451 static int allocleft;
ragge
1.17
452 static char *tmppole;
453 static int tmpleft;
ragge
1.18
454 int permallocsizetmpallocsizelostmem;
ragge
1.13
455
456 void *
457 permalloc(int size)
458 {
459         void *rv;
460
461 //printf("permalloc: allocpole %p allocleft %d size %d ", allocpole, allocleft, size);
462         if (size > MEMCHUNKSZ)
463                 cerror("permalloc");
ragge
1.20
464         if (size <= 0)
465                 cerror("permalloc2");
ragge
1.18
466         if (allocleft < size) {
ragge
1.13
467                 /* looses unused bytes */
ragge
1.18
468                 lostmem += allocleft;
ragge
1.17
469 //fprintf(stderr, "allocating perm\n");
ragge
1.13
470                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
471                         cerror("permalloc: out of memory");
472                 allocleft = MEMCHUNKSZ;
473         }
ragge
1.16
474         size = ROUNDUP(size);
ragge
1.13
475         rv = &allocpole[MEMCHUNKSZ-allocleft];
476 //printf("rv %p\n", rv);
477         allocleft -= size;
ragge
1.17
478         permallocsize += size;
ragge
1.13
479         return rv;
480 }
481
ragge
1.17
482 static char *tmplink;
483
ragge
1.13
484 void *
485 tmpalloc(int size)
486 {
ragge
1.17
487         void *rv;
488
489         if (size > MEMCHUNKSZ)
490                 cerror("tmpalloc");
ragge
1.20
491         if (size <= 0)
492                 cerror("tmpalloc2");
ragge
1.17
493 //printf("tmpalloc: tmppole %p tmpleft %d size %d ", tmppole, tmpleft, size);
494         if (tmpleft < size) {
495                 if ((tmppole = malloc(MEMCHUNKSZ)) == NULL)
496                         cerror("tmpalloc: out of memory");
497 //fprintf(stderr, "allocating tmp\n");
498                 tmpleft = MEMCHUNKSZ - sizeof(char *);
499                 *(char **)tmppole = tmplink;
500                 tmplink = tmppole;
501         }
502         size = ROUNDUP(size);
503         rv = &tmppole[MEMCHUNKSZ-tmpleft];
504 //printf("rv %p\n", rv);
505         tmpleft -= size;
506         tmpallocsize += size;
507         return rv;
ragge
1.13
508 }
509
510 void
511 tmpfree()
512 {
ragge
1.18
513         char *f, *of;
514
515         f = tmplink;
ragge
1.19
516         if (f == NULL)
517                 return;
518         if (*(char **)f == NULL) {
519                 tmpleft = MEMCHUNKSZ - sizeof(char *);
520                 return;
521         }
ragge
1.18
522         while (f != NULL) {
523                 of = f;
524                 f = *(char **)f;
525                 free(of);
526         }
527         tmplink = tmppole = NULL;
528         tmpleft = 0;
ragge
1.17
529 //fprintf(stderr, "freeing tmp\n");
ragge
1.13
530         /* XXX - nothing right now */
ragge
1.16
531 }
532
533 /*
534  * Allocate space on the permanent stack for a string of length len+1
535  * and copy it there.
536  * Return the new address.
537  */
538 char *
539 newstring(char *sint len)
540 {
541         char *u, *c;
542
543         len++;
544         if (allocleft < len) {
545                 u = c = permalloc(len);
546         } else {
547                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
548                 allocleft -= ROUNDUP(len+1);
549         }
550         while (len--)
551                 *c++ = *s++;
552         return u;
ragge
1.13
553 }
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-22 15:56 +0100