Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120926195612

Diff

Diff from 1.108 to:

Annotations

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

Annotated File View

plunky
1.108
1 /*      $Id: common.c,v 1.108 2012/09/26 19:56:12 plunky 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
plunky
1.104
188                 warniserr = 1;
ragge
1.93
189                 return;
190         }
plunky
1.99
191
192         isset = 1;
193         if (strncmp("no-"str3) == 0) {
194                 str += 3;
195                 isset = 0;
196         }
197
198         iserr = 0;
199         if (strncmp("error="str6) == 0) {
200                 str += 6;
201                 iserr = 1;
202         }
203
ragge
1.93
204         for (i = 0i < NUMWi++) {
205                 if (strcmp(flagstr[i], str) != 0)
206                         continue;
plunky
1.99
207
208                 if (isset) {
209                         if (iserr)
210                                 BITSET(werraryi);
ragge
1.93
211                         BITSET(warnaryi);
plunky
1.99
212                 } else if (iserr) {
213                         BITCLEAR(werraryi);
214                 } else {
ragge
1.93
215                         BITCLEAR(warnaryi);
plunky
1.99
216                 }
217
ragge
1.93
218                 return;
219         }
plunky
1.99
220
ragge
1.93
221         fprintf(stderr"unrecognised warning option '%s'\n"str);
222 }
223
224 /*
225  * Deal with gcc warnings.
226  */
227 void
228 warner(int type, ...)
229 {
230         va_list ap;
231         char *w;
ragge
1.103
232         extern int issyshdr;
233
234         if (issyshdr && type == Wtruncate)
235                 return/* Too many false positives */
ragge
1.93
236
237         if (TESTBIT(warnarytype) == 0)
238                 return/* no warning */
239         if (TESTBIT(werrarytype)) {
240                 w = "error";
241                 incerr();
242         } else
243                 w = "warning";
244
245         va_start(aptype);
246         fprintf(stderr"%s:%d: %s: "ftitlelinenow);
247         vfprintf(stderrwarntxt[type], ap);
248         fprintf(stderr"\n");
249         va_end(ap);
250 }
251 #endif /* MKEXT */
252
253 #ifndef MKEXT
ragge
1.22
254 static NODE *freelink;
ragge
1.101
255 int usednodes;
ragge
1.22
256
ragge
1.77
257 #ifndef LANG_F77
ragge
1.1
258 NODE *
plunky
1.102
259 talloc(void)
ragge
1.2
260 {
ragge
1.24
261         register NODE *p;
262
ragge
1.63
263         usednodes++;
ragge
1.1
264
ragge
1.22
265         if (freelink != NULL) {
266                 p = freelink;
267                 freelink = p->next;
268                 if (p->n_op != FREE)
ragge
1.23
269                         cerror("node not FREE: %p"p);
plunky
1.100
270                 if (ndebug)
ragge
1.23
271                         printf("alloc node %p from freelist\n"p);
ragge
1.22
272                 return p;
273         }
274
ragge
1.24
275         p = permalloc(sizeof(NODE));
276         p->n_op = FREE;
plunky
1.100
277         if (ndebug)
ragge
1.24
278                 printf("alloc node %p from memory\n"p);
279         return p;
ragge
1.2
280 }
ragge
1.77
281 #endif
ragge
1.47
282
283 /*
284  * make a fresh copy of p
285  */
286 NODE *
287 tcopy(NODE *p)
288 {
289         NODE *q;
290
291         q = talloc();
292         *q = *p;
293
294         switch (optype(q->n_op)) {
295         case BITYPE:
296                 q->n_right = tcopy(p->n_right);
297         case UTYPE:
298                 q->n_left = tcopy(p->n_left);
299         }
300
301         return(q);
302 }
303
ragge
1.77
304 #ifndef LANG_F77
ragge
1.2
305 /*
306  * ensure that all nodes have been freed
307  */
308 void
plunky
1.102
309 tcheck(void)
ragge
1.2
310 {
ragge
1.24
311         extern int inlnodecnt;
ragge
1.1
312
ragge
1.24
313         if (nerrors)
314                 return;
315
316         if ((usednodes - inlnodecnt) != 0)
317                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
318 }
ragge
1.77
319 #endif
ragge
1.1
320
ragge
1.2
321 /*
322  * free the tree p
323  */
324 void
325 tfree(NODE *p)
326 {
ragge
1.12
327         if (p->n_op != FREE)
ragge
1.83
328                 walkf(p, (void (*)(NODE *, void *))nfree0);
ragge
1.2
329 }
ragge
1.1
330
ragge
1.51
331 /*
332  * Free a node, and return its left descendant.
333  * It is up to the caller to know whether the return value is usable.
334  */
335 NODE *
ragge
1.22
336 nfree(NODE *p)
ragge
1.2
337 {
ragge
1.51
338         NODE *l;
ragge
1.38
339 #ifdef PCC_DEBUG_NODES
ragge
1.31
340         NODE *q;
ragge
1.36
341 #endif
ragge
1.22
342
ragge
1.51
343         if (p == NULL)
344                 cerror("freeing blank node!");
345                 
346         l = p->n_left;
347         if (p->n_op == FREE)
348                 cerror("freeing FREE node"p);
ragge
1.38
349 #ifdef PCC_DEBUG_NODES
ragge
1.51
350         q = freelink;
351         while (q != NULL) {
352                 if (q == p)
353                         cerror("freeing free node %p"p);
354                 q = q->next;
355         }
ragge
1.36
356 #endif
ragge
1.22
357
plunky
1.100
358         if (ndebug)
ragge
1.51
359                 printf("freeing node %p\n"p);
360         p->n_op = FREE;
361         p->next = freelink;
362         freelink = p;
363         usednodes--;
364         return l;
ragge
1.2
365 }
ragge
1.37
366 #endif
367
ragge
1.77
368 #ifdef LANG_F77
369 #define OPTYPE(x) optype(x)
370 #else
371 #define OPTYPE(x) coptype(x)
372 #endif
373
ragge
1.37
374 #ifdef MKEXT
375 #define coptype(o)      (dope[o]&TYFLG)
376 #else
ragge
1.34
377 int cdope(int);
ragge
1.37
378 #define coptype(o)      (cdope(o)&TYFLG)
379 #endif
ragge
1.34
380
ragge
1.2
381 void
ragge
1.60
382 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
383 {
ragge
1.1
384
385         int down1down2;
386
387         more:
388         down1 = down2 = 0;
389
ragge
1.2
390         (*f)(tdown, &down1, &down2);
ragge
1.1
391
ragge
1.77
392         switch (OPTYPEt->n_op )) {
ragge
1.1
393
394         case BITYPE:
ragge
1.12
395                 fwalkt->n_leftfdown1 );
396                 t = t->n_right;
ragge
1.1
397                 down = down2;
398                 goto more;
399
400         case UTYPE:
ragge
1.12
401                 t = t->n_left;
ragge
1.1
402                 down = down1;
403                 goto more;
404
405         }
ragge
1.2
406 }
ragge
1.1
407
ragge
1.2
408 void
ragge
1.83
409 walkf(NODE *tvoid (*f)(NODE *, void *), void *arg)
ragge
1.2
410 {
411         int opty;
ragge
1.1
412
ragge
1.77
413
414         opty = OPTYPE(t->n_op);
ragge
1.1
415
ragge
1.2
416         if (opty != LTYPE)
ragge
1.83
417                 walkft->n_leftfarg );
ragge
1.2
418         if (opty == BITYPE)
ragge
1.83
419                 walkft->n_rightfarg );
420         (*f)(targ);
ragge
1.2
421 }
ragge
1.1
422
ragge
1.11
423 int dope[DSIZE];
ragge
1.1
424 char *opst[DSIZE];
425
ragge
1.2
426 struct dopest {
427         int dopeop;
428         char opst[8];
429         int dopeval;
430 indope[] = {
431         { NAME"NAME"LTYPE, },
432         { REG"REG"LTYPE, },
433         { OREG"OREG"LTYPE, },
ragge
1.52
434         { TEMP"TEMP"LTYPE, },
ragge
1.2
435         { ICON"ICON"LTYPE, },
436         { FCON"FCON"LTYPE, },
437         { CCODES"CCODES"LTYPE, },
ragge
1.41
438         { UMINUS"U-"UTYPE, },
439         { UMUL"U*"UTYPE, },
ragge
1.44
440         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
441         { UCALL"UCALL"UTYPE|CALLFLG, },
442         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
443         { COMPL"~"UTYPE, },
444         { FORCE"FORCE"UTYPE, },
ragge
1.75
445         { XARG"XARG"UTYPE, },
446         { XASM"XASM"BITYPE, },
ragge
1.2
447         { SCONV"SCONV"UTYPE, },
448         { PCONV"PCONV"UTYPE, },
449         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
450         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
451         { MUL"*"BITYPE|FLOFLG|MULFLG, },
452         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
453         { CM","BITYPE, },
454         { ASSIGN"="BITYPE|ASGFLG, },
455         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
456         { MOD"%"BITYPE|DIVFLG, },
457         { LS"<<"BITYPE|SHFFLG, },
458         { RS">>"BITYPE|SHFFLG, },
459         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
460         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
461         { STREF"->"BITYPE, },
462         { CALL"CALL"BITYPE|CALLFLG, },
463         { FORTCALL"FCALL"BITYPE|CALLFLG, },
464         { EQ"=="BITYPE|LOGFLG, },
465         { NE"!="BITYPE|LOGFLG, },
466         { LE"<="BITYPE|LOGFLG, },
467         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
468         { GE">="BITYPE|LOGFLG, },
ragge
1.2
469         { GT">"BITYPE|LOGFLG, },
470         { UGT"UGT"BITYPE|LOGFLG, },
471         { UGE"UGE"BITYPE|LOGFLG, },
472         { ULT"ULT"BITYPE|LOGFLG, },
473         { ULE"ULE"BITYPE|LOGFLG, },
474         { CBRANCH"CBRANCH"BITYPE, },
475         { FLD"FLD"UTYPE, },
476         { PMCONV"PMCONV"BITYPE, },
477         { PVCONV"PVCONV"BITYPE, },
478         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
479         { GOTO"GOTO"UTYPE, },
480         { STASG"STASG"BITYPE|ASGFLG, },
481         { STARG"STARG"UTYPE, },
482         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
483         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
484         { ADDROF"U&"UTYPE, },
ragge
1.1
485
ragge
1.2
486         { -1,   "",     0 },
ragge
1.1
487 };
488
ragge
1.2
489 void
plunky
1.102
490 mkdope(void)
ragge
1.2
491 {
492         struct dopest *q;
ragge
1.1
493
494         forq = indopeq->dopeop >= 0; ++q ){
495                 dope[q->dopeop] = q->dopeval;
496                 opst[q->dopeop] = q->opst;
497         }
ragge
1.2
498 }
499
500 /*
501  * output a nice description of the type of t
502  */
503 void
plunky
1.108
504 tprint(TWORD tTWORD q)
ragge
1.2
505 {
ragge
1.1
506         static char * tnames[] = {
507                 "undef",
ragge
1.95
508                 "bool",
ragge
1.1
509                 "char",
ragge
1.29
510                 "uchar",
ragge
1.1
511                 "short",
ragge
1.29
512                 "ushort",
ragge
1.1
513                 "int",
ragge
1.29
514                 "unsigned",
ragge
1.1
515                 "long",
ragge
1.29
516                 "ulong",
ragge
1.9
517                 "longlong",
ragge
1.29
518                 "ulonglong",
ragge
1.1
519                 "float",
520                 "double",
ragge
1.29
521                 "ldouble",
ragge
1.1
522                 "strty",
523                 "unionty",
524                 "enumty",
525                 "moety",
ragge
1.29
526                 "void",
ragge
1.66
527                 "signed"/* pass1 */
ragge
1.95
528                 "farg"/* pass1 */
ragge
1.90
529                 "fimag"/* pass1 */
530                 "dimag"/* pass1 */
531                 "limag"/* pass1 */
ragge
1.80
532                 "fcomplex"/* pass1 */
533                 "dcomplex"/* pass1 */
534                 "lcomplex"/* pass1 */
ragge
1.88
535                 "enumty"/* pass1 */
ragge
1.1
536                 "?""?"
537                 };
538
ragge
1.35
539         for(;; t = DECREF(t), q = DECREF(q)) {
540                 if (ISCON(q))
plunky
1.108
541                         putchar('C');
ragge
1.35
542                 if (ISVOL(q))
plunky
1.108
543                         putchar('V');
ragge
1.1
544
ragge
1.2
545                 if (ISPTR(t))
plunky
1.108
546                         printf("PTR ");
ragge
1.2
547                 else if (ISFTN(t))
plunky
1.108
548                         printf("FTN ");
ragge
1.2
549                 else if (ISARY(t))
plunky
1.108
550                         printf("ARY ");
ragge
1.1
551                 else {
plunky
1.108
552                         printf("%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
553                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
554                         return;
555                 }
556         }
ragge
1.2
557 }
ragge
1.13
558
ragge
1.14
559 /*
ragge
1.13
560  * Memory allocation routines.
561  * Memory are allocated from the system in MEMCHUNKSZ blocks.
562  * permalloc() returns a bunch of memory that is never freed.
563  * Memory allocated through tmpalloc() will be released the
564  * next time a function is ended (via tmpfree()).
565  */
566
567 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.85
568 struct balloc {
ragge
1.67
569         char a1;
570         union {
571                 long long l;
572                 long double d;
573         } a2;
574 };
575
plunky
1.98
576 #define ALIGNMENT offsetof(struct balloc, a2)
ragge
1.72
577 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
ragge
1.13
578
579 static char *allocpole;
plunky
1.107
580 static size_t allocleft;
581 size_t permallocsizetmpallocsizelostmem;
ragge
1.13
582
583 void *
plunky
1.107
584 permalloc(size_t size)
ragge
1.13
585 {
586         void *rv;
587
ragge
1.85
588         if (size > MEMCHUNKSZ) {
589                 if ((rv = malloc(size)) == NULL)
590                         cerror("permalloc: missing %d bytes"size);
591                 return rv;
592         }
plunky
1.107
593         if (size == 0)
ragge
1.20
594                 cerror("permalloc2");
ragge
1.18
595         if (allocleft < size) {
plunky
1.94
596                 /* loses unused bytes */
ragge
1.18
597                 lostmem += allocleft;
ragge
1.13
598                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
599                         cerror("permalloc: out of memory");
600                 allocleft = MEMCHUNKSZ;
601         }
ragge
1.16
602         size = ROUNDUP(size);
ragge
1.13
603         rv = &allocpole[MEMCHUNKSZ-allocleft];
604         allocleft -= size;
ragge
1.17
605         permallocsize += size;
ragge
1.13
606         return rv;
607 }
608
609 void *
plunky
1.107
610 tmpcalloc(size_t size)
pj
1.54
611 {
612         void *rv;
613
614         rv = tmpalloc(size);
615         memset(rv0size);
616         return rv;
617 }
618
ragge
1.85
619 /*
620  * Duplicate a string onto the temporary heap.
621  */
622 char *
623 tmpstrdup(char *str)
624 {
plunky
1.107
625         size_t len;
ragge
1.85
626
627         len = strlen(str) + 1;
628         return memcpy(tmpalloc(len), strlen);
629 }
630
631 /*
632  * Allocation routines for temporary memory.
633  */
634 #if 0
635 #define ALLDEBUG(x)     printf x
636 #else
637 #define ALLDEBUG(x)
638 #endif
639
640 #define NELEM   ((MEMCHUNKSZ-ROUNDUP(sizeof(struct xalloc *)))/ALIGNMENT)
641 #define ELEMSZ  (ALIGNMENT)
642 #define MAXSZ   (NELEM*ELEMSZ)
643 struct xalloc {
644         struct xalloc *next;
645         union {
646                 struct balloc b/* for initial alignment */
647                 char elm[MAXSZ];
648         } u;
649 } *tapole, *tmpole;
650 int uselem = NELEM/* next unused element */
651
pj
1.54
652 void *
plunky
1.107
653 tmpalloc(size_t size)
ragge
1.13
654 {
ragge
1.85
655         struct xalloc *xp;
ragge
1.17
656         void *rv;
ragge
1.85
657         size_t nelem;
ragge
1.17
658
ragge
1.85
659         nelem = ROUNDUP(size)/ELEMSZ;
plunky
1.107
660         ALLDEBUG(("tmpalloc(%ld,%ld) %zd (%zd) "ELEMSZNELEMsizenelem));
ragge
1.85
661         if (nelem > NELEM/2) {
plunky
1.107
662                 size += ROUNDUP(sizeof(struct xalloc *));
663                 if ((xp = malloc(size)) == NULL)
ragge
1.85
664                         cerror("out of memory");
plunky
1.107
665                 ALLDEBUG(("XMEM! (%zd,%p) "sizexp));
ragge
1.85
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 *
plunky
1.107
747 newstring(char *ssize_t len)
ragge
1.16
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];
plunky
1.105
756                 allocleft -= ROUNDUP(len);
plunky
1.106
757                 permallocsize += ROUNDUP(len);
ragge
1.16
758         }
759         while (len--)
760                 *c++ = *s++;
761         return u;
ragge
1.13
762 }
ragge
1.80
763
764 /*
765  * Do a preorder walk of the CM list p and apply function f on each element.
766  */
767 void
768 flist(NODE *pvoid (*f)(NODE *, void *), void *arg)
769 {
770         if (p->n_op == CM) {
771                 (*f)(p->n_rightarg);
772                 flist(p->n_leftfarg);
773         } else
774                 (*f)(parg);
775 }
776
777 /*
778  * The same as flist but postorder.
779  */
780 void
781 listf(NODE *pvoid (*f)(NODE *))
782 {
783         if (p->n_op == CM) {
784                 listf(p->n_leftf);
785                 (*f)(p->n_right);
786         } else
787                 (*f)(p);
788 }
789
790 /*
791  * Get list argument number n from list, or NIL if out of list.
792  */
793 NODE *
794 listarg(NODE *pint nint *cnt)
795 {
796         NODE *r;
797
798         if (p->n_op == CM) {
799                 r = listarg(p->n_leftncnt);
800                 if (n == ++(*cnt))
801                         r = p->n_right;
802         } else {
803                 *cnt = 0;
804                 r = n == 0 ? p : NIL;
805         }
806         return r;
807 }
ragge
1.95
808
809 /*
810  * Make a type unsigned, if possible.
811  */
812 TWORD
813 enunsign(TWORD t)
814 {
815         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
816                 t |= 1;
817         return t;
818 }
819
820 /*
821  * Make a type signed, if possible.
822  */
823 TWORD
824 deunsign(TWORD t)
825 {
826         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
827                 t &= ~1;
828         return t;
829 }
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-29 11:58 +0100