Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20140516130202

Diff

Diff from 1.109 to:

Annotations

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

Annotated File View

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