Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140606131903

Diff

Diff from 1.110 to:

Annotations

Annotate by Age | Author | Mixed | None
ragge (729) plunky (137) stefan (10) pj (10) gmcgarry (2) mickey (1)
/fisheye/browse/pcc/pcc/mip/common.c

Annotated File View

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