Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120731073322

Diff

Diff from 1.103 to:

Annotations

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

Annotated File View

ragge
1.103
1 /*      $Id: common.c,v 1.103 2012/07/31 07:33:22 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  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 /*
28  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
29  *
30  * Redistribution and use in source and binary forms, with or without
31  * modification, are permitted provided that the following conditions
32  * are met:
33  *
34  * Redistributions of source code and documentation must retain the above
35  * copyright notice, this list of conditions and the following disclaimer.
36  * Redistributions in binary form must reproduce the above copyright
37  * notice, this list of conditionsand the following disclaimer in the
38  * documentation and/or other materials provided with the distribution.
39  * All advertising materials mentioning features or use of this software
40  * must display the following acknowledgement:
41  *      This product includes software developed or owned by Caldera
42  *      International, Inc.
43  * Neither the name of Caldera International, Inc. nor the names of other
44  * contributors may be used to endorse or promote products derived from
45  * this software without specific prior written permission.
46  *
47  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
48  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
49  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
52  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
56  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
57  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
58  * POSSIBILITY OF SUCH DAMAGE.
59  */
ragge
1.1
60
ragge
1.2
61 #include <stdarg.h>
plunky
1.98
62 #include <stddef.h>
ragge
1.2
63 #include <stdlib.h>
ragge
1.10
64 #include <stdio.h>
pj
1.54
65 #include <string.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 */
mickey
1.92
74 extern char *ftitle;
ragge
1.37
75 int lineno;
ragge
1.1
76
gmcgarry
1.76
77 int warniserr = 0;
78
ragge
1.10
79 #ifndef WHERE
80 #define WHERE(ch) fprintf(stderr, "%s, line %d: ", ftitle, lineno);
81 #endif
ragge
1.1
82
stefan
1.79
83 static void
84 incerr(void)
85 {
86         if (++nerrors > 30)
87                 cerror("too many errors");
88 }
89
ragge
1.2
90 /*
91  * nonfatal error message
92  * the routine where is different for pass 1 and pass 2;
93  * it tells where the error took place
94  */
95 void
96 uerror(char *s, ...)
97 {
98         va_list ap;
ragge
1.1
99
ragge
1.2
100         va_start(aps);
ragge
1.10
101         WHERE('u');
ragge
1.2
102         vfprintf(stderrsap);
103         fprintf(stderr"\n");
104         va_end(ap);
stefan
1.79
105         incerr();
ragge
1.2
106 }
107
108 /*
109  * compiler error: die
110  */
111 void
112 cerror(char *s, ...)
113 {
114         va_list ap;
ragge
1.1
115
ragge
1.2
116         va_start(aps);
ragge
1.10
117         WHERE('c');
ragge
1.2
118
119         /* give the compiler the benefit of the doubt */
120         if (nerrors && nerrors <= 30) {
121                 fprintf(stderr,
122                     "cannot recover from earlier errors: goodbye!\n");
123         } else {
124                 fprintf(stderr"compiler error: ");
125                 vfprintf(stderrsap);
126                 fprintf(stderr"\n");
127         }
128         va_end(ap);
ragge
1.1
129         EXIT(1);
ragge
1.2
130 }
ragge
1.1
131
ragge
1.2
132 /*
133  * warning
134  */
135 void
136 werror(char *s, ...)
137 {
138         va_list ap;
139
140         va_start(aps);
ragge
1.10
141         WHERE('w');
ragge
1.2
142         fprintf(stderr"warning: ");
143         vfprintf(stderrsap);
144         fprintf(stderr"\n");
ragge
1.70
145         va_end(ap);
stefan
1.79
146         if (warniserr)
147                 incerr();
ragge
1.2
148 }
ragge
1.1
149
ragge
1.37
150 #ifndef MKEXT
ragge
1.93
151
152 bittype warnary[(NUMW/NUMBITS)+1], werrary[(NUMW/NUMBITS)+1];
153
154 static char *warntxt[] = {
plunky
1.97
155         "conversion from '%s' to '%s' may alter its value"/* Wtruncate */
ragge
1.93
156         "function declaration isn't a prototype"/* Wstrict_prototypes */
157         "no previous prototype for `%s'"/* Wmissing_prototypes */
158         "return type defaults to `int'"/* Wimplicit_int */
159                  /* Wimplicit_function_declaration */
160         "implicit declaration of function '%s'",
161         "declaration of '%s' shadows a %s declaration"/* Wshadow */
162         "illegal pointer combination"/* Wpointer_sign */
163         "comparison between signed and unsigned"/* Wsign_compare */
164         "ignoring #pragma %s %s"/* Wunknown_pragmas */
165         "statement not reached"/* Wunreachable_code */
166 };
167
168 char *flagstr[] = {
169         "truncate""strict-prototypes""missing-prototypes"
170         "implicit-int""implicit-function-declaration""shadow"
171         "pointer-sign""sign-compare""unknown-pragmas"
172         "unreachable-code"
173 };
174
175 /*
176  * "emulate" the gcc warning flags.
177  */
178 void
179 Wflags(char *str)
180 {
plunky
1.99
181         int iissetiserr;
ragge
1.93
182
plunky
1.99
183         /* handle -Werror specially */
184         if (strcmp("error"str) == 0) {
ragge
1.93
185                 for (i = 0i < NUMWi++)
186                         BITSET(werraryi);
plunky
1.99
187
ragge
1.93
188                 return;
189         }
plunky
1.99
190
191         isset = 1;
192         if (strncmp("no-"str3) == 0) {
193                 str += 3;
194                 isset = 0;
195         }
196
197         iserr = 0;
198         if (strncmp("error="str6) == 0) {
199                 str += 6;
200                 iserr = 1;
201         }
202
ragge
1.93
203         for (i = 0i < NUMWi++) {
204                 if (strcmp(flagstr[i], str) != 0)
205                         continue;
plunky
1.99
206
207                 if (isset) {
208                         if (iserr)
209                                 BITSET(werraryi);
ragge
1.93
210                         BITSET(warnaryi);
plunky
1.99
211                 } else if (iserr) {
212                         BITCLEAR(werraryi);
213                 } else {
ragge
1.93
214                         BITCLEAR(warnaryi);
plunky
1.99
215                 }
216
ragge
1.93
217                 return;
218         }
plunky
1.99
219
ragge
1.93
220         fprintf(stderr"unrecognised warning option '%s'\n"str);
221 }
222
223 /*
224  * Deal with gcc warnings.
225  */
226 void
227 warner(int type, ...)
228 {
229         va_list ap;
230         char *w;
ragge
1.103
231         extern int issyshdr;
232
233         if (issyshdr && type == Wtruncate)
234                 return/* Too many false positives */
ragge
1.93
235
236         if (TESTBIT(warnarytype) == 0)
237                 return/* no warning */
238         if (TESTBIT(werrarytype)) {
239                 w = "error";
240                 incerr();
241         } else
242                 w = "warning";
243
244         va_start(aptype);
245         fprintf(stderr"%s:%d: %s: "ftitlelinenow);
246         vfprintf(stderrwarntxt[type], ap);
247         fprintf(stderr"\n");
248         va_end(ap);
249 }
250 #endif /* MKEXT */
251
252 #ifndef MKEXT
ragge
1.22
253 static NODE *freelink;
ragge
1.101
254 int usednodes;
ragge
1.22
255
ragge
1.77
256 #ifndef LANG_F77
ragge
1.1
257 NODE *
plunky
1.102
258 talloc(void)
ragge
1.2
259 {
ragge
1.24
260         register NODE *p;
261
ragge
1.63
262         usednodes++;
ragge
1.1
263
ragge
1.22
264         if (freelink != NULL) {
265                 p = freelink;
266                 freelink = p->next;
267                 if (p->n_op != FREE)
ragge
1.23
268                         cerror("node not FREE: %p"p);
plunky
1.100
269                 if (ndebug)
ragge
1.23
270                         printf("alloc node %p from freelist\n"p);
ragge
1.22
271                 return p;
272         }
273
ragge
1.24
274         p = permalloc(sizeof(NODE));
275         p->n_op = FREE;
plunky
1.100
276         if (ndebug)
ragge
1.24
277                 printf("alloc node %p from memory\n"p);
278         return p;
ragge
1.2
279 }
ragge
1.77
280 #endif
ragge
1.47
281
282 /*
283  * make a fresh copy of p
284  */
285 NODE *
286 tcopy(NODE *p)
287 {
288         NODE *q;
289
290         q = talloc();
291         *q = *p;
292
293         switch (optype(q->n_op)) {
294         case BITYPE:
295                 q->n_right = tcopy(p->n_right);
296         case UTYPE:
297                 q->n_left = tcopy(p->n_left);
298         }
299
300         return(q);
301 }
302
ragge
1.77
303 #ifndef LANG_F77
ragge
1.2
304 /*
305  * ensure that all nodes have been freed
306  */
307 void
plunky
1.102
308 tcheck(void)
ragge
1.2
309 {
ragge
1.24
310         extern int inlnodecnt;
ragge
1.1
311
ragge
1.24
312         if (nerrors)
313                 return;
314
315         if ((usednodes - inlnodecnt) != 0)
316                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
317 }
ragge
1.77
318 #endif
ragge
1.1
319
ragge
1.2
320 /*
321  * free the tree p
322  */
323 void
324 tfree(NODE *p)
325 {
ragge
1.12
326         if (p->n_op != FREE)
ragge
1.83
327                 walkf(p, (void (*)(NODE *, void *))nfree0);
ragge
1.2
328 }
ragge
1.1
329
ragge
1.51
330 /*
331  * Free a node, and return its left descendant.
332  * It is up to the caller to know whether the return value is usable.
333  */
334 NODE *
ragge
1.22
335 nfree(NODE *p)
ragge
1.2
336 {
ragge
1.51
337         NODE *l;
ragge
1.38
338 #ifdef PCC_DEBUG_NODES
ragge
1.31
339         NODE *q;
ragge
1.36
340 #endif
ragge
1.22
341
ragge
1.51
342         if (p == NULL)
343                 cerror("freeing blank node!");
344                 
345         l = p->n_left;
346         if (p->n_op == FREE)
347                 cerror("freeing FREE node"p);
ragge
1.38
348 #ifdef PCC_DEBUG_NODES
ragge
1.51
349         q = freelink;
350         while (q != NULL) {
351                 if (q == p)
352                         cerror("freeing free node %p"p);
353                 q = q->next;
354         }
ragge
1.36
355 #endif
ragge
1.22
356
plunky
1.100
357         if (ndebug)
ragge
1.51
358                 printf("freeing node %p\n"p);
359         p->n_op = FREE;
360         p->next = freelink;
361         freelink = p;
362         usednodes--;
363         return l;
ragge
1.2
364 }
ragge
1.37
365 #endif
366
ragge
1.77
367 #ifdef LANG_F77
368 #define OPTYPE(x) optype(x)
369 #else
370 #define OPTYPE(x) coptype(x)
371 #endif
372
ragge
1.37
373 #ifdef MKEXT
374 #define coptype(o)      (dope[o]&TYFLG)
375 #else
ragge
1.34
376 int cdope(int);
ragge
1.37
377 #define coptype(o)      (cdope(o)&TYFLG)
378 #endif
ragge
1.34
379
ragge
1.2
380 void
ragge
1.60
381 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
382 {
ragge
1.1
383
384         int down1down2;
385
386         more:
387         down1 = down2 = 0;
388
ragge
1.2
389         (*f)(tdown, &down1, &down2);
ragge
1.1
390
ragge
1.77
391         switch (OPTYPEt->n_op )) {
ragge
1.1
392
393         case BITYPE:
ragge
1.12
394                 fwalkt->n_leftfdown1 );
395                 t = t->n_right;
ragge
1.1
396                 down = down2;
397                 goto more;
398
399         case UTYPE:
ragge
1.12
400                 t = t->n_left;
ragge
1.1
401                 down = down1;
402                 goto more;
403
404         }
ragge
1.2
405 }
ragge
1.1
406
ragge
1.2
407 void
ragge
1.83
408 walkf(NODE *tvoid (*f)(NODE *, void *), void *arg)
ragge
1.2
409 {
410         int opty;
ragge
1.1
411
ragge
1.77
412
413         opty = OPTYPE(t->n_op);
ragge
1.1
414
ragge
1.2
415         if (opty != LTYPE)
ragge
1.83
416                 walkft->n_leftfarg );
ragge
1.2
417         if (opty == BITYPE)
ragge
1.83
418                 walkft->n_rightfarg );
419         (*f)(targ);
ragge
1.2
420 }
ragge
1.1
421
ragge
1.11
422 int dope[DSIZE];
ragge
1.1
423 char *opst[DSIZE];
424
ragge
1.2
425 struct dopest {
426         int dopeop;
427         char opst[8];
428         int dopeval;
429 indope[] = {
430         { NAME"NAME"LTYPE, },
431         { REG"REG"LTYPE, },
432         { OREG"OREG"LTYPE, },
ragge
1.52
433         { TEMP"TEMP"LTYPE, },
ragge
1.2
434         { ICON"ICON"LTYPE, },
435         { FCON"FCON"LTYPE, },
436         { CCODES"CCODES"LTYPE, },
ragge
1.41
437         { UMINUS"U-"UTYPE, },
438         { UMUL"U*"UTYPE, },
ragge
1.44
439         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
440         { UCALL"UCALL"UTYPE|CALLFLG, },
441         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
442         { COMPL"~"UTYPE, },
443         { FORCE"FORCE"UTYPE, },
ragge
1.75
444         { XARG"XARG"UTYPE, },
445         { XASM"XASM"BITYPE, },
ragge
1.2
446         { SCONV"SCONV"UTYPE, },
447         { PCONV"PCONV"UTYPE, },
448         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
449         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
450         { MUL"*"BITYPE|FLOFLG|MULFLG, },
451         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
452         { CM","BITYPE, },
453         { ASSIGN"="BITYPE|ASGFLG, },
454         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
455         { MOD"%"BITYPE|DIVFLG, },
456         { LS"<<"BITYPE|SHFFLG, },
457         { RS">>"BITYPE|SHFFLG, },
458         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
459         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
460         { STREF"->"BITYPE, },
461         { CALL"CALL"BITYPE|CALLFLG, },
462         { FORTCALL"FCALL"BITYPE|CALLFLG, },
463         { EQ"=="BITYPE|LOGFLG, },
464         { NE"!="BITYPE|LOGFLG, },
465         { LE"<="BITYPE|LOGFLG, },
466         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
467         { GE">="BITYPE|LOGFLG, },
ragge
1.2
468         { GT">"BITYPE|LOGFLG, },
469         { UGT"UGT"BITYPE|LOGFLG, },
470         { UGE"UGE"BITYPE|LOGFLG, },
471         { ULT"ULT"BITYPE|LOGFLG, },
472         { ULE"ULE"BITYPE|LOGFLG, },
473         { CBRANCH"CBRANCH"BITYPE, },
474         { FLD"FLD"UTYPE, },
475         { PMCONV"PMCONV"BITYPE, },
476         { PVCONV"PVCONV"BITYPE, },
477         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
478         { GOTO"GOTO"UTYPE, },
479         { STASG"STASG"BITYPE|ASGFLG, },
480         { STARG"STARG"UTYPE, },
481         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
482         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
483         { ADDROF"U&"UTYPE, },
ragge
1.1
484
ragge
1.2
485         { -1,   "",     0 },
ragge
1.1
486 };
487
ragge
1.2
488 void
plunky
1.102
489 mkdope(void)
ragge
1.2
490 {
491         struct dopest *q;
ragge
1.1
492
493         forq = indopeq->dopeop >= 0; ++q ){
494                 dope[q->dopeop] = q->dopeval;
495                 opst[q->dopeop] = q->opst;
496         }
ragge
1.2
497 }
498
499 /*
500  * output a nice description of the type of t
501  */
502 void
ragge
1.45
503 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
504 {
ragge
1.1
505         static char * tnames[] = {
506                 "undef",
ragge
1.95
507                 "bool",
ragge
1.1
508                 "char",
ragge
1.29
509                 "uchar",
ragge
1.1
510                 "short",
ragge
1.29
511                 "ushort",
ragge
1.1
512                 "int",
ragge
1.29
513                 "unsigned",
ragge
1.1
514                 "long",
ragge
1.29
515                 "ulong",
ragge
1.9
516                 "longlong",
ragge
1.29
517                 "ulonglong",
ragge
1.1
518                 "float",
519                 "double",
ragge
1.29
520                 "ldouble",
ragge
1.1
521                 "strty",
522                 "unionty",
523                 "enumty",
524                 "moety",
ragge
1.29
525                 "void",
ragge
1.66
526                 "signed"/* pass1 */
ragge
1.95
527                 "farg"/* pass1 */
ragge
1.90
528                 "fimag"/* pass1 */
529                 "dimag"/* pass1 */
530                 "limag"/* pass1 */
ragge
1.80
531                 "fcomplex"/* pass1 */
532                 "dcomplex"/* pass1 */
533                 "lcomplex"/* pass1 */
ragge
1.88
534                 "enumty"/* pass1 */
ragge
1.1
535                 "?""?"
536                 };
537
ragge
1.35
538         for(;; t = DECREF(t), q = DECREF(q)) {
539                 if (ISCON(q))
ragge
1.45
540                         fputc('C'fp);
ragge
1.35
541                 if (ISVOL(q))
ragge
1.45
542                         fputc('V'fp);
ragge
1.1
543
ragge
1.2
544                 if (ISPTR(t))
ragge
1.45
545                         fprintf(fp"PTR ");
ragge
1.2
546                 else if (ISFTN(t))
ragge
1.45
547                         fprintf(fp"FTN ");
ragge
1.2
548                 else if (ISARY(t))
ragge
1.45
549                         fprintf(fp"ARY ");
ragge
1.1
550                 else {
ragge
1.45
551                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
552                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
553                         return;
554                 }
555         }
ragge
1.2
556 }
ragge
1.13
557
ragge
1.14
558 /*
ragge
1.13
559  * Memory allocation routines.
560  * Memory are allocated from the system in MEMCHUNKSZ blocks.
561  * permalloc() returns a bunch of memory that is never freed.
562  * Memory allocated through tmpalloc() will be released the
563  * next time a function is ended (via tmpfree()).
564  */
565
566 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.85
567 struct balloc {
ragge
1.67
568         char a1;
569         union {
570                 long long l;
571                 long double d;
572         } a2;
573 };
574
plunky
1.98
575 #define ALIGNMENT offsetof(struct balloc, a2)
ragge
1.72
576 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
ragge
1.13
577
578 static char *allocpole;
579 static int allocleft;
ragge
1.18
580 int permallocsizetmpallocsizelostmem;
ragge
1.13
581
582 void *
583 permalloc(int size)
584 {
585         void *rv;
586
ragge
1.85
587         if (size > MEMCHUNKSZ) {
588                 if ((rv = malloc(size)) == NULL)
589                         cerror("permalloc: missing %d bytes"size);
590                 return rv;
591         }
ragge
1.20
592         if (size <= 0)
593                 cerror("permalloc2");
ragge
1.18
594         if (allocleft < size) {
plunky
1.94
595                 /* loses unused bytes */
ragge
1.18
596                 lostmem += allocleft;
ragge
1.13
597                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
598                         cerror("permalloc: out of memory");
599                 allocleft = MEMCHUNKSZ;
600         }
ragge
1.16
601         size = ROUNDUP(size);
ragge
1.13
602         rv = &allocpole[MEMCHUNKSZ-allocleft];
603         allocleft -= size;
ragge
1.17
604         permallocsize += size;
ragge
1.13
605         return rv;
606 }
607
608 void *
pj
1.54
609 tmpcalloc(int size)
610 {
611         void *rv;
612
613         rv = tmpalloc(size);
614         memset(rv0size);
615         return rv;
616 }
617
ragge
1.85
618 /*
619  * Duplicate a string onto the temporary heap.
620  */
621 char *
622 tmpstrdup(char *str)
623 {
624         int len;
625
626         len = strlen(str) + 1;
627         return memcpy(tmpalloc(len), strlen);
628 }
629
630 /*
631  * Allocation routines for temporary memory.
632  */
633 #if 0
634 #define ALLDEBUG(x)     printf x
635 #else
636 #define ALLDEBUG(x)
637 #endif
638
639 #define NELEM   ((MEMCHUNKSZ-ROUNDUP(sizeof(struct xalloc *)))/ALIGNMENT)
640 #define ELEMSZ  (ALIGNMENT)
641 #define MAXSZ   (NELEM*ELEMSZ)
642 struct xalloc {
643         struct xalloc *next;
644         union {
645                 struct balloc b/* for initial alignment */
646                 char elm[MAXSZ];
647         } u;
648 } *tapole, *tmpole;
649 int uselem = NELEM/* next unused element */
650
pj
1.54
651 void *
ragge
1.13
652 tmpalloc(int size)
653 {
ragge
1.85
654         struct xalloc *xp;
ragge
1.17
655         void *rv;
ragge
1.85
656         size_t nelem;
ragge
1.17
657
ragge
1.85
658         nelem = ROUNDUP(size)/ELEMSZ;
659         ALLDEBUG(("tmpalloc(%ld,%ld) %d (%zd) "ELEMSZNELEMsizenelem));
660         if (nelem > NELEM/2) {
661                 xp = malloc(size + ROUNDUP(sizeof(struct xalloc *)));
662                 if (xp == NULL)
663                         cerror("out of memory");
664                 ALLDEBUG(("XMEM! (%ld,%p) ",
665                     size + ROUNDUP(sizeof(struct xalloc *)), xp));
666                 xp->next = tmpole;
667                 tmpole = xp;
668                 ALLDEBUG(("rv %p\n", &xp->u.elm[0]));
669                 return &xp->u.elm[0];
670         }
671         if (nelem + uselem >= NELEM) {
672                 ALLDEBUG(("MOREMEM! "));
673                 /* alloc more */
674                 if ((xp = malloc(sizeof(struct xalloc))) == NULL)
675                         cerror("out of memory");
676                 xp->next = tapole;
677                 tapole = xp;
678                 uselem = 0;
679         } else
680                 xp = tapole;
681         rv = &xp->u.elm[uselem * ELEMSZ];
682         ALLDEBUG(("elemno %d "uselem));
683         uselem += nelem;
684         ALLDEBUG(("new %d rv %p\n"uselemrv));
ragge
1.17
685         return rv;
ragge
1.13
686 }
687
ragge
1.85
688 void
plunky
1.102
689 tmpfree(void)
ragge
1.61
690 {
ragge
1.85
691         struct xalloc *x1;
ragge
1.61
692
ragge
1.85
693         while (tmpole) {
694                 x1 = tmpole;
695                 tmpole = tmpole->next;
696                 ALLDEBUG(("XMEM! free %p\n"x1));
697                 free(x1);
698         }
699         while (tapole && tapole->next) {
700                 x1 = tapole;
701                 tapole = tapole->next;
702                 ALLDEBUG(("MOREMEM! free %p\n"x1));
703                 free(x1);
ragge
1.61
704         }
ragge
1.85
705         if (tapole)
706                 uselem = 0;
ragge
1.61
707 }
ragge
1.62
708
709 /*
ragge
1.85
710  * Set a mark for later removal from the temp heap.
ragge
1.81
711  */
ragge
1.85
712 void
713 markset(struct mark *m)
ragge
1.81
714 {
ragge
1.85
715         m->tmsav = tmpole;
716         m->tasav = tapole;
717         m->elem = uselem;
ragge
1.81
718 }
719
ragge
1.85
720 /*
721  * Remove everything on tmp heap from a mark.
722  */
ragge
1.13
723 void
ragge
1.85
724 markfree(struct mark *m)
ragge
1.13
725 {
ragge
1.85
726         struct xalloc *x1;
ragge
1.18
727
ragge
1.85
728         while (tmpole != m->tmsav) {
729                 x1 = tmpole;
730                 tmpole = tmpole->next;
731                 free(x1);
732         }
733         while (tapole != m->tasav) {
734                 x1 = tapole;
735                 tapole = tapole->next;
736                 free(x1);
ragge
1.19
737         }
ragge
1.85
738         uselem = m->elem;
ragge
1.16
739 }
740
741 /*
742  * Allocate space on the permanent stack for a string of length len+1
743  * and copy it there.
744  * Return the new address.
745  */
746 char *
747 newstring(char *sint len)
748 {
749         char *u, *c;
750
751         len++;
752         if (allocleft < len) {
753                 u = c = permalloc(len);
754         } else {
755                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
756                 allocleft -= ROUNDUP(len+1);
757         }
758         while (len--)
759                 *c++ = *s++;
760         return u;
ragge
1.13
761 }
ragge
1.80
762
763 /*
764  * Do a preorder walk of the CM list p and apply function f on each element.
765  */
766 void
767 flist(NODE *pvoid (*f)(NODE *, void *), void *arg)
768 {
769         if (p->n_op == CM) {
770                 (*f)(p->n_rightarg);
771                 flist(p->n_leftfarg);
772         } else
773                 (*f)(parg);
774 }
775
776 /*
777  * The same as flist but postorder.
778  */
779 void
780 listf(NODE *pvoid (*f)(NODE *))
781 {
782         if (p->n_op == CM) {
783                 listf(p->n_leftf);
784                 (*f)(p->n_right);
785         } else
786                 (*f)(p);
787 }
788
789 /*
790  * Get list argument number n from list, or NIL if out of list.
791  */
792 NODE *
793 listarg(NODE *pint nint *cnt)
794 {
795         NODE *r;
796
797         if (p->n_op == CM) {
798                 r = listarg(p->n_leftncnt);
799                 if (n == ++(*cnt))
800                         r = p->n_right;
801         } else {
802                 *cnt = 0;
803                 r = n == 0 ? p : NIL;
804         }
805         return r;
806 }
ragge
1.95
807
808 /*
809  * Make a type unsigned, if possible.
810  */
811 TWORD
812 enunsign(TWORD t)
813 {
814         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
815                 t |= 1;
816         return t;
817 }
818
819 /*
820  * Make a type signed, if possible.
821  */
822 TWORD
823 deunsign(TWORD t)
824 {
825         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
826                 t &= ~1;
827         return t;
828 }
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-11-01 03:01 +0100