00001 #include <assert.h>
00002 #include <stdarg.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <limits.h>
00006 #include <string.h>
00007
00008 #define NEW(p,a) ((p) = allocate(sizeof *(p), (a)))
00009 #define NEW0(p,a) memset(NEW((p),(a)), 0, sizeof *(p))
00010 #define isaddrop(op) (specific(op)==ADDRG+P || specific(op)==ADDRL+P \
00011 || specific(op)==ADDRF+P)
00012
00013 #define MAXLINE 512
00014 #define BUFSIZE 4096
00015
00016 #define istypename(t,tsym) (kind[t] == CHAR \
00017 || t == ID && tsym && tsym->sclass == TYPEDEF)
00018 #define sizeop(n) ((n)<<10)
00019 #define generic(op) ((op)&0x3F0)
00020 #define specific(op) ((op)&0x3FF)
00021 #define opindex(op) (((op)>>4)&0x3F)
00022 #define opkind(op) ((op)&~0x3F0)
00023 #define opsize(op) ((op)>>10)
00024 #define optype(op) ((op)&0xF)
00025 #ifdef __LCC__
00026 #ifndef __STDC__
00027 #define __STDC__
00028 #endif
00029 #endif
00030 #define NELEMS(a) ((int)(sizeof (a)/sizeof ((a)[0])))
00031 #undef roundup
00032 #define roundup(x,n) (((x)+((n)-1))&(~((n)-1)))
00033 #define mkop(op,ty) (specific((op) + ttob(ty)))
00034
00035 #define extend(x,ty) ((x)&(1<<(8*(ty)->size-1)) ? (x)|((~0UL)<<(8*(ty)->size-1)) : (x)&ones(8*(ty)->size))
00036 #define ones(n) ((n)>=8*sizeof (unsigned long) ? ~0UL : ~((~0UL)<<(n)))
00037
00038 #define isqual(t) ((t)->op >= CONST)
00039 #define unqual(t) (isqual(t) ? (t)->type : (t))
00040
00041 #define isvolatile(t) ((t)->op == VOLATILE \
00042 || (t)->op == CONST+VOLATILE)
00043 #define isconst(t) ((t)->op == CONST \
00044 || (t)->op == CONST+VOLATILE)
00045 #define isarray(t) (unqual(t)->op == ARRAY)
00046 #define isstruct(t) (unqual(t)->op == STRUCT \
00047 || unqual(t)->op == UNION)
00048 #define isunion(t) (unqual(t)->op == UNION)
00049 #define isfunc(t) (unqual(t)->op == FUNCTION)
00050 #define isptr(t) (unqual(t)->op == POINTER)
00051 #define ischar(t) ((t)->size == 1 && isint(t))
00052 #define isint(t) (unqual(t)->op == INT \
00053 || unqual(t)->op == UNSIGNED)
00054 #define isfloat(t) (unqual(t)->op == FLOAT)
00055 #define isarith(t) (unqual(t)->op <= UNSIGNED)
00056 #define isunsigned(t) (unqual(t)->op == UNSIGNED)
00057 #define isscalar(t) (unqual(t)->op <= POINTER \
00058 || unqual(t)->op == ENUM)
00059 #define isenum(t) (unqual(t)->op == ENUM)
00060 #define fieldsize(p) (p)->bitsize
00061 #define fieldright(p) ((p)->lsb - 1)
00062 #define fieldleft(p) (8*(p)->type->size - \
00063 fieldsize(p) - fieldright(p))
00064 #define fieldmask(p) (~(~(unsigned)0<<fieldsize(p)))
00065 typedef struct node *Node;
00066
00067 typedef struct list *List;
00068
00069 typedef struct code *Code;
00070
00071 typedef struct swtch *Swtch;
00072
00073 typedef struct symbol *Symbol;
00074
00075 typedef struct coord {
00076 char *file;
00077 unsigned x, y;
00078 } Coordinate;
00079 typedef struct table *Table;
00080
00081 typedef union value {
00082 long i;
00083 unsigned long u;
00084 long double d;
00085 void *p;
00086 void (*g)(void);
00087 } Value;
00088 typedef struct tree *Tree;
00089
00090 typedef struct type *Type;
00091
00092 typedef struct field *Field;
00093
00094 typedef struct {
00095 unsigned printed:1;
00096 unsigned marked;
00097 unsigned short typeno;
00098 void *xt;
00099 } Xtype;
00100
00101 #include "config.h"
00102 typedef struct metrics {
00103 unsigned char size, align, outofline;
00104 } Metrics;
00105 typedef struct interface {
00106 Metrics charmetric;
00107 Metrics shortmetric;
00108 Metrics intmetric;
00109 Metrics longmetric;
00110 Metrics longlongmetric;
00111 Metrics floatmetric;
00112 Metrics doublemetric;
00113 Metrics longdoublemetric;
00114 Metrics ptrmetric;
00115 Metrics structmetric;
00116 unsigned little_endian:1;
00117 unsigned mulops_calls:1;
00118 unsigned wants_callb:1;
00119 unsigned wants_argb:1;
00120 unsigned left_to_right:1;
00121 unsigned wants_dag:1;
00122 unsigned unsigned_char:1;
00123 void (*address)(Symbol p, Symbol q, long n);
00124 void (*blockbeg)(Env *);
00125 void (*blockend)(Env *);
00126 void (*defaddress)(Symbol);
00127 void (*defconst) (int suffix, int size, Value v);
00128 void (*defstring)(int n, char *s);
00129 void (*defsymbol)(Symbol);
00130 void (*emit) (Node);
00131 void (*export)(Symbol);
00132 void (*function)(Symbol, Symbol[], Symbol[], int);
00133 Node (*gen) (Node);
00134 void (*global)(Symbol);
00135 void (*import)(Symbol);
00136 void (*local)(Symbol);
00137 void (*progbeg)(int argc, char *argv[]);
00138 void (*progend)(void);
00139 void (*segment)(int);
00140 void (*space)(int);
00141 void (*stabblock)(int, int, Symbol*);
00142 void (*stabend) (Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *);
00143 void (*stabfend) (Symbol, int);
00144 void (*stabinit) (char *, int, char *[]);
00145 void (*stabline) (Coordinate *);
00146 void (*stabsym) (Symbol);
00147 void (*stabtype) (Symbol);
00148 Xinterface x;
00149 } Interface;
00150 typedef struct binding {
00151 char *name;
00152 Interface *ir;
00153 } Binding;
00154
00155 extern Binding bindings[];
00156 extern Interface *IR;
00157 typedef struct {
00158 List blockentry;
00159 List blockexit;
00160 List entry;
00161 List exit;
00162 List returns;
00163 List points;
00164 List calls;
00165 List end;
00166 } Events;
00167
00168 enum {
00169 #define xx(a,b,c,d,e,f,g) a=b,
00170 #define yy(a,b,c,d,e,f,g)
00171 #include "token.h"
00172 LAST
00173 };
00174 struct node {
00175 short op;
00176 short count;
00177 Symbol syms[3];
00178 Node kids[2];
00179 Node link;
00180 Xnode x;
00181 };
00182 enum {
00183 F=FLOAT,
00184 I=INT,
00185 U=UNSIGNED,
00186 P=POINTER,
00187 V=VOID,
00188 B=STRUCT
00189 };
00190 #define gop(name,value) name=value<<4,
00191 #define op(name,type,sizes)
00192
00193 enum { gop(CNST,1)
00194 op(CNST,F,fdx)
00195 op(CNST,I,csilh)
00196 op(CNST,P,p)
00197 op(CNST,U,csilh)
00198 gop(ARG,2)
00199 op(ARG,B,-)
00200 op(ARG,F,fdx)
00201 op(ARG,I,ilh)
00202 op(ARG,P,p)
00203 op(ARG,U,ilh)
00204 gop(ASGN,3)
00205 op(ASGN,B,-)
00206 op(ASGN,F,fdx)
00207 op(ASGN,I,csilh)
00208 op(ASGN,P,p)
00209 op(ASGN,U,csilh)
00210 gop(INDIR,4)
00211 op(INDIR,B,-)
00212 op(INDIR,F,fdx)
00213 op(INDIR,I,csilh)
00214 op(INDIR,P,p)
00215 op(INDIR,U,csilh)
00216 gop(CVF,7)
00217 op(CVF,F,fdx)
00218 op(CVF,I,ilh)
00219 gop(CVI,8)
00220 op(CVI,F,fdx)
00221 op(CVI,I,csilh)
00222 op(CVI,U,csilhp)
00223 gop(CVP,9)
00224 op(CVP,U,p)
00225 gop(CVU,11)
00226 op(CVU,I,csilh)
00227 op(CVU,P,p)
00228 op(CVU,U,csilh)
00229 gop(NEG,12)
00230 op(NEG,F,fdx)
00231 op(NEG,I,ilh)
00232 gop(CALL,13)
00233 op(CALL,B,-)
00234 op(CALL,F,fdx)
00235 op(CALL,I,ilh)
00236 op(CALL,P,p)
00237 op(CALL,U,ilh)
00238 op(CALL,V,-)
00239 gop(RET,15)
00240 op(RET,F,fdx)
00241 op(RET,I,ilh)
00242 op(RET,P,p)
00243 op(RET,U,ilh)
00244 op(RET,V,-)
00245 gop(ADDRG,16)
00246 op(ADDRG,P,p)
00247 gop(ADDRF,17)
00248 op(ADDRF,P,p)
00249 gop(ADDRL,18)
00250 op(ADDRL,P,p)
00251 gop(ADD,19)
00252 op(ADD,F,fdx)
00253 op(ADD,I,ilh)
00254 op(ADD,P,p)
00255 op(ADD,U,ilhp)
00256 gop(SUB,20)
00257 op(SUB,F,fdx)
00258 op(SUB,I,ilh)
00259 op(SUB,P,p)
00260 op(SUB,U,ilhp)
00261 gop(LSH,21)
00262 op(LSH,I,ilh)
00263 op(LSH,U,ilh)
00264 gop(MOD,22)
00265 op(MOD,I,ilh)
00266 op(MOD,U,ilh)
00267 gop(RSH,23)
00268 op(RSH,I,ilh)
00269 op(RSH,U,ilh)
00270 gop(BAND,24)
00271 op(BAND,I,ilh)
00272 op(BAND,U,ilh)
00273 gop(BCOM,25)
00274 op(BCOM,I,ilh)
00275 op(BCOM,U,ilh)
00276 gop(BOR,26)
00277 op(BOR,I,ilh)
00278 op(BOR,U,ilh)
00279 gop(BXOR,27)
00280 op(BXOR,I,ilh)
00281 op(BXOR,U,ilh)
00282 gop(DIV,28)
00283 op(DIV,F,fdx)
00284 op(DIV,I,ilh)
00285 op(DIV,U,ilh)
00286 gop(MUL,29)
00287 op(MUL,F,fdx)
00288 op(MUL,I,ilh)
00289 op(MUL,U,ilh)
00290 gop(EQ,30)
00291 op(EQ,F,fdx)
00292 op(EQ,I,ilh)
00293 op(EQ,U,ilhp)
00294 gop(GE,31)
00295 op(GE,F,fdx)
00296 op(GE,I,ilh)
00297 op(GE,U,ilhp)
00298 gop(GT,32)
00299 op(GT,F,fdx)
00300 op(GT,I,ilh)
00301 op(GT,U,ilhp)
00302 gop(LE,33)
00303 op(LE,F,fdx)
00304 op(LE,I,ilh)
00305 op(LE,U,ilhp)
00306 gop(LT,34)
00307 op(LT,F,fdx)
00308 op(LT,I,ilh)
00309 op(LT,U,ilhp)
00310 gop(NE,35)
00311 op(NE,F,fdx)
00312 op(NE,I,ilh)
00313 op(NE,U,ilhp)
00314 gop(JUMP,36)
00315 op(JUMP,V,-)
00316 gop(LABEL,37)
00317 op(LABEL,V,-)
00318 gop(LOAD,14)
00319 op(LOAD,B,-)
00320 op(LOAD,F,fdx)
00321 op(LOAD,I,csilh)
00322 op(LOAD,P,p)
00323 op(LOAD,U,csilhp) LASTOP };
00324
00325 #undef gop
00326 #undef op
00327 enum { CODE=1, BSS, DATA, LIT };
00328 enum { PERM=0, FUNC, STMT };
00329 struct list {
00330 void *x;
00331 List link;
00332 };
00333
00334 struct code {
00335 enum { Blockbeg, Blockend, Local, Address, Defpoint,
00336 Label, Start, Gen, Jump, Switch
00337 } kind;
00338 Code prev, next;
00339 union {
00340 struct {
00341 int level;
00342 Symbol *locals;
00343 Table identifiers, types;
00344 Env x;
00345 } block;
00346 Code begin;
00347 Symbol var;
00348
00349 struct {
00350 Symbol sym;
00351 Symbol base;
00352 long offset;
00353 } addr;
00354 struct {
00355 Coordinate src;
00356 int point;
00357 } point;
00358 Node forest;
00359 struct {
00360 Symbol sym;
00361 Symbol table;
00362 Symbol deflab;
00363 int size;
00364 long *values;
00365 Symbol *labels;
00366 } swtch;
00367
00368 } u;
00369 };
00370 struct swtch {
00371 Symbol sym;
00372 int lab;
00373 Symbol deflab;
00374 int ncases;
00375 int size;
00376 long *values;
00377 Symbol *labels;
00378 };
00379 struct symbol {
00380 char *name;
00381 int scope;
00382 Coordinate src;
00383 Symbol up;
00384 List uses;
00385 int sclass;
00386 unsigned structarg:1;
00387
00388 unsigned addressed:1;
00389 unsigned computed:1;
00390 unsigned temporary:1;
00391 unsigned generated:1;
00392 unsigned defined:1;
00393 Type type;
00394 float ref;
00395 union {
00396 struct {
00397 int label;
00398 Symbol equatedto;
00399 } l;
00400 struct {
00401 unsigned cfields:1;
00402 unsigned vfields:1;
00403 Table ftab;
00404 Field flist;
00405 } s;
00406 int value;
00407 Symbol *idlist;
00408 struct {
00409 Value min, max;
00410 } limits;
00411 struct {
00412 Value v;
00413 Symbol loc;
00414 } c;
00415 struct {
00416 Coordinate pt;
00417 int label;
00418 int ncalls;
00419 Symbol *callee;
00420 } f;
00421 int seg;
00422 Symbol alias;
00423 struct {
00424 Node cse;
00425 int replace;
00426 Symbol next;
00427 } t;
00428 } u;
00429 Xsymbol x;
00430 };
00431 enum { CONSTANTS=1, LABELS, GLOBAL, PARAM, LOCAL };
00432 struct tree {
00433 int op;
00434 Type type;
00435 Tree kids[2];
00436 Node node;
00437 union {
00438 Value v;
00439 Symbol sym;
00440
00441 Field field;
00442 } u;
00443 };
00444 enum {
00445 AND=38<<4,
00446 NOT=39<<4,
00447 OR=40<<4,
00448 COND=41<<4,
00449 RIGHT=42<<4,
00450 FIELD=43<<4
00451 };
00452 struct type {
00453 int op;
00454 Type type;
00455 int align;
00456 int size;
00457 union {
00458 Symbol sym;
00459 struct {
00460 unsigned oldstyle:1;
00461 Type *proto;
00462 } f;
00463 } u;
00464 Xtype x;
00465 };
00466 struct field {
00467 char *name;
00468 Type type;
00469 int offset;
00470 short bitsize;
00471 short lsb;
00472 Field link;
00473 };
00474 extern int assignargs;
00475 extern int prunetemps;
00476 extern int nodecount;
00477 extern Symbol cfunc;
00478 extern Symbol retv;
00479 extern Tree (*optree[])(int, Tree, Tree);
00480
00481 extern char kind[];
00482 extern int errcnt;
00483 extern int errlimit;
00484 extern int wflag;
00485 extern Events events;
00486 extern float refinc;
00487
00488 extern unsigned char *cp;
00489 extern unsigned char *limit;
00490 extern char *firstfile;
00491 extern char *file;
00492 extern char *line;
00493 extern int lineno;
00494 extern int t;
00495 extern char *token;
00496 extern Symbol tsym;
00497 extern Coordinate src;
00498 extern int Aflag;
00499 extern int Pflag;
00500 extern Symbol YYnull;
00501 extern Symbol YYcheck;
00502 extern int glevel;
00503 extern int xref;
00504
00505 extern int ncalled;
00506 extern int npoints;
00507
00508 extern int needconst;
00509 extern int explicitCast;
00510 extern struct code codehead;
00511 extern Code codelist;
00512 extern Table stmtlabs;
00513 extern float density;
00514 extern Table constants;
00515 extern Table externals;
00516 extern Table globals;
00517 extern Table identifiers;
00518 extern Table labels;
00519 extern Table types;
00520 extern int level;
00521
00522 extern List loci, symbols;
00523
00524 extern List symbols;
00525
00526 extern int where;
00527 extern Type chartype;
00528 extern Type doubletype;
00529 extern Type floattype;
00530 extern Type inttype;
00531 extern Type longdouble;
00532 extern Type longtype;
00533 extern Type longlong;
00534 extern Type shorttype;
00535 extern Type signedchar;
00536 extern Type unsignedchar;
00537 extern Type unsignedlonglong;
00538 extern Type unsignedlong;
00539 extern Type unsignedshort;
00540 extern Type unsignedtype;
00541 extern Type charptype;
00542 extern Type funcptype;
00543 extern Type voidptype;
00544 extern Type voidtype;
00545 extern Type unsignedptr;
00546 extern Type signedptr;
00547 extern Type widechar;
00548 extern void *allocate(unsigned long n, unsigned a);
00549 extern void deallocate(unsigned a);
00550 extern void *newarray(unsigned long m, unsigned long n, unsigned a);
00551 extern void walk(Tree e, int tlab, int flab);
00552 extern Node listnodes(Tree e, int tlab, int flab);
00553 extern Node newnode(int op, Node left, Node right, Symbol p);
00554 extern Tree cvtconst(Tree);
00555 extern void printdag(Node, int);
00556 extern void compound(int, Swtch, int);
00557 extern void defglobal(Symbol, int);
00558 extern void finalize(void);
00559 extern void program(void);
00560
00561 extern Tree vcall(Symbol func, Type ty, ...);
00562 extern Tree addrof(Tree);
00563 extern Tree asgn(Symbol, Tree);
00564 extern Tree asgntree(int, Tree, Tree);
00565 extern Type assign(Type, Tree);
00566 extern Tree bittree(int, Tree, Tree);
00567 extern Tree call(Tree, Type, Coordinate);
00568 extern Tree calltree(Tree, Type, Tree, Symbol);
00569 extern Tree condtree(Tree, Tree, Tree);
00570 extern Tree cnsttree(Type, ...);
00571 extern Tree consttree(unsigned int, Type);
00572 extern Tree eqtree(int, Tree, Tree);
00573 extern int iscallb(Tree);
00574 extern Tree shtree(int, Tree, Tree);
00575 extern void typeerror(int, Tree, Tree);
00576
00577 extern void test(int tok, char set[]);
00578 extern void expect(int tok);
00579 extern void skipto(int tok, char set[]);
00580 extern void error(const char *, ...);
00581 extern int fatal(const char *, const char *, int);
00582 extern void warning(const char *, ...);
00583
00584 typedef void (*Apply)(void *, void *, void *);
00585 extern void attach(Apply, void *, List *);
00586 extern void apply(List event, void *arg1, void *arg2);
00587 extern Tree retype(Tree p, Type ty);
00588 extern Tree rightkid(Tree p);
00589 extern int hascall(Tree p);
00590 extern Type binary(Type, Type);
00591 extern Tree cast(Tree, Type);
00592 extern Tree cond(Tree);
00593 extern Tree expr0(int);
00594 extern Tree expr(int);
00595 extern Tree expr1(int);
00596 extern Tree field(Tree, const char *);
00597 extern char *funcname(Tree);
00598 extern Tree idtree(Symbol);
00599 extern Tree incr(int, Tree, Tree);
00600 extern Tree lvalue(Tree);
00601 extern Tree nullcall(Type, Symbol, Tree, Tree);
00602 extern Tree pointer(Tree);
00603 extern Tree rvalue(Tree);
00604 extern Tree value(Tree);
00605
00606 extern void defpointer(Symbol);
00607 extern Type initializer(Type, int);
00608 extern void swtoseg(int);
00609
00610 extern void input_init(int, char *[]);
00611 extern void fillbuf(void);
00612 extern void nextline(void);
00613
00614 extern int getchr(void);
00615 extern int gettok(void);
00616
00617 extern void emitcode(void);
00618 extern void gencode (Symbol[], Symbol[]);
00619 extern void fprint(FILE *f, const char *fmt, ...);
00620 extern char *stringf(const char *, ...);
00621 extern void check(Node);
00622 extern void print(const char *, ...);
00623
00624 extern List append(void *x, List list);
00625 extern int length(List list);
00626 extern void *ltov (List *list, unsigned a);
00627 extern void init(int, char *[]);
00628
00629 extern Type typename(void);
00630 extern void checklab(Symbol p, void *cl);
00631 extern Type enumdcl(void);
00632 extern void main_init(int, char *[]);
00633 extern int main(int, char *[]);
00634
00635 extern void vfprint(FILE *, char *, const char *, va_list);
00636
00637 extern int process(char *);
00638 extern int findfunc(char *, char *);
00639 extern int findcount(char *, int, int);
00640
00641 extern Tree constexpr(int);
00642 extern int intexpr(int, int);
00643 extern Tree simplify(int, Type, Tree, Tree);
00644 extern int ispow2(unsigned long u);
00645
00646 extern int reachable(int);
00647
00648 extern void addlocal(Symbol);
00649 extern void branch(int);
00650 extern Code code(int);
00651 extern void definelab(int);
00652 extern void definept(Coordinate *);
00653 extern void equatelab(Symbol, Symbol);
00654 extern Node jump(int);
00655 extern void retcode(Tree);
00656 extern void statement(int, Swtch, int);
00657 extern void swcode(Swtch, int *, int, int);
00658 extern void swgen(Swtch);
00659
00660 extern char * string(const char *str);
00661 extern char *stringn(const char *str, int len);
00662 extern char *stringd(long n);
00663 extern Symbol relocate(const char *name, Table src, Table dst);
00664 extern void use(Symbol p, Coordinate src);
00665 extern void locus(Table tp, Coordinate *cp);
00666 extern Symbol allsymbols(Table);
00667
00668 extern Symbol constant(Type, Value);
00669 extern void enterscope(void);
00670 extern void exitscope(void);
00671 extern Symbol findlabel(int);
00672 extern Symbol findtype(Type);
00673 extern void foreach(Table, int, void (*)(Symbol, void *), void *);
00674 extern Symbol genident(int, Type, int);
00675 extern int genlabel(int);
00676 extern Symbol install(const char *, Table *, int, int);
00677 extern Symbol intconst(int);
00678 extern Symbol lookup(const char *, Table);
00679 extern Symbol mkstr(char *);
00680 extern Symbol mksymbol(int, const char *, Type);
00681 extern Symbol newtemp(int, int, int);
00682 extern Table table(Table, int);
00683 extern Symbol temporary(int, Type);
00684 extern char *vtoa(Type, Value);
00685
00686 extern int nodeid(Tree);
00687 extern char *opname(int);
00688 extern int *printed(int);
00689 extern void printtree(Tree, int);
00690 extern Tree root(Tree);
00691 extern Tree texpr(Tree (*)(int), int, int);
00692 extern Tree tree(int, Type, Tree, Tree);
00693
00694 extern void type_init(int, char *[]);
00695
00696 extern Type signedint(Type);
00697
00698 extern int hasproto(Type);
00699 extern void outtype(Type, FILE *);
00700 extern void printdecl (Symbol p, Type ty);
00701 extern void printproto(Symbol p, Symbol args[]);
00702 extern char *typestring(Type ty, char *id);
00703 extern Field fieldref(const char *name, Type ty);
00704 extern Type array(Type, int, int);
00705 extern Type atop(Type);
00706 extern Type btot(int, int);
00707 extern Type compose(Type, Type);
00708 extern Type deref(Type);
00709 extern int eqtype(Type, Type, int);
00710 extern Field fieldlist(Type);
00711 extern Type freturn(Type);
00712 extern Type ftype(Type, Type);
00713 extern Type func(Type, Type *, int);
00714 extern Field newfield(char *, Type, Type);
00715 extern Type newstruct(int, char *);
00716 extern void printtype(Type, int);
00717 extern Type promote(Type);
00718 extern Type ptr(Type);
00719 extern Type qual(int, Type);
00720 extern void rmtypes(int);
00721 extern int ttob(Type);
00722 extern int variadic(Type);
00723