diff options
Diffstat (limited to 'lcc/src')
44 files changed, 0 insertions, 19274 deletions
diff --git a/lcc/src/2html.c b/lcc/src/2html.c deleted file mode 100644 index 8a0be3a..0000000 --- a/lcc/src/2html.c +++ /dev/null @@ -1,555 +0,0 @@ -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include "c.h" -#include "rcc.h" -#if WIN32 -#include <fcntl.h> -#include <io.h> -#endif - - -static void do_int(int x) { - printf("%d", x); -} - -static void do_scope(int x) { -#define xx(c) if (x == c) { printf(#c); return; } - xx(CONSTANTS) - xx(LABELS) - xx(GLOBAL) - xx(PARAM) - xx(LOCAL) -#undef xx - if (x > LOCAL) - printf("LOCAL+%d", x-LOCAL); - else - do_int(x); -} - -static void do_sclass(int x) { -#define xx(c) if (x == c) { printf(#c); return; } - xx(REGISTER) - xx(AUTO) - xx(EXTERN) - xx(STATIC) - xx(TYPEDEF) -#undef xx - do_int(x); -} - -static void do_flags(int x) { - char *bar = ""; -#define xx(f,n) if ((x>>n)&1) { printf("%s" #f, bar); bar = "|"; } - xx(structarg,0) - xx(addressed,1) - xx(computed,2) - xx(temporary,3) - xx(generated,4) -#undef xx - if (*bar == '\0') - do_int(x); -} - -static void do_seg(int x) { -#define xx(s) if (x == s) { printf(#s); return; } - xx(CODE) - xx(BSS) - xx(DATA) - xx(LIT) -#undef xx - do_int(x); -} - -#define xx(ptr,field,type) do { printf("<li>" #field " = "); do_##type(ptr->field); printf("</li>\n"); } while (0) - -static void do_op(int x) { - static char *opnames[] = { - "", - "CNST", - "ARG", - "ASGN", - "INDIR", - "CVC", - "CVD", - "CVF", - "CVI", - "CVP", - "CVS", - "CVU", - "NEG", - "CALL", - "*LOAD*", - "RET", - "ADDRG", - "ADDRF", - "ADDRL", - "ADD", - "SUB", - "LSH", - "MOD", - "RSH", - "BAND", - "BCOM", - "BOR", - "BXOR", - "DIV", - "MUL", - "EQ", - "GE", - "GT", - "LE", - "LT", - "NE", - "JUMP", - "LABEL", - "AND", - "NOT", - "OR", - "COND", - "RIGHT", - "FIELD" - }; - int op = opindex(x); - if (op < 1 || op >= sizeof opnames/sizeof opnames[0]) - printf("%d", x); - else - printf("%s", opnames[op]); -} - -static void do_define_uid(int x) { - printf("<strong id=uid%d>%d</strong>", x, x); -} - -static void do_define_label(int x) { - printf("<strong id=ll%d>%d</strong>", x, x); -} - -static void do_uid(int x) { - printf("<a href='#%d'>%d</a>", x, x, x); -} - -static void do_label(int x) { - printf("<a href='#L%d'>%d</a>", x, x, x); -} - -static int nextid; - -static void do_list(list_ty x, void do_one(void *), char *type, char *listhtml, char *separator) { - int count = Seq_length(x); - - if (count == 0) - printf("<em>empty %s list</em>\n", type); - else { - int i; - printf("<em>%s list</em>", type); - if (listhtml != NULL) - printf("<%s>\n", listhtml); - for (i = 0; i < count; i++) { - if (listhtml != NULL) - printf("<li>"); - printf(separator); - do_one(Seq_get(x, i)); - if (listhtml != NULL) - printf("</li>\n"); - } - if (listhtml != NULL) - printf("</%s>\n", listhtml); - } -} - -static void do_uid_list(list_ty x) { - int i, count = Seq_length(x); - - if (count == 0) - printf("<em>empty int list</em>\n"); - else { - int i; - printf("<em>int list</em>"); - for (i= 0; i < count; i++) { - printf(" "); - do_uid(*(int *)Seq_get(x, i)); - } - } -} - -static void do_identifier(const char *x) { - printf("%s", x); -} - -static void do_real(rcc_real_ty x) { - double d; - unsigned *p = (unsigned *)&d; - static union { int x; char endian; } little = { 1 }; - - p[1-little.endian] = x->msb; - p[little.endian] = x->lsb; - printf("(%#X,%#X) = %g", x->msb, x->lsb, d); -} - -static void do_suffix(int x) { - static char suffixes[] = "0F234IUPVB"; - - if (x < 0 || x >= (sizeof suffixes/sizeof suffixes[0]) - 1) - printf("%d", x); - else - printf("%c", suffixes[x]); -} - -static void do_enum(void *x) { - rcc_enum__ty e = x; - - do_identifier(e->id); - printf("="); - do_int(e->value); -} - -static void do_enum_list(list_ty x) { - do_list(x, do_enum, "enum", NULL, " "); -} - -static void do_field(void *x) { - rcc_field_ty f = x; - - printf("<em>field</em><ul>\n"); - xx(f,id,identifier); - xx(f,type,uid); - xx(f,offset,int); - xx(f,bitsize,int); - xx(f,lsb,int); - printf("</ul>\n"); -} - -static void do_field_list(list_ty x) { - do_list(x, do_field, "field", "ol", ""); -} - -static void do_symbol(rcc_symbol_ty x) { - printf("<em>symbol</em><ul>\n"); - xx(x,id,identifier); - xx(x,type,uid); - xx(x,scope,scope); - xx(x,sclass,sclass); - xx(x,ref,int); - xx(x,flags,flags); - printf("</ul>\n"); -} - -#define caselabel(kind) case rcc_##kind##_enum: \ - printf("<strong>" #kind "</strong> : <em>%s</em>", typename); \ - printf("<ul>\n"); attributes -#define yy(kind,field,type) xx((&x->v.rcc_##kind),field,type) - -static void do_type(rcc_type_ty x) { -#define attributes xx(x,size,int); xx(x,align,int) - switch (x->kind) { - static char *typename = "type"; - caselabel(INT); break; - caselabel(UNSIGNED); break; - caselabel(FLOAT); break; - caselabel(VOID); break; - caselabel(POINTER); - yy(POINTER,type,uid); - break; - caselabel(ENUM); - yy(ENUM,tag,identifier); - yy(ENUM,ids,enum_list); - break; - caselabel(STRUCT); - yy(STRUCT,tag,identifier); - yy(STRUCT,fields,field_list); - break; - caselabel(UNION); - yy(UNION,tag,identifier); - yy(UNION,fields,field_list); - break; - caselabel(ARRAY); - yy(ARRAY,type,uid); - break; - caselabel(FUNCTION); - yy(FUNCTION,type,uid); - yy(FUNCTION,formals,uid_list); - break; - caselabel(CONST); - yy(CONST,type,uid); - break; - caselabel(VOLATILE); - yy(VOLATILE,type,uid); - break; - default: assert(0); - } -#undef attributes - printf("</ul>\n"); -} - -static void do_item(rcc_item_ty x) { - printf("<a name='%d'>", x->uid); -#define attributes xx(x,uid,define_uid) - printf("</a>"); - switch (x->kind) { - static char *typename = "item"; - caselabel(Symbol); - yy(Symbol,symbol,symbol); - break; - caselabel(Type); - yy(Type,type,type); - break; - default: assert(0); - } -#undef attributes - printf("</ul>\n"); -} - -static void do_item_list(list_ty x) { - int count = Seq_length(x); - - if (count == 0) - printf("<em>empty item list</em>\n"); - else { - int i; - printf("<em>item list</em>"); - printf("<ol>\n"); - for (i = 0; i < count; i++) { - rcc_item_ty item = Seq_get(x, i); - printf("<li value=%d>", item->uid); - do_item(item); - printf("</li>\n"); - } - printf("</ol>\n"); - } -} - -static void do_string(string_ty x) { - printf("%d,<code>'%s'</code>", x.len, x.str); -} - -static void do_generic_string(void *x) { - do_string(*(string_ty *)x); -} - -static void do_string_list(list_ty x) { - do_list(x, do_generic_string, "string", "ol", ""); -} - -static void do_node(void *y) { - rcc_node_ty x = y; - - if (x->kind == rcc_LABEL_enum) - printf("<a name='L%d'></a>", x->v.rcc_LABEL.label); -#define attributes xx(x,suffix,suffix); xx(x,size,int) - switch (x->kind) { - static char *typename = "node"; - caselabel(CNST); - yy(CNST,value,int); - break; - caselabel(CNSTF); - yy(CNSTF,value,real); - break; - caselabel(ARG); - yy(ARG,left,node); - yy(ARG,len,int); - yy(ARG,align,int); - break; - caselabel(ASGN); - yy(ASGN,left,node); - yy(ASGN,right,node); - yy(ASGN,len,int); - yy(ASGN,align,int); - break; - caselabel(CVT); - yy(CVT,op,op); - yy(CVT,left,node); - yy(CVT,fromsize,int); - break; - caselabel(CALL); - yy(CALL,left,node); - yy(CALL,type,uid); - break; - caselabel(CALLB); - yy(CALLB,left,node); - yy(CALLB,right,node); - yy(CALLB,type,uid); - break; - caselabel(RET); break; - caselabel(ADDRG); - yy(ADDRG,uid,uid); - break; - caselabel(ADDRL); - yy(ADDRL,uid,uid); - break; - caselabel(ADDRF); - yy(ADDRF,uid,uid); - break; - caselabel(Unary); - yy(Unary,op,op); - yy(Unary,left,node); - break; - caselabel(Binary); - yy(Binary,op,op); - yy(Binary,left,node); - yy(Binary,right,node); - break; - caselabel(Compare); - yy(Compare,op,op); - yy(Compare,left,node); - yy(Compare,right,node); - yy(Compare,label,label); - break; - caselabel(LABEL); - yy(LABEL,label,define_label); - break; - caselabel(BRANCH); - yy(BRANCH,label,label); - break; - caselabel(CSE); - yy(CSE,uid,uid); - yy(CSE,node,node); - break; - default: assert(0); - } -#undef attributes - printf("</ul>"); -} - -static void do_node_list(list_ty x) { - do_list(x, do_node, "node", "ol", ""); -} - -static void do_interface(void *); - -static void do_interface_list(list_ty x) { - do_list(x, do_interface, "interface", "ol", ""); -} - -static void do_interface(void *y) { - rcc_interface_ty x = y; - - if (x->kind == rcc_Address_enum) - printf("<a name='%d'></a>", x->v.rcc_Address.uid); - else if (x->kind == rcc_Local_enum) - printf("<a name='%d'></a>", x->v.rcc_Local.uid); -#define attributes - switch (x->kind) { - static char *typename = "interface"; - caselabel(Export); - yy(Export,p,uid); - break; - caselabel(Import); - yy(Import,p,uid); - break; - caselabel(Global); - yy(Global,p,uid); - yy(Global,seg,seg); - break; - caselabel(Local); - yy(Local,uid,define_uid); - yy(Local,p,symbol); - break; - caselabel(Address); - yy(Address,uid,define_uid); - yy(Address,q,symbol); - yy(Address,p,uid); - yy(Address,n,int); - break; - caselabel(Segment); - yy(Segment,seg,seg); - break; - caselabel(Defaddress); - yy(Defaddress,p,uid); - break; - caselabel(Deflabel); - yy(Deflabel,label,label); - break; - caselabel(Defconst); - yy(Defconst,suffix,suffix); - yy(Defconst,size,int); - yy(Defconst,value,int); - break; - caselabel(Defconstf); - yy(Defconstf,size,int); - yy(Defconstf,value,real); - break; - caselabel(Defstring); - yy(Defstring,s,string); - break; - caselabel(Space); - yy(Space,n,int); - break; - caselabel(Function); - yy(Function,f,uid); - yy(Function,caller,uid_list); - yy(Function,callee,uid_list); - yy(Function,ncalls,int); - yy(Function,codelist,interface_list); - break; - caselabel(Forest); - yy(Forest,nodes,node_list); - break; - case rcc_Blockbeg_enum: printf("<strong>Blockbeg</strong> : <em>%s</em>", typename); return; - case rcc_Blockend_enum: printf("<strong>Blockend</strong> : <em>%s</em>", typename); return; - default: assert(0); - } -#undef attributes - printf("</ul>\n"); -} - -static void do_program(rcc_program_ty x) { - printf("<ul>\n"); - xx(x,nuids,int); - xx(x,nlabels,int); - xx(x,items,item_list); - xx(x,interfaces,interface_list); - xx(x,argc,int); - xx(x,argv,string_list); - printf("</ul>\n"); -} - -int main(int argc, char *argv[]) { - int i, version; - float stamp = (assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) -; - char *infile = NULL, *outfile = NULL; - rcc_program_ty pickle; - - for (i = 1; i < argc; i++) - if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) { - if (infile == NULL) - infile = argv[i]; - else if (outfile == NULL) - outfile = argv[i]; - } - if (infile != NULL && strcmp(infile, "-") != 0 - && freopen(infile, "rb", stdin) == NULL) { - fprintf(stderr, "%s: can't read `%s'\n", argv[0], infile); - exit(EXIT_FAILURE); - } - if (infile == NULL || strcmp(infile, "-") == 0) - infile = "Standard Input"; -#if WIN32 - else - _setmode(_fileno(stdin), _O_BINARY); -#endif - if (outfile != NULL && strcmp(outfile, "-") != 0 - && freopen(outfile, "w", stdout) == NULL) { - fprintf(stderr, "%s: can't write `%s'\n", argv[0], outfile); - exit(EXIT_FAILURE); - } - version = read_int(stdin); - assert(version/100 == (int)stamp); - pickle = rcc_read_program(stdin); - printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\"\n"); - printf("<html><head><title>%s</title>\n" - "<link rev=made href=\"mailto:drh@microsoft.com\">\n" - "</head><body>\n<h1>%s</h1>\n", infile, infile); - printf("<p>version = %d.%d</p>", version/100, version%100); - do_program(pickle); - { - time_t t; - time(&t); - printf("<hr><address>%s</address>\n", ctime(&t)); - } - printf("</body></html>\n"); - return EXIT_SUCCESS; -} diff --git a/lcc/src/alloc.c b/lcc/src/alloc.c deleted file mode 100644 index e0566df..0000000 --- a/lcc/src/alloc.c +++ /dev/null @@ -1,94 +0,0 @@ -#include "c.h" -struct block { - struct block *next; - char *limit; - char *avail; -}; -union align { - long l; - char *p; - double d; - int (*f)(void); -}; -union header { - struct block b; - union align a; -}; -#ifdef PURIFY -union header *arena[3]; - -void *allocate(unsigned long n, unsigned a) { - union header *new = malloc(sizeof *new + n); - - assert(a < NELEMS(arena)); - if (new == NULL) { - error("insufficient memory\n"); - exit(1); - } - new->b.next = (void *)arena[a]; - arena[a] = new; - return new + 1; -} - -void deallocate(unsigned a) { - union header *p, *q; - - assert(a < NELEMS(arena)); - for (p = arena[a]; p; p = q) { - q = (void *)p->b.next; - free(p); - } - arena[a] = NULL; -} - -void *newarray(unsigned long m, unsigned long n, unsigned a) { - return allocate(m*n, a); -} -#else -static struct block - first[] = { { NULL }, { NULL }, { NULL } }, - *arena[] = { &first[0], &first[1], &first[2] }; -static struct block *freeblocks; - -void *allocate(unsigned long n, unsigned a) { - struct block *ap; - - assert(a < NELEMS(arena)); - assert(n > 0); - ap = arena[a]; - n = roundup(n, sizeof (union align)); - while (n > ap->limit - ap->avail) { - if ((ap->next = freeblocks) != NULL) { - freeblocks = freeblocks->next; - ap = ap->next; - } else - { - unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align)); - ap->next = malloc(m); - ap = ap->next; - if (ap == NULL) { - error("insufficient memory\n"); - exit(1); - } - ap->limit = (char *)ap + m; - } - ap->avail = (char *)((union header *)ap + 1); - ap->next = NULL; - arena[a] = ap; - - } - ap->avail += n; - return ap->avail - n; -} - -void *newarray(unsigned long m, unsigned long n, unsigned a) { - return allocate(m*n, a); -} -void deallocate(unsigned a) { - assert(a < NELEMS(arena)); - arena[a]->next = freeblocks; - freeblocks = first[a].next; - first[a].next = NULL; - arena[a] = &first[a]; -} -#endif diff --git a/lcc/src/alpha.md b/lcc/src/alpha.md deleted file mode 100644 index 450dfd3..0000000 --- a/lcc/src/alpha.md +++ /dev/null @@ -1,1192 +0,0 @@ -%{ -#define INTTMP ((0xff<<1)|(1<<22)|(1<<25)|(1<<27)) -#define INTVAR (0x3f<<9) -#define FLTTMP ((0x3f<<10)|(0x1ff<<22)) -#define FLTVAR (0xff<<2) - -#define INTRET 0x00000001 -#define FLTRET 0x00000003 - -#define readsreg(p) \ - (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P) -#define setsrc(d) ((d) && (d)->x.regnode && \ - (d)->x.regnode->set == src->x.regnode->set && \ - (d)->x.regnode->mask&src->x.regnode->mask) - -#define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b)) - -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -static Symbol ireg[32], freg[32]; -static Symbol iregw, fregw; - -static int tmpregs[] = {4, 2, 3}; -static Symbol blkreg; - -static int cseg; - -static char *currentfile; - -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -acon: con "%0" -acon: ADDRGP8 "%a" - -addr: ADDI4(reg,acon) "%1($%0)" -addr: ADDI8(reg,acon) "%1($%0)" -addr: ADDU8(reg,acon) "%1($%0)" -addr: ADDP8(reg,acon) "%1($%0)" - -addr: acon "%0" -addr: reg "($%0)" - -addr: ADDRFP8 "%a+%F($sp)" -addr: ADDRLP8 "%a+%F($sp)" - -reg: addr "lda $%c,%0\n" 1 - -reg: CNSTI1 "# reg\n" range(a, 0, 0) -reg: CNSTI2 "# reg\n" range(a, 0, 0) -reg: CNSTI4 "# reg\n" range(a, 0, 0) -reg: CNSTI8 "# reg\n" range(a, 0, 0) -reg: CNSTU1 "# reg\n" range(a, 0, 0) -reg: CNSTU2 "# reg\n" range(a, 0, 0) -reg: CNSTU4 "# reg\n" range(a, 0, 0) -reg: CNSTU8 "# reg\n" range(a, 0, 0) -reg: CNSTP8 "# reg\n" range(a, 0, 0) - -stmt: ASGNI1(addr,reg) "stb $%1,%0\n" 1 -stmt: ASGNU1(addr,reg) "stb $%1,%0\n" 1 -stmt: ASGNI2(addr,reg) "stw $%1,%0\n" 1 -stmt: ASGNU2(addr,reg) "stw $%1,%0\n" 1 - -stmt: ASGNI4(addr,reg) "stl $%1,%0\n" 1 -stmt: ASGNU4(addr,reg) "stl $%1,%0\n" 1 -stmt: ASGNI8(addr,reg) "stq $%1,%0\n" 1 -stmt: ASGNU8(addr,reg) "stq $%1,%0\n" 1 -stmt: ASGNP8(addr,reg) "stq $%1,%0\n" 1 - -reg: INDIRI1(reg) "ldb $%c,($%0)\n" 1 -reg: INDIRI2(reg) "ldw $%c,($%0)\n" 1 -reg: INDIRI4(addr) "ldl $%c,%0\n" 1 -reg: INDIRI8(addr) "ldq $%c,%0\n" 1 -reg: INDIRP8(addr) "ldq $%c,%0\n" 1 -reg: INDIRU1(reg) "ldbu $%c,($%0)\n" 1 -reg: INDIRU2(reg) "ldwu $%c,($%0)\n" 1 -reg: INDIRU4(addr) "ldl $%c,%0\nzap $%c,240,$%c\n" 2 -reg: INDIRU8(addr) "ldq $%c,%0\n" 1 - -reg: CVII4(INDIRI1(reg)) "ldb $%c,($%0)\n" 1 -reg: CVII8(INDIRI1(reg)) "ldb $%c,($%0)\n" 1 -reg: CVII4(INDIRI2(reg)) "ldw $%c,($%0)\n" 1 -reg: CVII8(INDIRI2(reg)) "ldw $%c,($%0)\n" 1 -reg: CVII8(INDIRI4(addr)) "ldl $%c,%0\n" 1 - -reg: CVUU4(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUU8(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUU4(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUU8(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUU8(INDIRU4(addr)) "ldl $%c,%0\nzap $%c,240,$%c\n" 2 - -reg: CVUI4(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUI8(INDIRU1(reg)) "ldbu $%c,($%0)\n" 1 -reg: CVUI4(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUI8(INDIRU2(reg)) "ldwu $%c,($%0)\n" 1 -reg: CVUI8(INDIRU4(addr)) "ldl $%c,%0\nzap $%c,240,$%c\n" 2 - -reg: CVIU8(reg) "mov $%0,$%c\n" move(a) - -reg: INDIRF4(addr) "lds $f%c,%0\n" 1 -reg: INDIRF8(addr) "ldt $f%c,%0\n" 1 -stmt: ASGNF4(addr,reg) "sts $f%1,%0\n" 1 -stmt: ASGNF8(addr,reg) "stt $f%1,%0\n" 1 - -reg: MULI4(reg,rc) "mull $%0,%1,$%c\n" 1 -reg: MULI8(reg,rc) "mulq $%0,%1,$%c\n" 1 -reg: MULU4(reg,rc) "mull $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: MULU8(reg,rc) "mulq $%0,%1,$%c\n" 1 - -reg: DIVI4(reg,rc) "divl $%0,%1,$%c\n" 1 -reg: DIVI8(reg,rc) "divq $%0,%1,$%c\n" 1 -reg: DIVU4(reg,rc) "divlu $%0,%1,$%c\n" 1 -reg: DIVU8(reg,rc) "divqu $%0,%1,$%c\n" 1 -reg: MODI4(reg,rc) "reml $%0,%1,$%c\n" 1 -reg: MODI8(reg,rc) "remq $%0,%1,$%c\n" 1 -reg: MODU4(reg,rc) "remlu $%0,%1,$%c\n" 1 -reg: MODU8(reg,rc) "remqu $%0,%1,$%c\n" 1 - -rc: con "%0" -rc: reg "$%0" - -reg: ADDI4(reg,rc) "addl $%0,%1,$%c\n" 1 -reg: ADDI8(reg,rc) "addq $%0,%1,$%c\n" 1 -reg: ADDP8(reg,rc) "addq $%0,%1,$%c\n" 1 -reg: ADDU4(reg,rc) "addl $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: ADDU8(reg,rc) "addq $%0,%1,$%c\n" 1 -reg: SUBI4(reg,rc) "subl $%0,%1,$%c\n" 1 -reg: SUBI8(reg,rc) "subq $%0,%1,$%c\n" 1 -reg: SUBP8(reg,rc) "subq $%0,%1,$%c\n" 1 -reg: SUBU4(reg,rc) "subl $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: SUBU8(reg,rc) "subq $%0,%1,$%c\n" 1 - -reg: BANDI4(reg,rc) "and $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: BANDI8(reg,rc) "and $%0,%1,$%c\n" 1 -reg: BANDU4(reg,rc) "and $%0,%1,$%c\n" 1 -reg: BANDU8(reg,rc) "and $%0,%1,$%c\n" 1 -reg: BORI4(reg,rc) "or $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: BORI8(reg,rc) "or $%0,%1,$%c\n" 1 -reg: BORU4(reg,rc) "or $%0,%1,$%c\n" 1 -reg: BORU8(reg,rc) "or $%0,%1,$%c\n" 1 -reg: BXORI4(reg,rc) "xor $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: BXORI8(reg,rc) "xor $%0,%1,$%c\n" 1 -reg: BXORU4(reg,rc) "xor $%0,%1,$%c\n" 1 -reg: BXORU8(reg,rc) "xor $%0,%1,$%c\n" 1 - -rc6: CNSTI4 "%a" range(a,0,63) -rc6: CNSTI8 "%a" range(a,0,63) -rc6: reg "$%0" - -reg: LSHI4(reg,rc6) "sll $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: LSHI8(reg,rc6) "sll $%0,%1,$%c\n" 1 -reg: LSHU4(reg,rc6) "sll $%0,%1,$%c\nzap $%c,240,$%c\n" 2 -reg: LSHU8(reg,rc6) "sll $%0,%1,$%c\n" 1 -reg: RSHI4(reg,rc6) "sra $%0,%1,$%c\naddl $%c,0,$%c\n" 2 -reg: RSHI8(reg,rc6) "sra $%0,%1,$%c\n" 1 -reg: RSHU4(reg,rc6) "srl $%0,%1,$%c\n" 1 -reg: RSHU8(reg,rc6) "srl $%0,%1,$%c\n" 1 - -reg: BCOMI4(reg) "not $%0,$%c\naddl $%c,0,$%c\n" 2 -reg: BCOMU4(reg) "not $%0,$%c\nzap $%c,240,$%c\n" 2 -reg: BCOMI8(reg) "not $%0,$%c\n" 1 -reg: BCOMU8(reg) "not $%0,$%c\n" 1 -reg: NEGI4(reg) "negl $%0,$%c\n" 1 -reg: NEGI8(reg) "negq $%0,$%c\n" 1 -reg: LOADI1(reg) "mov $%0,$%c\n" move(a) -reg: LOADI2(reg) "mov $%0,$%c\n" move(a) -reg: LOADI4(reg) "mov $%0,$%c\n" move(a) -reg: LOADI8(reg) "mov $%0,$%c\n" move(a) -reg: LOADP8(reg) "mov $%0,$%c\n" move(a) -reg: LOADU1(reg) "mov $%0,$%c\n" move(a) -reg: LOADU2(reg) "mov $%0,$%c\n" move(a) -reg: LOADU4(reg) "mov $%0,$%c\n" move(a) -reg: LOADU8(reg) "mov $%0,$%c\n" move(a) - -reg: ADDF4(reg,reg) "adds $f%0,$f%1,$f%c\n" 1 -reg: ADDF8(reg,reg) "addt $f%0,$f%1,$f%c\n" 1 -reg: DIVF4(reg,reg) "divs $f%0,$f%1,$f%c\n" 1 -reg: DIVF8(reg,reg) "divt $f%0,$f%1,$f%c\n" 1 -reg: MULF4(reg,reg) "muls $f%0,$f%1,$f%c\n" 1 -reg: MULF8(reg,reg) "mult $f%0,$f%1,$f%c\n" 1 -reg: SUBF4(reg,reg) "subs $f%0,$f%1,$f%c\n" 1 -reg: SUBF8(reg,reg) "subt $f%0,$f%1,$f%c\n" 1 -reg: LOADF4(reg) "fmov $f%0,$f%c\n" move(a) -reg: LOADF8(reg) "fmov $f%0,$f%c\n" move(a) -reg: NEGF4(reg) "negs $f%0,$f%c\n" 1 -reg: NEGF8(reg) "negt $f%0,$f%c\n" 1 -reg: CVII4(reg) "sll $%0,8*(8-%a),$%c\nsra $%c,8*(8-%a),$%c\n" 2 -reg: CVII8(reg) "sll $%0,8*(8-%a),$%c\nsra $%c,8*(8-%a),$%c\n" 2 -reg: CVUI4(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 -reg: CVUI8(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 -reg: CVUU4(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 -reg: CVUU8(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 - -reg: CVUP8(reg) "and $%0,(1<<(8*%a))-1,$%c\n" 1 - -reg: CVFF4(reg) "cvtts $f%0,$f%c\n" 1 -reg: CVFF8(reg) "cvtst $f%0,$f%c\n" 1 - -reg: CVIF4(reg) "stq $%0,-56+%F($sp)\nldt $%f%c,-56+%F($sp)\ncvtqs $f%c,$f%c\n" 3 -reg: CVIF8(reg) "stq $%0,-56+%F($sp)\nldt $%f%c,-56+%F($sp)\ncvtqt $f%c,$f%c\n" 3 -reg: CVIF4(INDIRI4(addr)) "lds $f%c,%0\ncvtlq $f%c,$f%c\ncvtqs $f%c,$f%c\n" 3 -reg: CVIF4(INDIRI8(addr)) "ldt $f%c,%0\ncvtqs $f%c,$f%c\n" 2 -reg: CVIF8(INDIRI4(addr)) "lds $f%c,%0\ncvtlq $f%c,$f%c\ncvtqt $f%c,$f%c\n" 3 -reg: CVIF8(INDIRI8(addr)) "ldt $f%c,%0\ncvtqt $f%c,$f%c\n" 2 - -reg: CVFI4(reg) "cvttqc $f%0,$f1\ncvtql $f1,$f1\nsts $f1,-56+%F($sp)\nldl $%c,-56+%F($sp)\n" 4 -reg: CVFI8(reg) "cvttqc $f%0,$f1\nstt $f1,-56+%F($sp)\nldq $%c,-56+%F($sp)\n" 3 - -stmt: LABELV "%a:\n" - -stmt: JUMPV(acon) "br %0\n" 1 -stmt: JUMPV(reg) "jmp ($%0)\n" 1 - -stmt: EQI4(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: EQU4(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: EQI8(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: EQU8(reg,rc6) "cmpeq $%0,%1,$23\nbne $23,%a\n" 2 -stmt: NEI4(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: NEU4(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: NEI8(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: NEU8(reg,rc6) "cmpeq $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GEI4(reg,rc6) "cmplt $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GEI8(reg,rc6) "cmplt $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GEU4(reg,rc6) "cmpult $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: GEU8(reg,rc6) "cmpult $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: GTI4(reg,rc6) "cmple $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GTI8(reg,rc6) "cmple $%0,%1,$23\nbeq $23,%a\n" 2 -stmt: GTU4(reg,rc6) "cmpule $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: GTU8(reg,rc6) "cmpule $%0,%1,$23\nbeq $23,%a\n" 1 -stmt: LEI4(reg,rc6) "cmple $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LEI8(reg,rc6) "cmple $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LEU4(reg,rc6) "cmpule $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LEU8(reg,rc6) "cmpule $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTI4(reg,rc6) "cmplt $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTI8(reg,rc6) "cmplt $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTU4(reg,rc6) "cmpult $%0,%1,$23\nbne $23,%a\n" 2 -stmt: LTU8(reg,rc6) "cmpult $%0,%1,$23\nbne $23,%a\n" 2 - -stmt: EQF4(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: EQF8(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LEF4(reg,reg) "cmptle $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LEF8(reg,reg) "cmptle $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LTF4(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 -stmt: LTF8(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbne $f1,%a\n" 2 - -stmt: NEF4(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: NEF8(reg,reg) "cmpteq $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GEF4(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GEF8(reg,reg) "cmptlt $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GTF4(reg,reg) "cmptle $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 -stmt: GTF8(reg,reg) "cmptle $f%0,$f%1,$f1\nfbeq $f1,%a\n" 2 - -ar: ADDRGP8 "%a" -ar: reg "($%0)" - -reg: CALLF4(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLF8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLI4(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLI8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLP8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLU4(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -reg: CALLU8(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 -stmt: CALLV(ar) "jsr $26,%0\nldgp $gp,0($26)\n" 2 - -stmt: RETF4(reg) "# ret\n" 1 -stmt: RETF8(reg) "# ret\n" 1 -stmt: RETI4(reg) "# ret\n" 1 -stmt: RETU4(reg) "# ret\n" 1 -stmt: RETI8(reg) "# ret\n" 1 -stmt: RETU8(reg) "# ret\n" 1 -stmt: RETP8(reg) "# ret\n" 1 -stmt: RETV(reg) "# ret\n" 1 - -stmt: ARGF4(reg) "# arg\n" 1 -stmt: ARGF8(reg) "# arg\n" 1 -stmt: ARGI4(reg) "# arg\n" 1 -stmt: ARGI8(reg) "# arg\n" 1 -stmt: ARGP8(reg) "# arg\n" 1 -stmt: ARGU4(reg) "# arg\n" 1 -stmt: ARGU8(reg) "# arg\n" 1 - -stmt: ARGB(INDIRB(reg)) "# argb %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "# asgnb %0 %1\n" 1 - -%% -static void progend(void){} - -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - - for (i = 0; i < 32; i++) - freg[i] = mkreg("%d", i, 1, FREG); - for (i = 0; i < 32; i++) - ireg[i] = mkreg("%d", i, 1, IREG); - ireg[29]->x.name = "gp"; - ireg[30]->x.name = "sp"; - fregw = mkwildcard(freg); - iregw = mkwildcard(ireg); - - tmask[IREG] = INTTMP; tmask[FREG] = FLTTMP; - vmask[IREG] = INTVAR; vmask[FREG] = FLTVAR; - - blkreg = mkreg("1", 1, 0xf, IREG); - -} - -static Symbol rmap(int opk) { - switch (optype(opk)) { - case I: case U: case P: case B: - return iregw; - case F: - return fregw; - default: - return 0; - } -} - -static Symbol argreg(int offset, int ty) { - if (offset >= 48) - return NULL; - else if (ty == F) - return freg[(offset/8) + 16]; - else - return ireg[(offset/8) + 16]; -} - -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case CNST+I: case CNST+U: case CNST+P: - if (range(p, 0, 0) == 0) { - setreg(p, ireg[31]); - p->x.registered = 1; - } - break; - case CNST+F: - if (p->syms[0]->u.c.v.d == 0) { - setreg(p, freg[31]); - p->x.registered = 1; - } - break; - - case CALL+V: - rtarget(p, 0, ireg[27]); - break; - case CALL+F: - rtarget(p, 0, ireg[27]); - setreg(p, freg[0]); - break; - case CALL+I: case CALL+P: case CALL+U: - rtarget(p, 0, ireg[27]); - setreg(p, ireg[0]); - break; - case RET+F: - rtarget(p, 0, freg[0]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, ireg[0]); - break; - - case ARG+F: case ARG+I: case ARG+P: case ARG+U: { - Symbol q = argreg(p->syms[2]->u.c.v.i, optype(p->op)); - if (q) - rtarget(p, 0, q); - break; - } - - - case ASGN+B: rtarget(p->kids[1], 0, blkreg); break; - case ARG+B: rtarget(p->kids[0], 0, blkreg); break; - - } -} - -static void clobber(Node p) { - assert(p); - switch (specific(p->op)) { - case ASGN+I: case ASGN+U: - if (opsize(p->op) <= 2) - spill(1<<24, IREG, p); - break; - - case DIV+I: case DIV+U: case MOD+I: case MOD+U: - spill(((1<<27)|(3<<24))&~p->syms[RX]->x.regnode->mask, IREG, p); - break; - - case CALL+F: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP, FREG, p); - break; - case CALL+I: case CALL+P: case CALL+U: - spill(INTTMP, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - case CALL+V: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - - } -} - -static void emit2(Node p) { - int dst, n, src, sz, ty; - static int ty0; - Symbol q; - - switch (specific(p->op)) { - case ARG+F: case ARG+I: case ARG+P: case ARG+U: - ty = optype(p->op); - sz = opsize(p->op); - q = argreg(p->syms[2]->u.c.v.i, ty); - src = getregnum(p->x.kids[0]); - if (q) - break; - else if (ty == F && sz == 4) - print("sts $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else if (ty == F && sz == 8) - print("stt $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else if (sz == 4) - print("stq $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else if (sz == 8) - print("stq $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i - 48); - else - assert(0); - break; - - case ASGN+B: - dalign = salign = p->syms[1]->u.c.v.i; - blkcopy(getregnum(p->x.kids[0]), 0, - getregnum(p->x.kids[1]), 0, - p->syms[0]->u.c.v.i, tmpregs); - break; - - - case ARG+B: { - int doff = p->syms[2]->u.c.v.i, soff = 0, sreg = getregnum(p->x.kids[0]); - dalign = 8; - salign = p->syms[1]->u.c.v.i; - n = p->syms[0]->u.c.v.i; - for ( ; doff <= 40 && n > 0; doff += 8) { - print("uldq $%d,%d($%d)\n", (doff/8)+16, soff, sreg); - soff += 8; - n -= 8; - } - if (n > 0) - blkcopy(30, doff - 48, sreg, soff, n, tmpregs); - break; - } - - } -} - -static void doarg(Node p) { - p->syms[2] = intconst(mkactual(8, roundup(p->syms[0]->u.c.v.i,8))); -} - -static void local(Symbol p) { - if (askregvar(p, rmap(ttob(p->type))) == 0) - mkauto(p); -} - -static int bitcount(unsigned mask) { - unsigned i, n = 0; - - for (i = 1; i; i <<= 1) - if (mask&i) - n++; - return n; -} - -static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int i, sizeargs, saved, sizefsave, sizeisave, varargs; - Symbol r, argregs[6]; - - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - maxargoffset = offset = maxoffset = 0; - - for (i = 0; callee[i]; i++) - ; - varargs = variadic(f->type) - || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0; - if (varargs) - sizeargs = 2*48; - else - sizeargs = 48; - - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - if (isfloat(p->type) && varargs) { - p->x.offset = q->x.offset = offset - 2*48; - p->x.name = q->x.name = stringd(offset - 2*48); - } else { - p->x.offset = q->x.offset = offset - 48; - p->x.name = q->x.name = stringd(offset - 48); - } - offset = roundup(offset, q->type->align); - r = argreg(offset, optype(ttob(q->type))); - if (i < 6) - argregs[i] = r; - offset = roundup(offset + q->type->size, 8); - if (varargs) - p->sclass = AUTO; - else if (r && ncalls == 0 && !isstruct(q->type) && !p->addressed -) { - p->sclass = q->sclass = REGISTER; - askregvar(p, r); - assert(p->x.regnode && p->x.regnode->vbl == p); - q->x = p->x; - q->type = p->type; - } else if (askregvar(p, rmap(ttob(p->type))) - && r != NULL /* - && (isint(p->type) || p->type == q->type) */ -) { - assert(q->sclass != REGISTER); - p->sclass = q->sclass = REGISTER; - q->type = p->type; - } - - } - assert(!caller[i]); - - offset = sizeargs + 8; - gencode(caller, callee); - usedmask[IREG] &= ~(INTTMP|(0x3f<<16)|INTRET); - usedmask[FREG] &= ~(FLTTMP|(0x3f<<16)|FLTRET); - if (ncalls || usedmask[IREG] || usedmask[FREG]) - usedmask[IREG] |= 1<<26; - sizefsave = 8*bitcount(usedmask[FREG]); - sizeisave = 8*bitcount(usedmask[IREG]); - if (maxargoffset > 48) - maxargoffset -= 48; - else - maxargoffset = 0; - if (maxoffset < sizeargs) - maxoffset = sizeargs; - framesize = roundup(maxargoffset + sizefsave + sizeisave + maxoffset, 16); - segment(CODE); - print(".ent %s\n", f->x.name); - print("%s:\n", f->x.name); - print("ldgp $gp,0($27)\n"); - i = maxargoffset + sizefsave - framesize; - if (framesize > 0) - print("lda $sp,%d($sp)\n", -framesize); - if (usedmask[FREG]) - print(".fmask 0x%x,%d\n", usedmask[FREG], i - 8); - if (usedmask[IREG]) - print(".mask 0x%x,%d\n", usedmask[IREG], i + sizeisave - 8); - print(".frame $sp,%d,$26,%d\n", framesize, sizeargs); - - saved = maxargoffset; - for (i = 2; i <= 9; i++) - if (usedmask[FREG]&(1<<i)) { - print("stt $f%d,%d($sp)\n", i, saved); - saved += 8; - } - - for (i = 9; i <= 26; i++) - if (usedmask[IREG]&(1<<i)) { - print("stq $%d,%d($sp)\n", i, saved); - saved += 8; - } - for (i = 0; i < 6 && callee[i]; i++) { - r = argregs[i]; - if (r && r->x.regnode != callee[i]->x.regnode) { - Symbol out = callee[i]; - Symbol in = caller[i]; - int rn = r->x.regnode->number; - int rs = r->x.regnode->set; - int tyin = ttob(in->type); - - assert(out && in && r && r->x.regnode); - assert(out->sclass != REGISTER || out->x.regnode); - if (out->sclass == REGISTER) { - if (rs == FREG) - print("fmov $f%d,$f%d\n", rn, out->x.regnode->number); - else - print("mov $%d,$%d\n", rn, out->x.regnode->number); - - } else { - int off = in->x.offset + framesize; - if (rs == FREG && tyin == F+sizeop(8)) - print("stt $f%d,%d($sp)\n", rn, off); - else if (rs == FREG && tyin == F+sizeop(4)) - print("sts $f%d,%d($sp)\n", rn, off); - else { - int i, n = (in->type->size + 7)/8; - for (i = rn; i < rn+n && i <= 21; i++) - print("stq $%d,%d($sp)\n", i, off + (i-rn)*8); - } - - } - - } - } - if (varargs && callee[i-1]) { - i = callee[i-1]->x.offset + roundup(callee[i-1]->type->size, 8); - for (i = (48+i)/8; i < 6; i++) { - print("stq $%d,%d($sp)\n", i + 16, framesize - 48 + 8*i); - print("stt $f%d,%d($sp)\n", i + 16, framesize - 2*48 + 8*i); - } - } - print(".prologue 1\n"); - - emitcode(); - saved = maxargoffset; - for (i = 2; i <= 9; i++) - if (usedmask[FREG]&(1<<i)) { - print("ldt $f%d,%d($sp)\n", i, saved); - saved += 8; - } - for (i = 9; i <= 26; i++) - if (usedmask[IREG]&(1<<i)) { - print("ldq $%d,%d($sp)\n", i, saved); - saved += 8; - } - if (framesize > 0) - print("lda $sp,%d($sp)\n", framesize); - print("ret\n"); - print(".end %s\n", f->x.name); - -} - -static void defconst(int suffix, int size, Value v) { - if (suffix == F && size == 4) { - float f = v.d; - print(".long 0x%x\n", *(unsigned *)&f); - } else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".long 0x%x\n.long 0x%x\n", p[swap], p[!swap]); - } else if (suffix == P) - print(".quad 0x%X\n", v.p); - else if (size == 1) - print(".byte 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 2) - print(".word 0x%x\n", suffix == I ? v.i&0xFFFF : v.u&0xFFFF); - else if (size == 4) - print(".long 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 8) - print(".quad 0x%X\n", suffix == I ? v.i : v.u); - -} - -static void defaddress(Symbol p) { - print(".quad %s\n", p->x.name); -} - -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} - -static void export(Symbol p) { - print(".globl %s\n", p->x.name); -} - -static void import(Symbol p) { - if (!isfunc(p->type)) - print(".extern %s %d\n", p->name, p->type->size); -} - -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("L.%d", genlabel(1)); - else if (p->generated) - p->x.name = stringf("L.%s", p->name); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; -} - -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", p->x.name, - n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} - -static void global(Symbol p) { - if (p->u.seg == DATA || p->u.seg == LIT) { - assert(p->type->align <= 8); - print(".align %c\n", ".01.2...3"[p->type->align]); - print("%s:\n", p->x.name); - } else if (p->sclass == STATIC || Aflag >= 2) - print(".lcomm %s,%d\n", p->x.name, p->type->size); - else - print( ".comm %s,%d\n", p->x.name, p->type->size); -} - -static void segment(int n) { - cseg = n; - switch (n) { - case DATA: print(".sdata\n"); break; - case CODE: print(".text\n"); break; - case LIT: print(".rdata\n"); break; - } -} - -static void space(int n) { - if (cseg != BSS) - print(".space %d\n", n); -} - -static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { - int lab = genlabel(1); - - print("addq $%d,%d,$%d\n", sreg, size&~7, sreg); - print("addq $%d,%d,$%d\n", dreg, size&~7, tmps[2]); - blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); - print("L.%d:\n", lab); - print("addq $%d,%d,$%d\n", sreg, -8, sreg); - print("addq $%d,%d,$%d\n", tmps[2], -8, tmps[2]); - blkcopy(tmps[2], doff, sreg, soff, 8, tmps); - print("cmpult $%d,$%d,$23\nbne $23,L.%d\n", dreg, tmps[2], lab); -} - -static void blkfetch(int size, int off, int reg, int tmp) { - assert(size == 1 || size == 2 || size == 4 || size == 8); - if (size == 1) - print("ldb $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("ldw $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size && size == 4) - print("ldl $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size && size == 8) - print("ldq $%d,%d($%d)\n", tmp, off, reg); - else if (size == 4) - print("uldl $%d,%d($%d)\n", tmp, off, reg); - else - print("uldq $%d,%d($%d)\n", tmp, off, reg); -} - -static void blkstore(int size, int off, int reg, int tmp) { - assert(size == 1 || size == 2 || size == 4 || size == 8); - if (size == 1) - print("stb $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("stw $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size && size == 4) - print("stl $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size && size == 8) - print("stq $%d,%d($%d)\n", tmp, off, reg); - else if (size == 4) - print("ustl $%d,%d($%d)\n", tmp, off, reg); - else - print("ustq $%d,%d($%d)\n", tmp, off, reg); -} - -/* stabinit - initialize stab output */ -static void stabinit(char *file, int argc, char *argv[]) { - if (file) { - print(".file 2,\"%s\"\n", file); - currentfile = file; - } -} - -/* stabline - emit stab entry for source coordinate *cp */ -static void stabline(Coordinate *cp) { - if (cp->file && cp->file != currentfile) { - print(".file 2,\"%s\"\n", cp->file); - currentfile = cp->file; - } - print(".loc 2,%d\n", cp->y); -} - -/* stabsym - output a stab entry for symbol p */ -static void stabsym(Symbol p) { - if (p == cfunc && IR->stabline) - (*IR->stabline)(&p->src); -} -Interface alphaIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 8, 8, 0, /* long */ - 8, 8, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 8, 8, 0, /* T * */ - 0, 1, 0, /* struct */ - - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, stabinit, stabline, stabsym, 0, - { - 1, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } - -}; - - -static char rcsid[] = "$Id: alpha.md 145 2001-10-17 21:53:10Z timo $"; - diff --git a/lcc/src/asdl.c b/lcc/src/asdl.c deleted file mode 100644 index bb22c89..0000000 --- a/lcc/src/asdl.c +++ /dev/null @@ -1,399 +0,0 @@ -#include "c.h" -#include "rcc.h" -#if WIN32 -#include <fcntl.h> -#include <io.h> -#endif - - -static list_ty interfaces; -static rcc_program_ty pickle; - -char *string(const char *str) { - return (char *)Atom_string(str); -} - -char *stringd(long n) { - return (char *)Atom_int(n); -} - -char *stringn(const char *str, int len) { - return (char *)Atom_new(str, len); -} - -static void put(rcc_interface_ty node) { - Seq_addhi(interfaces, node); -} - -static int typeuid(Type ty) { - rcc_type_ty type; - - assert(ty); - if (ty->x.typeno != 0) - return ty->x.typeno; - ty->x.typeno = pickle->nuids++; - switch (ty->op) { -#define xx(op) case op: type = rcc_##op(ty->size, ty->align); break - xx(INT); - xx(UNSIGNED); - xx(FLOAT); - xx(VOID); -#undef xx -#define xx(op) case op: type = rcc_##op(ty->size, ty->align, typeuid(ty->type)); break - xx(POINTER); - xx(ARRAY); - xx(CONST); - xx(VOLATILE); -#undef xx - case CONST+VOLATILE: - type = rcc_CONST(ty->size, ty->align, typeuid(ty->type)); - break; - case ENUM: { - list_ty ids = Seq_new(0); - int i; - for (i = 0; ty->u.sym->u.idlist[i] != NULL; i++) - Seq_addhi(ids, rcc_enum_(ty->u.sym->u.idlist[i]->name, - ty->u.sym->u.idlist[i]->u.value)); - assert(i > 0); - type = rcc_ENUM(ty->size, ty->align, ty->u.sym->name, ids); - break; - } - case STRUCT: case UNION: { - list_ty fields = Seq_new(0); - Field p = fieldlist(ty); - for ( ; p != NULL; p = p->link) - Seq_addhi(fields, rcc_field(p->name, typeuid(p->type), p->offset, p->bitsize, p->lsb)); - if (ty->op == STRUCT) - type = rcc_STRUCT(ty->size, ty->align, ty->u.sym->name, fields); - else - type = rcc_UNION (ty->size, ty->align, ty->u.sym->name, fields); - break; - } - case FUNCTION: { - list_ty formals = Seq_new(0); - if (ty->u.f.proto != NULL && ty->u.f.proto[0] != NULL) { - int i; - for (i = 0; ty->u.f.proto[i] != NULL; i++) - Seq_addhi(formals, to_generic_int(typeuid(ty->u.f.proto[i]))); - } else if (ty->u.f.proto != NULL && ty->u.f.proto[0] == NULL) - Seq_addhi(formals, to_generic_int(typeuid(voidtype))); - type = rcc_FUNCTION(ty->size, ty->align, typeuid(ty->type), formals); - break; - } - default: assert(0); - } - Seq_addhi(pickle->items, rcc_Type(ty->x.typeno, type)); - return ty->x.typeno; -} - -static int symboluid(Symbol p) { - assert(p); - assert(p->scope != CONSTANTS && p->scope != LABELS); - if (p->x.offset == 0) - p->x.offset = pickle->nuids++; - return p->x.offset; -} - -static rcc_symbol_ty mk_symbol(Symbol p) { - int flags = 0, ref = 10000*p->ref; - - if (p->ref > 0 && ref == 0) - ref++; -#define xx(f,n) flags |= p->f<<n; - xx(structarg,0) - xx(addressed,1) - xx(computed,2) - xx(temporary,3) - xx(generated,4) -#undef xx - return rcc_symbol(p->name, typeuid(p->type), p->scope, p->sclass, ref, flags); -} - -static rcc_real_ty mk_real(int size, Value v) { - unsigned *p = (unsigned *)&v.d; - return rcc_real(p[swap], p[1-swap]); -} - -static void asdl_segment(int n) { - static int cseg; - - if (cseg != n) - put(rcc_Segment(cseg = n)); -} - -static void asdl_address(Symbol q, Symbol p, long n) { - assert(q->x.offset == 0); - put(rcc_Address(symboluid(q), mk_symbol(q), symboluid(p), n)); -} - -static void asdl_blockbeg(Env *e) { - put(rcc_Blockbeg()); -} - -static void asdl_blockend(Env *e) { - put(rcc_Blockend()); -} - -static void asdl_defaddress(Symbol p) { - if (p->scope == LABELS) - put(rcc_Deflabel(p->u.l.label)); - else - put(rcc_Defaddress(symboluid(p))); -} - -static void asdl_defconst(int suffix, int size, Value v) { - switch (suffix) { - case I: put(rcc_Defconst(suffix, size, v.i)); return; - case U: put(rcc_Defconst(suffix, size, v.u)); return; - case P: put(rcc_Defconst(suffix, size, (unsigned long)v.p)); return; /* FIXME */ - case F: put(rcc_Defconstf(size, mk_real(size, v))); return; - assert(0); - } -} - -static void asdl_defstring(int len, char *str) { - put(rcc_Defstring(Text_box(stringn(str, len), len))); -} - -static void asdl_defsymbol(Symbol p) { - if (p->scope >= GLOBAL) - symboluid(p); -} - -static Symbol temps; - -static rcc_node_ty visit(Node p) { - Symbol q; - rcc_node_ty left = NULL, right = NULL; - int suffix = optype(p->op), size = opsize(p->op); - - assert(p); - for (q = temps; q; q = q->u.t.next) - if (q->u.t.cse == p) { - q->u.t.cse = NULL; - return rcc_CSE(0, 0, symboluid(q), visit(p)); - } - if (p->kids[0] != NULL) - left = visit(p->kids[0]); - if (p->kids[1] != NULL) - right = visit(p->kids[1]); - switch (specific(p->op)) { - case CNST+F: - assert(p->syms[0]); - return rcc_CNSTF(suffix, size, mk_real(size, p->syms[0]->u.c.v)); - case CALL+B: - assert(p->syms[0]); - assert(p->syms[0]->type); - return rcc_CALLB(suffix, size, left, right, typeuid(p->syms[0]->type)); - case RET+V: - return rcc_RET(suffix, size); - case LABEL+V: - assert(p->syms[0]); - return rcc_LABEL(suffix, size, p->syms[0]->u.l.label); - } - switch (generic(p->op)) { - case CNST: - assert(p->syms[0]); - return rcc_CNST(suffix, size, p->syms[0]->u.c.v.i); /* FIXME */ - case ARG: - assert(p->syms[0]); - return rcc_ARG(suffix, size, left, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i); - case ASGN: - assert(p->syms[0]); - assert(p->syms[1]); - return rcc_ASGN(suffix, size, left, right, p->syms[0]->u.c.v.i, p->syms[1]->u.c.v.i); - case CVF: case CVI: case CVP: case CVU: - assert(p->syms[0]); - return rcc_CVT(suffix, size, generic(p->op), left, p->syms[0]->u.c.v.i); - case CALL: - assert(p->syms[0]); - assert(p->syms[0]->type); - return rcc_CALL(suffix, size, left, typeuid(p->syms[0]->type)); -#define xx(op) case op: return rcc_##op(suffix, size, symboluid(p->syms[0])) - xx(ADDRG); - xx(ADDRF); -#undef xx - case ADDRL: - if (!p->syms[0]->defined) - (*IR->local)(p->syms[0]); - p->syms[0]->defined = 1; - return rcc_ADDRL(suffix, size, symboluid(p->syms[0])); - case JUMP: - if (p->syms[0] != NULL) - return rcc_BRANCH(suffix, size, p->syms[0]->u.l.label); - return rcc_Unary(suffix, size, generic(p->op), left); - case INDIR: case RET: case NEG: case BCOM: - return rcc_Unary(suffix, size, generic(p->op), left); - case BOR: case BAND: case BXOR: case RSH: case LSH: - case ADD: case SUB: case DIV: case MUL: case MOD: - return rcc_Binary(suffix, size, generic(p->op), left, right); - case EQ: case NE: case GT: case GE: case LE: case LT: - assert(p->syms[0]); - return rcc_Compare(suffix, size, generic(p->op), left, right, p->syms[0]->u.l.label); - } - assert(0); - return NULL; -} - -static void asdl_emit(Node p) {} - -static void asdl_local(Symbol p) { - assert(p->x.offset == 0); - put(rcc_Local(symboluid(p), mk_symbol(p))); - if (p->temporary && p->u.t.cse) { - p->u.t.next = temps; - temps = p; - } -} - -static Symbol pending = NULL; - -static void dopending(Symbol p) { - if (pending != NULL) { - int uid = symboluid(pending); - rcc_symbol_ty symbol = mk_symbol(pending); - Seq_addhi(pickle->items, rcc_Symbol(uid, symbol)); - } - pending = p; -} - - -static void asdl_export(Symbol p) { - put(rcc_Export(symboluid(p))); -} - -static void asdl_function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - list_ty codelist = Seq_new(0), save, calleelist = Seq_new(0), callerlist = Seq_new(0); - int i; - - dopending(f); - for (i = 0; caller[i] != NULL; i++) { - asdl_local(caller[i]); - Seq_addhi(callerlist, to_generic_int(symboluid(caller[i]))); - } - for (i = 0; callee[i] != NULL; i++) { - asdl_local(callee[i]); - Seq_addhi(calleelist, to_generic_int(symboluid(callee[i]))); - } - save = interfaces; - interfaces = codelist; - gencode(caller, callee); - asdl_segment(CODE); - emitcode(); - interfaces = save; - put(rcc_Function(symboluid(f), callerlist, calleelist, ncalls, codelist)); -} - -static Node asdl_gen(Node p) { - Node q; - list_ty forest = Seq_new(0); - - for (q = p; p != NULL; p = p->link) - if (specific(p->op) == JUMP+V && specific(p->kids[0]->op) == ADDRG+P - && p->kids[0]->syms[0]->scope == LABELS) { - p->syms[0] = p->kids[0]->syms[0]; - p->kids[0] = NULL; - } - for (p = q; p != NULL; p = p->link) - Seq_addhi(forest, visit(p)); - put(rcc_Forest(forest)); - temps = NULL; - return q; -} - -static void asdl_global(Symbol p) { - dopending(p); - put(rcc_Global(symboluid(p), p->u.seg)); -} - -static void asdl_import(Symbol p) { - dopending(p); - put(rcc_Import(symboluid(p))); -} - -static void asdl_progbeg(int argc, char *argv[]) { - int i; - -#if WIN32 - _setmode(_fileno(stdout), _O_BINARY); -#endif - pickle = rcc_program(1, 0, Seq_new(0), Seq_new(0), argc, Seq_new(0)); - for (i = 0; i < argc; i++) - Seq_addhi(pickle->argv, to_generic_string(Text_box(argv[i], strlen(argv[i]) + 1))); - interfaces = pickle->interfaces; -} - -static int checkuid(list_ty list) { - int i, n = 0, count = Seq_length(list); - - for (i = 0; i < count; i++) { - rcc_interface_ty in = Seq_get(list, i); - if (in->kind == rcc_Local_enum - || in->kind == rcc_Address_enum) - n++; - else if (in->kind == rcc_Function_enum) - n += checkuid(in->v.rcc_Function.codelist); - } - return n; -} - -static void asdl_progend(void) { - dopending(NULL); - { - int n = checkuid(pickle->interfaces) + Seq_length(pickle->items); - if (n != pickle->nuids - 1) - fprintf(stderr, "?bogus uid count: have %d should have %d\n", - n, pickle->nuids-1); - } - pickle->nlabels = genlabel(0); - write_int((int)(100*(assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) -), stdout); - rcc_write_program(pickle, stdout); -} -static void asdl_space(int n) { - put(rcc_Space(n)); -} - -void asdl_init(int argc, char *argv[]) { - int i; - static int inited; - - if (inited) - return; - inited = 1; - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-asdl") == 0) { -#define xx(f) IR->f = asdl_##f - xx(address); - xx(blockbeg); - xx(blockend); - xx(defaddress); - xx(defconst); - xx(defstring); - xx(defsymbol); - xx(emit); - xx(export); - xx(function); - xx(gen); - xx(global); - xx(import); - xx(local); - xx(progbeg); - xx(progend); - xx(segment); - xx(space); -#undef xx -#define xx(f) IR->f = 0 - xx(stabblock); - xx(stabend); - xx(stabfend); - xx(stabinit); - xx(stabline); - xx(stabsym); - xx(stabtype); -#undef xx - IR->wants_dag = 0; - prunetemps = 0; /* pass2 prunes useless temps */ - assignargs = 0; /* pass2 generates caller to callee assignments */ - } -} diff --git a/lcc/src/bind.c b/lcc/src/bind.c deleted file mode 100644 index c27036f..0000000 --- a/lcc/src/bind.c +++ /dev/null @@ -1,23 +0,0 @@ -#include "c.h" -extern Interface alphaIR; -extern Interface mipsebIR, mipselIR; -extern Interface sparcIR, solarisIR; -extern Interface x86IR, x86linuxIR; -extern Interface symbolicIR, symbolic64IR; -extern Interface nullIR; -extern Interface bytecodeIR; -Binding bindings[] = { - /*{ "alpha/osf", &alphaIR },*/ - /*{ "mips/irix", &mipsebIR },*/ - /*{ "mips/ultrix", &mipselIR },*/ - /*{ "sparc/sun", &sparcIR },*/ - /*{ "sparc/solaris", &solarisIR },*/ - /*{ "x86/win32", &x86IR },*/ - /*{ "x86/linux", &x86linuxIR },*/ - { "symbolic/osf", &symbolic64IR }, - { "symbolic/irix", &symbolicIR }, - { "symbolic", &symbolicIR }, - { "null", &nullIR }, - { "bytecode", &bytecodeIR }, - { NULL, NULL }, -}; diff --git a/lcc/src/bytecode.c b/lcc/src/bytecode.c deleted file mode 100644 index b267d6f..0000000 --- a/lcc/src/bytecode.c +++ /dev/null @@ -1,365 +0,0 @@ -#include "c.h" -#define I(f) b_##f - - -static void I(segment)(int n) { - static int cseg; - - if (cseg != n) - switch (cseg = n) { - case CODE: print("code\n"); return; - case DATA: print("data\n"); return; - case BSS: print("bss\n"); return; - case LIT: print("lit\n"); return; - default: assert(0); - } -} - -static void I(address)(Symbol q, Symbol p, long n) { - q->x.name = stringf("%s%s%D", p->x.name, n > 0 ? "+" : "", n); -} - -static void I(defaddress)(Symbol p) { - print("address %s\n", p->x.name); -} - -static void I(defconst)(int suffix, int size, Value v) { - switch (suffix) { - case I: - if (size > sizeof (int)) - print("byte %d %D\n", size, v.i); - else - print("byte %d %d\n", size, v.i); - return; - case U: - if (size > sizeof (unsigned)) - print("byte %d %U\n", size, v.u); - else - print("byte %d %u\n", size, v.u); - return; - case P: print("byte %d %U\n", size, (unsigned long)v.p); return; - case F: - if (size == 4) { - float f = v.d; - print("byte 4 %u\n", *(unsigned *)&f); - } else { - unsigned *p = (unsigned *)&v.d; - print("byte 4 %u\n", p[swap]); - print("byte 4 %u\n", p[1 - swap]); - } - return; - } - assert(0); -} - -static void I(defstring)(int len, char *str) { - char *s; - - for (s = str; s < str + len; s++) - print("byte 1 %d\n", (*s)&0377); -} - -static void I(defsymbol)(Symbol p) { - if (p->scope == CONSTANTS) - switch (optype(ttob(p->type))) { - case I: p->x.name = stringf("%D", p->u.c.v.i); break; - case U: p->x.name = stringf("%U", p->u.c.v.u); break; - case P: p->x.name = stringf("%U", p->u.c.v.p); break; - case F: - { // JDC: added this to get inline floats - unsigned temp; - - *(float *)&temp = p->u.c.v.d; - p->x.name = stringf("%U", temp ); - } - break;// JDC: added this - default: assert(0); - } - else if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("$%d", genlabel(1)); - else if (p->scope == LABELS || p->generated) - p->x.name = stringf("$%s", p->name); - else - p->x.name = p->name; -} - -static void dumptree(Node p) { - switch (specific(p->op)) { - case ASGN+B: - assert(p->kids[0]); - assert(p->kids[1]); - assert(p->syms[0]); - dumptree(p->kids[0]); - dumptree(p->kids[1]); - print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.u); - return; - case RET+V: - assert(!p->kids[0]); - assert(!p->kids[1]); - print("%s\n", opname(p->op)); - return; - } - switch (generic(p->op)) { - case CNST: case ADDRG: case ADDRF: case ADDRL: case LABEL: - assert(!p->kids[0]); - assert(!p->kids[1]); - assert(p->syms[0] && p->syms[0]->x.name); - print("%s %s\n", opname(p->op), p->syms[0]->x.name); - return; - case CVF: case CVI: case CVP: case CVU: - assert(p->kids[0]); - assert(!p->kids[1]); - assert(p->syms[0]); - dumptree(p->kids[0]); - print("%s %d\n", opname(p->op), p->syms[0]->u.c.v.i); - return; - case ARG: case BCOM: case NEG: case INDIR: case JUMP: case RET: - assert(p->kids[0]); - assert(!p->kids[1]); - dumptree(p->kids[0]); - print("%s\n", opname(p->op)); - return; - case CALL: - assert(p->kids[0]); - assert(!p->kids[1]); - assert(optype(p->op) != B); - dumptree(p->kids[0]); - print("%s\n", opname(p->op)); - if ( !p->count ) { printf("pop\n"); }; // JDC - return; - case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH: - case ADD: case SUB: case DIV: case MUL: case MOD: - assert(p->kids[0]); - assert(p->kids[1]); - dumptree(p->kids[0]); - dumptree(p->kids[1]); - print("%s\n", opname(p->op)); - return; - case EQ: case NE: case GT: case GE: case LE: case LT: - assert(p->kids[0]); - assert(p->kids[1]); - assert(p->syms[0]); - assert(p->syms[0]->x.name); - dumptree(p->kids[0]); - dumptree(p->kids[1]); - print("%s %s\n", opname(p->op), p->syms[0]->x.name); - return; - } - assert(0); -} - -static void I(emit)(Node p) { - for (; p; p = p->link) - dumptree(p); -} - -static void I(export)(Symbol p) { - print("export %s\n", p->x.name); -} - -static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int i; - - (*IR->segment)(CODE); - offset = 0; - for (i = 0; caller[i] && callee[i]; i++) { - offset = roundup(offset, caller[i]->type->align); - caller[i]->x.name = callee[i]->x.name = stringf("%d", offset); - caller[i]->x.offset = callee[i]->x.offset = offset; - offset += caller[i]->type->size; - } - maxargoffset = maxoffset = argoffset = offset = 0; - gencode(caller, callee); - print("proc %s %d %d\n", f->x.name, maxoffset, maxargoffset); - emitcode(); - print("endproc %s %d %d\n", f->x.name, maxoffset, maxargoffset); - -} - -static void gen02(Node p) { - assert(p); - if (generic(p->op) == ARG) { - assert(p->syms[0]); - argoffset += (p->syms[0]->u.c.v.i < 4 ? 4 : p->syms[0]->u.c.v.i); - } else if (generic(p->op) == CALL) { - maxargoffset = (argoffset > maxargoffset ? argoffset : maxargoffset); - argoffset = 0; - } -} - -static void gen01(Node p) { - if (p) { - gen01(p->kids[0]); - gen01(p->kids[1]); - gen02(p); - } -} - -static Node I(gen)(Node p) { - Node q; - - assert(p); - for (q = p; q; q = q->link) - gen01(q); - return p; -} - -static void I(global)(Symbol p) { - print("align %d\n", p->type->align > 4 ? 4 : p->type->align); - print("LABELV %s\n", p->x.name); -} - -static void I(import)(Symbol p) { - print("import %s\n", p->x.name); -} - -static void I(local)(Symbol p) { - offset = roundup(offset, p->type->align); - p->x.name = stringf("%d", offset); - p->x.offset = offset; - offset += p->type->size; -} - -static void I(progbeg)(int argc, char *argv[]) {} - -static void I(progend)(void) {} - -static void I(space)(int n) { - print("skip %d\n", n); -} - -//======================================================== - -// JDC: hacked up to get interleaved source lines in asm code -static char *sourceFile; -static char *sourcePtr; -static int sourceLine; - -static int filelength( FILE *f ) { - int pos; - int end; - - pos = ftell (f); - fseek (f, 0, SEEK_END); - end = ftell (f); - fseek (f, pos, SEEK_SET); - - return end; -} - -static void LoadSourceFile( const char *filename ) { - FILE *f; - int length; - - f = fopen( filename, "r" ); - if ( !f ) { - print( ";couldn't open %s\n", filename ); - sourceFile = NULL; - return; - } - length = filelength( f ); - sourceFile = malloc( length + 1 ); - if ( sourceFile ) { - fread( sourceFile, length, 1, f ); - sourceFile[length] = 0; - } - - fclose( f ); - sourceLine = 1; - sourcePtr = sourceFile; -} - -static void PrintToSourceLine( int line ) { - int c; - - if ( !sourceFile ) { - return; - } - while ( sourceLine <= line ) { - int i; - - for ( i = 0 ; sourcePtr[i] && sourcePtr[i] != '\n' ; i++ ) { - } - c = sourcePtr[i]; - if ( c == '\n' ) { - sourcePtr[i] = 0; - } - print( ";%d:%s\n", sourceLine, sourcePtr ); - if ( c == 0 ) { - sourcePtr += i; // end of file - } else { - sourcePtr += i+1; - } - sourceLine++; - } -} - -static void I(stabline)(Coordinate *cp) { - static char *prevfile; - static int prevline; - - if (cp->file && (prevfile == NULL || strcmp(prevfile, cp->file) != 0)) { - print("file \"%s\"\n", prevfile = cp->file); - prevline = 0; - if ( sourceFile ) { - free( sourceFile ); - sourceFile = NULL; - } - // load the new source file - LoadSourceFile( cp->file ); - } - if (cp->y != prevline) { - print("line %d\n", prevline = cp->y); - PrintToSourceLine( cp->y ); - } -} - -//======================================================== - -#define b_blockbeg blockbeg -#define b_blockend blockend - -Interface bytecodeIR = { - {1, 1, 0}, /* char */ - {2, 2, 0}, /* short */ - {4, 4, 0}, /* int */ - {4, 4, 0}, /* long */ - {4, 4, 0}, /* long long */ - {4, 4, 0}, /* float */ // JDC: use inline floats - {4, 4, 0}, /* double */ // JDC: don't ever emit 8 byte double code - {4, 4, 0}, /* long double */ // JDC: don't ever emit 8 byte double code - {4, 4, 0}, /* T* */ - {0, 4, 0}, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 0, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - I(address), - I(blockbeg), - I(blockend), - I(defaddress), - I(defconst), - I(defstring), - I(defsymbol), - I(emit), - I(export), - I(function), - I(gen), - I(global), - I(import), - I(local), - I(progbeg), - I(progend), - I(segment), - I(space), - 0, /* I(stabblock) */ - 0, /* I(stabend) */ - 0, /* I(stabfend) */ - 0, /* I(stabinit) */ - I(stabline), - 0, /* I(stabsym) */ - 0, /* I(stabtype) */ -}; diff --git a/lcc/src/c.h b/lcc/src/c.h deleted file mode 100644 index b46cf3b..0000000 --- a/lcc/src/c.h +++ /dev/null @@ -1,723 +0,0 @@ -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> -#include <string.h> - -#define NEW(p,a) ((p) = allocate(sizeof *(p), (a))) -#define NEW0(p,a) memset(NEW((p),(a)), 0, sizeof *(p)) -#define isaddrop(op) (specific(op)==ADDRG+P || specific(op)==ADDRL+P \ - || specific(op)==ADDRF+P) - -#define MAXLINE 512 -#define BUFSIZE 4096 - -#define istypename(t,tsym) (kind[t] == CHAR \ - || (t == ID && tsym && tsym->sclass == TYPEDEF)) -#define sizeop(n) ((n)<<10) -#define generic(op) ((op)&0x3F0) -#define specific(op) ((op)&0x3FF) -#define opindex(op) (((op)>>4)&0x3F) -#define opkind(op) ((op)&~0x3F0) -#define opsize(op) ((op)>>10) -#define optype(op) ((op)&0xF) -#ifdef __LCC__ -#ifndef __STDC__ -#define __STDC__ -#endif -#endif -#define NELEMS(a) ((int)(sizeof (a)/sizeof ((a)[0]))) -#undef roundup -#define roundup(x,n) (((x)+((n)-1))&(~((n)-1))) -#define mkop(op,ty) (specific((op) + ttob(ty))) - -#define extend(x,ty) ((x)&(1<<(8*(ty)->size-1)) ? (x)|((~0UL)<<(8*(ty)->size-1)) : (x)&ones(8*(ty)->size)) -#define ones(n) ((n)>=8*sizeof (unsigned long) ? ~0UL : ~((~0UL)<<(n))) - -#define isqual(t) ((t)->op >= CONST) -#define unqual(t) (isqual(t) ? (t)->type : (t)) - -#define isvolatile(t) ((t)->op == VOLATILE \ - || (t)->op == CONST+VOLATILE) -#define isconst(t) ((t)->op == CONST \ - || (t)->op == CONST+VOLATILE) -#define isarray(t) (unqual(t)->op == ARRAY) -#define isstruct(t) (unqual(t)->op == STRUCT \ - || unqual(t)->op == UNION) -#define isunion(t) (unqual(t)->op == UNION) -#define isfunc(t) (unqual(t)->op == FUNCTION) -#define isptr(t) (unqual(t)->op == POINTER) -#define ischar(t) ((t)->size == 1 && isint(t)) -#define isint(t) (unqual(t)->op == INT \ - || unqual(t)->op == UNSIGNED) -#define isfloat(t) (unqual(t)->op == FLOAT) -#define isarith(t) (unqual(t)->op <= UNSIGNED) -#define isunsigned(t) (unqual(t)->op == UNSIGNED) -#define isscalar(t) (unqual(t)->op <= POINTER \ - || unqual(t)->op == ENUM) -#define isenum(t) (unqual(t)->op == ENUM) -#define fieldsize(p) (p)->bitsize -#define fieldright(p) ((p)->lsb - 1) -#define fieldleft(p) (8*(p)->type->size - \ - fieldsize(p) - fieldright(p)) -#define fieldmask(p) (~(~(unsigned)0<<fieldsize(p))) -typedef struct node *Node; - -typedef struct list *List; - -typedef struct code *Code; - -typedef struct swtch *Swtch; - -typedef struct symbol *Symbol; - -typedef struct coord { - char *file; - unsigned x, y; -} Coordinate; -typedef struct table *Table; - -typedef union value { - long i; - unsigned long u; - long double d; - void *p; - void (*g)(void); -} Value; -typedef struct tree *Tree; - -typedef struct type *Type; - -typedef struct field *Field; - -typedef struct { - unsigned printed:1; - unsigned marked; - unsigned short typeno; - void *xt; -} Xtype; - -#include "config.h" -typedef struct metrics { - unsigned char size, align, outofline; -} Metrics; -typedef struct interface { - Metrics charmetric; - Metrics shortmetric; - Metrics intmetric; - Metrics longmetric; - Metrics longlongmetric; - Metrics floatmetric; - Metrics doublemetric; - Metrics longdoublemetric; - Metrics ptrmetric; - Metrics structmetric; - unsigned little_endian:1; - unsigned mulops_calls:1; - unsigned wants_callb:1; - unsigned wants_argb:1; - unsigned left_to_right:1; - unsigned wants_dag:1; - unsigned unsigned_char:1; -void (*address)(Symbol p, Symbol q, long n); -void (*blockbeg)(Env *); -void (*blockend)(Env *); -void (*defaddress)(Symbol); -void (*defconst) (int suffix, int size, Value v); -void (*defstring)(int n, char *s); -void (*defsymbol)(Symbol); -void (*emit) (Node); -void (*export)(Symbol); -void (*function)(Symbol, Symbol[], Symbol[], int); -Node (*gen) (Node); -void (*global)(Symbol); -void (*import)(Symbol); -void (*local)(Symbol); -void (*progbeg)(int argc, char *argv[]); -void (*progend)(void); -void (*segment)(int); -void (*space)(int); -void (*stabblock)(int, int, Symbol*); -void (*stabend) (Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -void (*stabfend) (Symbol, int); -void (*stabinit) (char *, int, char *[]); -void (*stabline) (Coordinate *); -void (*stabsym) (Symbol); -void (*stabtype) (Symbol); - Xinterface x; -} Interface; -typedef struct binding { - char *name; - Interface *ir; -} Binding; - -extern Binding bindings[]; -extern Interface *IR; -typedef struct { - List blockentry; - List blockexit; - List entry; - List exit; - List returns; - List points; - List calls; - List end; -} Events; - -enum { -#define xx(a,b,c,d,e,f,g) a=b, -#define yy(a,b,c,d,e,f,g) -#include "token.h" - LAST -}; -struct node { - short op; - short count; - Symbol syms[3]; - Node kids[2]; - Node link; - Xnode x; -}; -enum { - F=FLOAT, - I=INT, - U=UNSIGNED, - P=POINTER, - V=VOID, - B=STRUCT -}; -#define gop(name,value) name=value<<4, -#define op(name,type,sizes) - -enum { gop(CNST,1) - op(CNST,F,fdx) - op(CNST,I,csilh) - op(CNST,P,p) - op(CNST,U,csilh) - gop(ARG,2) - op(ARG,B,-) - op(ARG,F,fdx) - op(ARG,I,ilh) - op(ARG,P,p) - op(ARG,U,ilh) - gop(ASGN,3) - op(ASGN,B,-) - op(ASGN,F,fdx) - op(ASGN,I,csilh) - op(ASGN,P,p) - op(ASGN,U,csilh) - gop(INDIR,4) - op(INDIR,B,-) - op(INDIR,F,fdx) - op(INDIR,I,csilh) - op(INDIR,P,p) - op(INDIR,U,csilh) - gop(CVF,7) - op(CVF,F,fdx) - op(CVF,I,ilh) - gop(CVI,8) - op(CVI,F,fdx) - op(CVI,I,csilh) - op(CVI,U,csilhp) - gop(CVP,9) - op(CVP,U,p) - gop(CVU,11) - op(CVU,I,csilh) - op(CVU,P,p) - op(CVU,U,csilh) - gop(NEG,12) - op(NEG,F,fdx) - op(NEG,I,ilh) - gop(CALL,13) - op(CALL,B,-) - op(CALL,F,fdx) - op(CALL,I,ilh) - op(CALL,P,p) - op(CALL,U,ilh) - op(CALL,V,-) - gop(RET,15) - op(RET,F,fdx) - op(RET,I,ilh) - op(RET,P,p) - op(RET,U,ilh) - op(RET,V,-) - gop(ADDRG,16) - op(ADDRG,P,p) - gop(ADDRF,17) - op(ADDRF,P,p) - gop(ADDRL,18) - op(ADDRL,P,p) - gop(ADD,19) - op(ADD,F,fdx) - op(ADD,I,ilh) - op(ADD,P,p) - op(ADD,U,ilhp) - gop(SUB,20) - op(SUB,F,fdx) - op(SUB,I,ilh) - op(SUB,P,p) - op(SUB,U,ilhp) - gop(LSH,21) - op(LSH,I,ilh) - op(LSH,U,ilh) - gop(MOD,22) - op(MOD,I,ilh) - op(MOD,U,ilh) - gop(RSH,23) - op(RSH,I,ilh) - op(RSH,U,ilh) - gop(BAND,24) - op(BAND,I,ilh) - op(BAND,U,ilh) - gop(BCOM,25) - op(BCOM,I,ilh) - op(BCOM,U,ilh) - gop(BOR,26) - op(BOR,I,ilh) - op(BOR,U,ilh) - gop(BXOR,27) - op(BXOR,I,ilh) - op(BXOR,U,ilh) - gop(DIV,28) - op(DIV,F,fdx) - op(DIV,I,ilh) - op(DIV,U,ilh) - gop(MUL,29) - op(MUL,F,fdx) - op(MUL,I,ilh) - op(MUL,U,ilh) - gop(EQ,30) - op(EQ,F,fdx) - op(EQ,I,ilh) - op(EQ,U,ilhp) - gop(GE,31) - op(GE,F,fdx) - op(GE,I,ilh) - op(GE,U,ilhp) - gop(GT,32) - op(GT,F,fdx) - op(GT,I,ilh) - op(GT,U,ilhp) - gop(LE,33) - op(LE,F,fdx) - op(LE,I,ilh) - op(LE,U,ilhp) - gop(LT,34) - op(LT,F,fdx) - op(LT,I,ilh) - op(LT,U,ilhp) - gop(NE,35) - op(NE,F,fdx) - op(NE,I,ilh) - op(NE,U,ilhp) - gop(JUMP,36) - op(JUMP,V,-) - gop(LABEL,37) - op(LABEL,V,-) - gop(LOAD,14) - op(LOAD,B,-) - op(LOAD,F,fdx) - op(LOAD,I,csilh) - op(LOAD,P,p) - op(LOAD,U,csilhp) LASTOP }; - -#undef gop -#undef op -enum { CODE=1, BSS, DATA, LIT }; -enum { PERM=0, FUNC, STMT }; -struct list { - void *x; - List link; -}; - -struct code { - enum { Blockbeg, Blockend, Local, Address, Defpoint, - Label, Start, Gen, Jump, Switch - } kind; - Code prev, next; - union { - struct { - int level; - Symbol *locals; - Table identifiers, types; - Env x; - } block; - Code begin; - Symbol var; - - struct { - Symbol sym; - Symbol base; - long offset; - } addr; - struct { - Coordinate src; - int point; - } point; - Node forest; - struct { - Symbol sym; - Symbol table; - Symbol deflab; - int size; - long *values; - Symbol *labels; - } swtch; - - } u; -}; -struct swtch { - Symbol sym; - int lab; - Symbol deflab; - int ncases; - int size; - long *values; - Symbol *labels; -}; -struct symbol { - char *name; - int scope; - Coordinate src; - Symbol up; - List uses; - int sclass; - unsigned structarg:1; - - unsigned addressed:1; - unsigned computed:1; - unsigned temporary:1; - unsigned generated:1; - unsigned defined:1; - Type type; - float ref; - union { - struct { - int label; - Symbol equatedto; - } l; - struct { - unsigned cfields:1; - unsigned vfields:1; - Table ftab; /* omit */ - Field flist; - } s; - int value; - Symbol *idlist; - struct { - Value min, max; - } limits; - struct { - Value v; - Symbol loc; - } c; - struct { - Coordinate pt; - int label; - int ncalls; - Symbol *callee; - } f; - int seg; - Symbol alias; - struct { - Node cse; - int replace; - Symbol next; - } t; - } u; - Xsymbol x; -}; -enum { CONSTANTS=1, LABELS, GLOBAL, PARAM, LOCAL }; -struct tree { - int op; - Type type; - Tree kids[2]; - Node node; - union { - Value v; - Symbol sym; - - Field field; - } u; -}; -enum { - AND=38<<4, - NOT=39<<4, - OR=40<<4, - COND=41<<4, - RIGHT=42<<4, - FIELD=43<<4 -}; -struct type { - int op; - Type type; - int align; - int size; - union { - Symbol sym; - struct { - unsigned oldstyle:1; - Type *proto; - } f; - } u; - Xtype x; -}; -struct field { - char *name; - Type type; - int offset; - short bitsize; - short lsb; - Field link; -}; -extern int assignargs; -extern int prunetemps; -extern int nodecount; -extern Symbol cfunc; -extern Symbol retv; -extern Tree (*optree[])(int, Tree, Tree); - -extern char kind[]; -extern int errcnt; -extern int errlimit; -extern int wflag; -extern Events events; -extern float refinc; - -extern unsigned char *cp; -extern unsigned char *limit; -extern char *firstfile; -extern char *file; -extern char *line; -extern int lineno; -extern int t; -extern char *token; -extern Symbol tsym; -extern Coordinate src; -extern int Aflag; -extern int Pflag; -extern Symbol YYnull; -extern Symbol YYcheck; -extern int glevel; -extern int xref; - -extern int ncalled; -extern int npoints; - -extern int needconst; -extern int explicitCast; -extern struct code codehead; -extern Code codelist; -extern Table stmtlabs; -extern float density; -extern Table constants; -extern Table externals; -extern Table globals; -extern Table identifiers; -extern Table labels; -extern Table types; -extern int level; - -extern List loci, symbols; - -extern List symbols; - -extern int where; -extern Type chartype; -extern Type doubletype; -extern Type floattype; -extern Type inttype; -extern Type longdouble; -extern Type longtype; -extern Type longlong; -extern Type shorttype; -extern Type signedchar; -extern Type unsignedchar; -extern Type unsignedlonglong; -extern Type unsignedlong; -extern Type unsignedshort; -extern Type unsignedtype; -extern Type charptype; -extern Type funcptype; -extern Type voidptype; -extern Type voidtype; -extern Type unsignedptr; -extern Type signedptr; -extern Type widechar; -extern void *allocate(unsigned long n, unsigned a); -extern void deallocate(unsigned a); -extern void *newarray(unsigned long m, unsigned long n, unsigned a); -extern void walk(Tree e, int tlab, int flab); -extern Node listnodes(Tree e, int tlab, int flab); -extern Node newnode(int op, Node left, Node right, Symbol p); -extern Tree cvtconst(Tree); -extern void printdag(Node, int); -extern void compound(int, Swtch, int); -extern void defglobal(Symbol, int); -extern void finalize(void); -extern void program(void); - -extern Tree vcall(Symbol func, Type ty, ...); -extern Tree addrof(Tree); -extern Tree asgn(Symbol, Tree); -extern Tree asgntree(int, Tree, Tree); -extern Type assign(Type, Tree); -extern Tree bittree(int, Tree, Tree); -extern Tree call(Tree, Type, Coordinate); -extern Tree calltree(Tree, Type, Tree, Symbol); -extern Tree condtree(Tree, Tree, Tree); -extern Tree cnsttree(Type, ...); -extern Tree consttree(unsigned int, Type); -extern Tree eqtree(int, Tree, Tree); -extern int iscallb(Tree); -extern Tree shtree(int, Tree, Tree); -extern void typeerror(int, Tree, Tree); - -extern void test(int tok, char set[]); -extern void expect(int tok); -extern void skipto(int tok, char set[]); -extern void error(const char *, ...); -extern int fatal(const char *, const char *, int); -extern void warning(const char *, ...); - -typedef void (*Apply)(void *, void *, void *); -extern void attach(Apply, void *, List *); -extern void apply(List event, void *arg1, void *arg2); -extern Tree retype(Tree p, Type ty); -extern Tree rightkid(Tree p); -extern int hascall(Tree p); -extern Type binary(Type, Type); -extern Tree cast(Tree, Type); -extern Tree cond(Tree); -extern Tree expr0(int); -extern Tree expr(int); -extern Tree expr1(int); -extern Tree field(Tree, const char *); -extern char *funcname(Tree); -extern Tree idtree(Symbol); -extern Tree incr(int, Tree, Tree); -extern Tree lvalue(Tree); -extern Tree nullcall(Type, Symbol, Tree, Tree); -extern Tree pointer(Tree); -extern Tree rvalue(Tree); -extern Tree value(Tree); - -extern void defpointer(Symbol); -extern Type initializer(Type, int); -extern void swtoseg(int); - -extern void input_init(int, char *[]); -extern void fillbuf(void); -extern void nextline(void); - -extern int getchr(void); -extern int gettok(void); - -extern void emitcode(void); -extern void gencode (Symbol[], Symbol[]); -extern void fprint(FILE *f, const char *fmt, ...); -extern char *stringf(const char *, ...); -extern void check(Node); -extern void print(const char *, ...); - -extern List append(void *x, List list); -extern int length(List list); -extern void *ltov (List *list, unsigned a); -extern void init(int, char *[]); - -extern Type typename(void); -extern void checklab(Symbol p, void *cl); -extern Type enumdcl(void); -extern void main_init(int, char *[]); -extern int main(int, char *[]); - -extern void vfprint(FILE *, char *, const char *, va_list); - -extern int process(char *); -extern int findfunc(char *, char *); -extern int findcount(char *, int, int); - -extern Tree constexpr(int); -extern int intexpr(int, int); -extern Tree simplify(int, Type, Tree, Tree); -extern int ispow2(unsigned long u); - -extern int reachable(int); - -extern void addlocal(Symbol); -extern void branch(int); -extern Code code(int); -extern void definelab(int); -extern void definept(Coordinate *); -extern void equatelab(Symbol, Symbol); -extern Node jump(int); -extern void retcode(Tree); -extern void statement(int, Swtch, int); -extern void swcode(Swtch, int *, int, int); -extern void swgen(Swtch); - -extern char * string(const char *str); -extern char *stringn(const char *str, int len); -extern char *stringd(long n); -extern Symbol relocate(const char *name, Table src, Table dst); -extern void use(Symbol p, Coordinate src); -extern void locus(Table tp, Coordinate *cp); -extern Symbol allsymbols(Table); - -extern Symbol constant(Type, Value); -extern void enterscope(void); -extern void exitscope(void); -extern Symbol findlabel(int); -extern Symbol findtype(Type); -extern void foreach(Table, int, void (*)(Symbol, void *), void *); -extern Symbol genident(int, Type, int); -extern int genlabel(int); -extern Symbol install(const char *, Table *, int, int); -extern Symbol intconst(int); -extern Symbol lookup(const char *, Table); -extern Symbol mkstr(char *); -extern Symbol mksymbol(int, const char *, Type); -extern Symbol newtemp(int, int, int); -extern Table table(Table, int); -extern Symbol temporary(int, Type); -extern char *vtoa(Type, Value); - -extern int nodeid(Tree); -extern char *opname(int); -extern int *printed(int); -extern void printtree(Tree, int); -extern Tree root(Tree); -extern Tree texpr(Tree (*)(int), int, int); -extern Tree tree(int, Type, Tree, Tree); - -extern void type_init(int, char *[]); - -extern Type signedint(Type); - -extern int hasproto(Type); -extern void outtype(Type, FILE *); -extern void printdecl (Symbol p, Type ty); -extern void printproto(Symbol p, Symbol args[]); -extern char *typestring(Type ty, char *id); -extern Field fieldref(const char *name, Type ty); -extern Type array(Type, int, int); -extern Type atop(Type); -extern Type btot(int, int); -extern Type compose(Type, Type); -extern Type deref(Type); -extern int eqtype(Type, Type, int); -extern Field fieldlist(Type); -extern Type freturn(Type); -extern Type ftype(Type, Type); -extern Type func(Type, Type *, int); -extern Field newfield(char *, Type, Type); -extern Type newstruct(int, char *); -extern void printtype(Type, int); -extern Type promote(Type); -extern Type ptr(Type); -extern Type qual(int, Type); -extern void rmtypes(int); -extern int ttob(Type); -extern int variadic(Type); - diff --git a/lcc/src/config.h b/lcc/src/config.h deleted file mode 100644 index 6f0d5a6..0000000 --- a/lcc/src/config.h +++ /dev/null @@ -1,102 +0,0 @@ -typedef struct { - unsigned char max_unaligned_load; - Symbol (*rmap)(int); - - void (*blkfetch)(int size, int off, int reg, int tmp); - void (*blkstore)(int size, int off, int reg, int tmp); - void (*blkloop)(int dreg, int doff, - int sreg, int soff, - int size, int tmps[]); - void (*_label)(Node); - int (*_rule)(void*, int); - short **_nts; - void (*_kids)(Node, int, Node*); - char **_string; - char **_templates; - char *_isinstruction; - char **_ntname; - void (*emit2)(Node); - void (*doarg)(Node); - void (*target)(Node); - void (*clobber)(Node); -} Xinterface; -extern int askregvar(Symbol, Symbol); -extern void blkcopy(int, int, int, int, int, int[]); -extern int getregnum(Node); -extern int mayrecalc(Node); -extern int mkactual(int, int); -extern void mkauto(Symbol); -extern Symbol mkreg(char *, int, int, int); -extern Symbol mkwildcard(Symbol *); -extern int move(Node); -extern int notarget(Node); -extern void parseflags(int, char **); -extern int range(Node, int, int); -extern unsigned regloc(Symbol); /* omit */ -extern void rtarget(Node, int, Symbol); -extern void setreg(Node, Symbol); -extern void spill(unsigned, int, Node); -extern int widens(Node); - -extern int argoffset, maxargoffset; -extern int bflag, dflag; -extern int dalign, salign; -extern int framesize; -extern unsigned freemask[], usedmask[]; -extern int offset, maxoffset; -extern int swap; -extern unsigned tmask[], vmask[]; -typedef struct { - unsigned listed:1; - unsigned registered:1; - unsigned emitted:1; - unsigned copy:1; - unsigned equatable:1; - unsigned spills:1; - unsigned mayrecalc:1; - void *state; - short inst; - Node kids[3]; - Node prev, next; - Node prevuse; - short argno; -} Xnode; -typedef struct { - Symbol vbl; - short set; - short number; - unsigned mask; -} *Regnode; -enum { IREG=0, FREG=1 }; -typedef struct { - char *name; - unsigned int eaddr; /* omit */ - int offset; - Node lastuse; - int usecount; - Regnode regnode; - Symbol *wildcard; -} Xsymbol; -enum { RX=2 }; -typedef struct { - int offset; - unsigned freemask[2]; -} Env; - -#define LBURG_MAX SHRT_MAX - -enum { VREG=(44<<4) }; - -/* Exported for the front end */ -extern void blockbeg(Env *); -extern void blockend(Env *); -extern void emit(Node); -extern Node gen(Node); - -extern unsigned emitbin(Node, int); - -#ifdef NDEBUG -#define debug(x) (void)0 -#else -#define debug(x) (void)(dflag&&((x),0)) -#endif diff --git a/lcc/src/dag.c b/lcc/src/dag.c deleted file mode 100644 index 420cbe7..0000000 --- a/lcc/src/dag.c +++ /dev/null @@ -1,736 +0,0 @@ -#include "c.h" - - -#define iscall(op) (generic(op) == CALL \ - || (IR->mulops_calls \ - && (generic(op)==DIV||generic(op)==MOD||generic(op)==MUL) \ - && ( optype(op)==U || optype(op)==I))) -static Node forest; -static struct dag { - struct node node; - struct dag *hlink; -} *buckets[16]; -int nodecount; -static Tree firstarg; -int assignargs = 1; -int prunetemps = -1; -static Node *tail; - -static int depth = 0; -static Node replace(Node); -static Node prune(Node); -static Node asgnnode(Symbol, Node); -static struct dag *dagnode(int, Node, Node, Symbol); -static Symbol equated(Symbol); -static void fixup(Node); -static void labelnode(int); -static void list(Node); -static void kill(Symbol); -static Node node(int, Node, Node, Symbol); -static void printdag1(Node, int, int); -static void printnode(Node, int, int); -static void reset(void); -static Node tmpnode(Node); -static void typestab(Symbol, void *); -static Node undag(Node); -static Node visit(Node, int); -static void unlist(void); -void walk(Tree tp, int tlab, int flab) { - listnodes(tp, tlab, flab); - if (forest) { - Node list = forest->link; - forest->link = NULL; - if (!IR->wants_dag) - list = undag(list); - code(Gen)->u.forest = list; - forest = NULL; - } - reset(); - deallocate(STMT); -} - -static Node node(int op, Node l, Node r, Symbol sym) { - int i; - struct dag *p; - - i = (opindex(op)^((unsigned long)sym>>2))&(NELEMS(buckets)-1); - for (p = buckets[i]; p; p = p->hlink) - if (p->node.op == op && p->node.syms[0] == sym - && p->node.kids[0] == l && p->node.kids[1] == r) - return &p->node; - p = dagnode(op, l, r, sym); - p->hlink = buckets[i]; - buckets[i] = p; - ++nodecount; - return &p->node; -} -static struct dag *dagnode(int op, Node l, Node r, Symbol sym) { - struct dag *p; - - NEW0(p, FUNC); - p->node.op = op; - if ((p->node.kids[0] = l) != NULL) - ++l->count; - if ((p->node.kids[1] = r) != NULL) - ++r->count; - p->node.syms[0] = sym; - return p; -} -Node newnode(int op, Node l, Node r, Symbol sym) { - return &dagnode(op, l, r, sym)->node; -} -static void kill(Symbol p) { - int i; - struct dag **q; - - for (i = 0; i < NELEMS(buckets); i++) - for (q = &buckets[i]; *q; ) - if (generic((*q)->node.op) == INDIR && - (!isaddrop((*q)->node.kids[0]->op) - || (*q)->node.kids[0]->syms[0] == p)) { - *q = (*q)->hlink; - --nodecount; - } else - q = &(*q)->hlink; -} -static void reset(void) { - if (nodecount > 0) - memset(buckets, 0, sizeof buckets); - nodecount = 0; -} -Node listnodes(Tree tp, int tlab, int flab) { - Node p = NULL, l, r; - int op; - - assert(tlab || flab || (tlab == 0 && flab == 0)); - if (tp == NULL) - return NULL; - if (tp->node) - return tp->node; - op = tp->op + sizeop(tp->type->size); - switch (generic(tp->op)) { - case AND: { if (depth++ == 0) reset(); - if (flab) { - listnodes(tp->kids[0], 0, flab); - listnodes(tp->kids[1], 0, flab); - } else { - listnodes(tp->kids[0], 0, flab = genlabel(1)); - listnodes(tp->kids[1], tlab, 0); - labelnode(flab); - } - depth--; } break; - case OR: { if (depth++ == 0) - reset(); - if (tlab) { - listnodes(tp->kids[0], tlab, 0); - listnodes(tp->kids[1], tlab, 0); - } else { - tlab = genlabel(1); - listnodes(tp->kids[0], tlab, 0); - listnodes(tp->kids[1], 0, flab); - labelnode(tlab); - } - depth--; - } break; - case NOT: { return listnodes(tp->kids[0], flab, tlab); } - case COND: { Tree q = tp->kids[1]; - assert(tlab == 0 && flab == 0); - if (tp->u.sym) - addlocal(tp->u.sym); - flab = genlabel(2); - listnodes(tp->kids[0], 0, flab); - assert(q && q->op == RIGHT); - reset(); - listnodes(q->kids[0], 0, 0); - if (forest->op == LABEL+V) { - equatelab(forest->syms[0], findlabel(flab + 1)); - unlist(); - } - list(jump(flab + 1)); - labelnode(flab); - listnodes(q->kids[1], 0, 0); - if (forest->op == LABEL+V) { - equatelab(forest->syms[0], findlabel(flab + 1)); - unlist(); - } - labelnode(flab + 1); - - if (tp->u.sym) - p = listnodes(idtree(tp->u.sym), 0, 0); } break; - case CNST: { Type ty = unqual(tp->type); - assert(ty->u.sym); - if (tlab || flab) { - assert(ty == inttype); - if (tlab && tp->u.v.i != 0) - list(jump(tlab)); - else if (flab && tp->u.v.i == 0) - list(jump(flab)); - } - else if (ty->u.sym->addressed) - p = listnodes(cvtconst(tp), 0, 0); - else - p = node(op, NULL, NULL, constant(ty, tp->u.v)); } break; - case RIGHT: { if ( tp->kids[0] && tp->kids[1] - && generic(tp->kids[1]->op) == ASGN - && ((generic(tp->kids[0]->op) == INDIR - && tp->kids[0]->kids[0] == tp->kids[1]->kids[0]) - || (tp->kids[0]->op == FIELD - && tp->kids[0] == tp->kids[1]->kids[0]))) { - assert(tlab == 0 && flab == 0); - if (generic(tp->kids[0]->op) == INDIR) { - p = listnodes(tp->kids[0], 0, 0); - list(p); - listnodes(tp->kids[1], 0, 0); - } - else { - assert(generic(tp->kids[0]->kids[0]->op) == INDIR); - list(listnodes(tp->kids[0]->kids[0], 0, 0)); - p = listnodes(tp->kids[0], 0, 0); - listnodes(tp->kids[1], 0, 0); - } - } else if (tp->kids[1]) { - listnodes(tp->kids[0], 0, 0); - p = listnodes(tp->kids[1], tlab, flab); - } else - p = listnodes(tp->kids[0], tlab, flab); } break; - case JUMP: { assert(tlab == 0 && flab == 0); - assert(tp->u.sym == 0); - assert(tp->kids[0]); - l = listnodes(tp->kids[0], 0, 0); - list(newnode(JUMP+V, l, NULL, NULL)); - reset(); } break; - case CALL: { Tree save = firstarg; - firstarg = NULL; - assert(tlab == 0 && flab == 0); - if (tp->op == CALL+B && !IR->wants_callb) { - Tree arg0 = tree(ARG+P, tp->kids[1]->type, - tp->kids[1], NULL); - if (IR->left_to_right) - firstarg = arg0; - l = listnodes(tp->kids[0], 0, 0); - if (!IR->left_to_right || firstarg) { - firstarg = NULL; - listnodes(arg0, 0, 0); - } - p = newnode(CALL+V, l, NULL, NULL); - } else { - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = newnode(tp->op == CALL+B ? tp->op : op, l, r, NULL); - } - NEW0(p->syms[0], FUNC); - assert(isptr(tp->kids[0]->type)); - assert(isfunc(tp->kids[0]->type->type)); - p->syms[0]->type = tp->kids[0]->type->type; - list(p); - reset(); - cfunc->u.f.ncalls++; - firstarg = save; - } break; - case ARG: { assert(tlab == 0 && flab == 0); - if (IR->left_to_right) - listnodes(tp->kids[1], 0, 0); - if (firstarg) { - Tree arg = firstarg; - firstarg = NULL; - listnodes(arg, 0, 0); - } - l = listnodes(tp->kids[0], 0, 0); - list(newnode(tp->op == ARG+B ? tp->op : op, l, NULL, NULL)); - forest->syms[0] = intconst(tp->type->size); - forest->syms[1] = intconst(tp->type->align); - if (!IR->left_to_right) - listnodes(tp->kids[1], 0, 0); } break; - case EQ: case NE: case GT: case GE: case LE: - case LT: { assert(tp->u.sym == 0); - assert(errcnt || tlab || flab); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - assert(errcnt || opkind(l->op) == opkind(r->op)); - assert(errcnt || optype(op) == optype(l->op)); - if (tlab) - assert(flab == 0), - list(newnode(generic(tp->op) + opkind(l->op), l, r, findlabel(tlab))); - else if (flab) { - switch (generic(tp->op)) { - case EQ: op = NE; break; - case NE: op = EQ; break; - case GT: op = LE; break; - case LT: op = GE; break; - case GE: op = LT; break; - case LE: op = GT; break; - default: assert(0); - } - list(newnode(op + opkind(l->op), l, r, findlabel(flab))); - } - if (forest && forest->syms[0]) - forest->syms[0]->ref++; } break; - case ASGN: { assert(tlab == 0 && flab == 0); - if (tp->kids[0]->op == FIELD) { - Tree x = tp->kids[0]->kids[0]; - Field f = tp->kids[0]->u.field; - assert(generic(x->op) == INDIR); - reset(); - l = listnodes(lvalue(x), 0, 0); - if (fieldsize(f) < 8*f->type->size) { - unsigned int fmask = fieldmask(f); - unsigned int mask = fmask<<fieldright(f); - Tree q = tp->kids[1]; - if ((q->op == CNST+I && q->u.v.i == 0) - || (q->op == CNST+U && q->u.v.u == 0)) - q = bittree(BAND, x, cnsttree(unsignedtype, (unsigned long)~mask)); - else if ((q->op == CNST+I && (q->u.v.i&fmask) == fmask) - || (q->op == CNST+U && (q->u.v.u&fmask) == fmask)) - q = bittree(BOR, x, cnsttree(unsignedtype, (unsigned long)mask)); - else { - listnodes(q, 0, 0); - q = bittree(BOR, - bittree(BAND, rvalue(lvalue(x)), - cnsttree(unsignedtype, (unsigned long)~mask)), - bittree(BAND, shtree(LSH, cast(q, unsignedtype), - cnsttree(unsignedtype, (unsigned long)fieldright(f))), - cnsttree(unsignedtype, (unsigned long)mask))); - } - r = listnodes(q, 0, 0); - op = ASGN + ttob(q->type); - } else { - r = listnodes(tp->kids[1], 0, 0); - op = ASGN + ttob(tp->kids[1]->type); - } - } else { - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - } - list(newnode(tp->op == ASGN+B ? tp->op : op, l, r, NULL)); - forest->syms[0] = intconst(tp->kids[1]->type->size); - forest->syms[1] = intconst(tp->kids[1]->type->align); - if (isaddrop(tp->kids[0]->op) - && !tp->kids[0]->u.sym->computed) - kill(tp->kids[0]->u.sym); - else - reset(); - p = listnodes(tp->kids[1], 0, 0); } break; - case BOR: case BAND: case BXOR: - case ADD: case SUB: case RSH: - case LSH: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = node(op, l, r, NULL); } break; - case DIV: case MUL: - case MOD: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - r = listnodes(tp->kids[1], 0, 0); - p = node(op, l, r, NULL); - if (IR->mulops_calls && isint(tp->type)) { - list(p); - cfunc->u.f.ncalls++; - } } break; - case RET: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - list(newnode(op, l, NULL, NULL)); } break; - case CVF: case CVI: case CVP: - case CVU: { assert(tlab == 0 && flab == 0); - assert(optype(tp->kids[0]->op) != optype(tp->op) || tp->kids[0]->type->size != tp->type->size); - l = listnodes(tp->kids[0], 0, 0); - p = node(op, l, NULL, intconst(tp->kids[0]->type->size)); - } break; - case BCOM: - case NEG: { assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - p = node(op, l, NULL, NULL); } break; - case INDIR: { Type ty = tp->kids[0]->type; - assert(tlab == 0 && flab == 0); - l = listnodes(tp->kids[0], 0, 0); - if (isptr(ty)) - ty = unqual(ty)->type; - if (isvolatile(ty) - || (isstruct(ty) && unqual(ty)->u.sym->u.s.vfields)) - p = newnode(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); - else - p = node(tp->op == INDIR+B ? tp->op : op, l, NULL, NULL); } break; - case FIELD: { Tree q = tp->kids[0]; - if (tp->type == inttype) { - long n = fieldleft(tp->u.field); - q = shtree(RSH, - shtree(LSH, q, cnsttree(inttype, n)), - cnsttree(inttype, n + fieldright(tp->u.field))); - } else if (fieldsize(tp->u.field) < 8*tp->u.field->type->size) - q = bittree(BAND, - shtree(RSH, q, cnsttree(inttype, (long)fieldright(tp->u.field))), - cnsttree(unsignedtype, (unsigned long)fieldmask(tp->u.field))); - assert(tlab == 0 && flab == 0); - p = listnodes(q, 0, 0); } break; - case ADDRG: - case ADDRF: { assert(tlab == 0 && flab == 0); - p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); - } break; - case ADDRL: { assert(tlab == 0 && flab == 0); - if (tp->u.sym->temporary) - addlocal(tp->u.sym); - p = node(tp->op + sizeop(voidptype->size), NULL, NULL, tp->u.sym); } break; - default:assert(0); - } - tp->node = p; - return p; -} -static void list(Node p) { - if (p && p->link == NULL) { - if (forest) { - p->link = forest->link; - forest->link = p; - } else - p->link = p; - forest = p; - } -} -static void labelnode(int lab) { - assert(lab); - if (forest && forest->op == LABEL+V) - equatelab(findlabel(lab), forest->syms[0]); - else - list(newnode(LABEL+V, NULL, NULL, findlabel(lab))); - reset(); -} -static void unlist(void) { - Node p; - - assert(forest); - assert(forest != forest->link); - p = forest->link; - while (p->link != forest) - p = p->link; - p->link = forest->link; - forest = p; -} -Tree cvtconst(Tree p) { - Symbol q = constant(p->type, p->u.v); - Tree e; - - if (q->u.c.loc == NULL) - q->u.c.loc = genident(STATIC, p->type, GLOBAL); - if (isarray(p->type)) { - e = simplify(ADDRG, atop(p->type), NULL, NULL); - e->u.sym = q->u.c.loc; - } else - e = idtree(q->u.c.loc); - return e; -} -void gencode(Symbol caller[], Symbol callee[]) { - Code cp; - Coordinate save; - - if (prunetemps == -1) - prunetemps = !IR->wants_dag; - save = src; - if (assignargs) { - int i; - Symbol p, q; - cp = codehead.next->next; - codelist = codehead.next; - for (i = 0; (p = callee[i]) != NULL - && (q = caller[i]) != NULL; i++) - if (p->sclass != q->sclass || p->type != q->type) - walk(asgn(p, idtree(q)), 0, 0); - codelist->next = cp; - cp->prev = codelist; - } - if (glevel && IR->stabsym) { - int i; - Symbol p, q; - for (i = 0; (p = callee[i]) != NULL - && (q = caller[i]) != NULL; i++) { - (*IR->stabsym)(p); - if (p->sclass != q->sclass || p->type != q->type) - (*IR->stabsym)(q); - } - swtoseg(CODE); - } - cp = codehead.next; - for ( ; errcnt <= 0 && cp; cp = cp->next) - switch (cp->kind) { - case Address: (*IR->address)(cp->u.addr.sym, cp->u.addr.base, - cp->u.addr.offset); break; - case Blockbeg: { - Symbol *p = cp->u.block.locals; - (*IR->blockbeg)(&cp->u.block.x); - for ( ; *p; p++) - if ((*p)->ref != 0.0) - (*IR->local)(*p); - else if (glevel) (*IR->local)(*p); - } - break; - case Blockend: (*IR->blockend)(&cp->u.begin->u.block.x); break; - case Defpoint: src = cp->u.point.src; break; - case Gen: case Jump: - case Label: if (prunetemps) - cp->u.forest = prune(cp->u.forest); - fixup(cp->u.forest); - cp->u.forest = (*IR->gen)(cp->u.forest); break; - case Local: (*IR->local)(cp->u.var); break; - case Switch: break; - default: assert(0); - } - src = save; -} -static void fixup(Node p) { - for ( ; p; p = p->link) - switch (generic(p->op)) { - case JUMP: - if (specific(p->kids[0]->op) == ADDRG+P) - p->kids[0]->syms[0] = - equated(p->kids[0]->syms[0]); - break; - case LABEL: assert(p->syms[0] == equated(p->syms[0])); break; - case EQ: case GE: case GT: case LE: case LT: case NE: - assert(p->syms[0]); - p->syms[0] = equated(p->syms[0]); - } -} -static Symbol equated(Symbol p) { - { Symbol q; for (q = p->u.l.equatedto; q; q = q->u.l.equatedto) assert(p != q); } - while (p->u.l.equatedto) - p = p->u.l.equatedto; - return p; -} -void emitcode(void) { - Code cp; - Coordinate save; - - save = src; - cp = codehead.next; - for ( ; errcnt <= 0 && cp; cp = cp->next) - switch (cp->kind) { - case Address: break; - case Blockbeg: if (glevel && IR->stabblock) { - (*IR->stabblock)('{', cp->u.block.level - LOCAL, cp->u.block.locals); - swtoseg(CODE); - } - break; - case Blockend: if (glevel && IR->stabblock) { - Code bp = cp->u.begin; - foreach(bp->u.block.identifiers, bp->u.block.level, typestab, NULL); - foreach(bp->u.block.types, bp->u.block.level, typestab, NULL); - (*IR->stabblock)('}', bp->u.block.level - LOCAL, bp->u.block.locals); - swtoseg(CODE); - } - break; - case Defpoint: src = cp->u.point.src; - if (glevel > 0 && IR->stabline) { - (*IR->stabline)(&cp->u.point.src); swtoseg(CODE); } break; - case Gen: case Jump: - case Label: if (cp->u.forest) - (*IR->emit)(cp->u.forest); break; - case Local: if (glevel && IR->stabsym) { - (*IR->stabsym)(cp->u.var); - swtoseg(CODE); - } break; - case Switch: { int i; - defglobal(cp->u.swtch.table, LIT); - (*IR->defaddress)(equated(cp->u.swtch.labels[0])); - for (i = 1; i < cp->u.swtch.size; i++) { - long k = cp->u.swtch.values[i-1]; - while (++k < cp->u.swtch.values[i]) - assert(k < LONG_MAX), - (*IR->defaddress)(equated(cp->u.swtch.deflab)); - (*IR->defaddress)(equated(cp->u.swtch.labels[i])); - } - swtoseg(CODE); - } break; - default: assert(0); - } - src = save; -} - -static Node undag(Node forest) { - Node p; - - tail = &forest; - for (p = forest; p; p = p->link) - if (generic(p->op) == INDIR) { - assert(p->count >= 1); - visit(p, 1); - if (p->syms[2]) { - assert(p->syms[2]->u.t.cse); - p->syms[2]->u.t.cse = NULL; - addlocal(p->syms[2]); - } - } else if (iscall(p->op) && p->count >= 1) - visit(p, 1); - else { - assert(p->count == 0), - visit(p, 1); - *tail = p; - tail = &p->link; - } - *tail = NULL; - return forest; -} -static Node replace(Node p) { - if (p && ( generic(p->op) == INDIR - && generic(p->kids[0]->op) == ADDRL - && p->kids[0]->syms[0]->temporary - && p->kids[0]->syms[0]->u.t.replace)) { - p = p->kids[0]->syms[0]->u.t.cse; - if (generic(p->op) == INDIR && isaddrop(p->kids[0]->op)) - p = newnode(p->op, newnode(p->kids[0]->op, NULL, NULL, - p->kids[0]->syms[0]), NULL, NULL); - else if (generic(p->op) == ADDRG) - p = newnode(p->op, NULL, NULL, p->syms[0]); - else - assert(0); - p->count = 1; - } else if (p) { - p->kids[0] = replace(p->kids[0]); - p->kids[1] = replace(p->kids[1]); - } - return p; -} -static Node prune(Node forest) { - Node p, *tail = &forest; - int count = 0; - - for (p = forest; p; p = p->link) { - if (count > 0) { - p->kids[0] = replace(p->kids[0]); - p->kids[1] = replace(p->kids[1]); - } - if (( generic(p->op) == ASGN - && generic(p->kids[0]->op) == ADDRL - && p->kids[0]->syms[0]->temporary - && p->kids[0]->syms[0]->u.t.cse == p->kids[1])) { - Symbol tmp = p->kids[0]->syms[0]; - if (!tmp->defined) - (*IR->local)(tmp); - tmp->defined = 1; - if (( generic(p->kids[1]->op) == INDIR - && isaddrop(p->kids[1]->kids[0]->op) - && p->kids[1]->kids[0]->syms[0]->sclass == REGISTER) - || (( generic(p->kids[1]->op) == INDIR - && isaddrop(p->kids[1]->kids[0]->op)) && tmp->sclass == AUTO) - || (generic(p->kids[1]->op) == ADDRG && tmp->sclass == AUTO)) { - tmp->u.t.replace = 1; - count++; - continue; /* and omit the assignment */ - } - } - /* keep the assignment and other roots */ - *tail = p; - tail = &(*tail)->link; - } - assert(*tail == NULL); - return forest; -} -static Node visit(Node p, int listed) { - if (p) { - if (p->syms[2]) - p = tmpnode(p); - else if ((p->count <= 1 && !iscall(p->op)) - || (p->count == 0 && iscall(p->op))) { - p->kids[0] = visit(p->kids[0], 0); - p->kids[1] = visit(p->kids[1], 0); - } - - else if (specific(p->op) == ADDRL+P || specific(p->op) == ADDRF+P) { - assert(!listed); - p = newnode(p->op, NULL, NULL, p->syms[0]); - p->count = 1; - } - else if (p->op == INDIR+B) { - p = newnode(p->op, p->kids[0], NULL, NULL); - p->count = 1; - p->kids[0] = visit(p->kids[0], 0); - p->kids[1] = visit(p->kids[1], 0); - } - else { - p->kids[0] = visit(p->kids[0], 0); - p->kids[1] = visit(p->kids[1], 0); - p->syms[2] = temporary(REGISTER, btot(p->op, opsize(p->op))); - assert(!p->syms[2]->defined); - p->syms[2]->ref = 1; - p->syms[2]->u.t.cse = p; - - *tail = asgnnode(p->syms[2], p); - tail = &(*tail)->link; - if (!listed) - p = tmpnode(p); - }; - } - return p; -} -static Node tmpnode(Node p) { - Symbol tmp = p->syms[2]; - - assert(tmp); - if (--p->count == 0) - p->syms[2] = NULL; - p = newnode(INDIR + ttob(tmp->type), - newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), NULL, NULL); - p->count = 1; - return p; -} -static Node asgnnode(Symbol tmp, Node p) { - p = newnode(ASGN + ttob(tmp->type), - newnode(ADDRL + ttob(voidptype), NULL, NULL, tmp), p, NULL); - p->syms[0] = intconst(tmp->type->size); - p->syms[1] = intconst(tmp->type->align); - return p; -} -/* printdag - print dag p on fd, or the node list if p == 0 */ -void printdag(Node p, int fd) { - FILE *f = fd == 1 ? stdout : stderr; - - printed(0); - if (p == 0) { - if ((p = forest) != NULL) - do { - p = p->link; - printdag1(p, fd, 0); - } while (p != forest); - } else if (*printed(nodeid((Tree)p))) - fprint(f, "node'%d printed above\n", nodeid((Tree)p)); - else - printdag1(p, fd, 0); -} - -/* printdag1 - recursively print dag p */ -static void printdag1(Node p, int fd, int lev) { - int id, i; - - if (p == 0 || *printed(id = nodeid((Tree)p))) - return; - *printed(id) = 1; - for (i = 0; i < NELEMS(p->kids); i++) - printdag1(p->kids[i], fd, lev + 1); - printnode(p, fd, lev); -} - -/* printnode - print fields of dag p */ -static void printnode(Node p, int fd, int lev) { - if (p) { - FILE *f = fd == 1 ? stdout : stderr; - int i, id = nodeid((Tree)p); - fprint(f, "%c%d%s", lev == 0 ? '\'' : '#', id, - &" "[id < 10 ? 0 : id < 100 ? 1 : 2]); - fprint(f, "%s count=%d", opname(p->op), p->count); - for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++) - fprint(f, " #%d", nodeid((Tree)p->kids[i])); - if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type) - fprint(f, " {%t}", p->syms[0]->type); - else - for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) - if (p->syms[i]->name) - fprint(f, " %s", p->syms[i]->name); - else - fprint(f, " %p", p->syms[i]); - fprint(f, "\n"); - } -} - -/* typestab - emit stab entries for p */ -static void typestab(Symbol p, void *cl) { - if (!isfunc(p->type) && (p->sclass == EXTERN || p->sclass == STATIC) && IR->stabsym) - (*IR->stabsym)(p); - else if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype) - (*IR->stabtype)(p); -} - diff --git a/lcc/src/dagcheck.md b/lcc/src/dagcheck.md deleted file mode 100644 index 292dbee..0000000 --- a/lcc/src/dagcheck.md +++ /dev/null @@ -1,210 +0,0 @@ -%{ -#include "c.h" -typedef Node NODEPTR_TYPE; -#define OP_LABEL(p) (specific((p)->op)) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -#define PANIC error -%} -%term CNSTF=17 CNSTI=21 CNSTP=23 CNSTU=22 -%term ARGB=41 ARGF=33 ARGI=37 ARGP=39 ARGU=38 -%term ASGNB=57 ASGNF=49 ASGNI=53 ASGNP=55 ASGNU=54 -%term INDIRB=73 INDIRF=65 INDIRI=69 INDIRP=71 INDIRU=70 -%term CVFF=113 CVFI=117 -%term CVIF=129 CVII=133 CVIU=134 -%term CVPP=151 CVPU=150 -%term CVUI=181 CVUP=183 CVUU=182 -%term NEGF=193 NEGI=197 -%term CALLB=217 CALLF=209 CALLI=213 CALLP=215 CALLU=214 CALLV=216 -%term RETF=241 RETI=245 RETP=247 RETU=246 RETV=248 -%term ADDRGP=263 -%term ADDRFP=279 -%term ADDRLP=295 -%term ADDF=305 ADDI=309 ADDP=311 ADDU=310 -%term SUBF=321 SUBI=325 SUBP=327 SUBU=326 -%term LSHI=341 LSHU=342 -%term MODI=357 MODU=358 -%term RSHI=373 RSHU=374 -%term BANDI=389 BANDU=390 -%term BCOMI=405 BCOMU=406 -%term BORI=421 BORU=422 -%term BXORI=437 BXORU=438 -%term DIVF=449 DIVI=453 DIVU=454 -%term MULF=465 MULI=469 MULU=470 -%term EQF=481 EQI=485 EQU=486 -%term GEF=497 GEI=501 GEU=502 -%term GTF=513 GTI=517 GTU=518 -%term LEF=529 LEI=533 LEU=534 -%term LTF=545 LTI=549 LTU=550 -%term NEF=561 NEI=565 NEU=566 -%term JUMPV=584 -%term LABELV=600 -%% -stmt: INDIRB(P) "" -stmt: INDIRF(P) "" -stmt: INDIRI(P) "" -stmt: INDIRU(P) "" -stmt: INDIRP(P) "" -stmt: CALLF(P) "" -stmt: CALLI(P) "" -stmt: CALLU(P) "" -stmt: CALLP(P) "" -stmt: V "" -bogus: I "" 1 -bogus: U "" 1 -bogus: P "" 1 -bogus: F "" 1 -bogus: B "" 1 -bogus: V "" 1 -I: bogus "" 1 -U: bogus "" 1 -P: bogus "" 1 -F: bogus "" 1 -B: bogus "" 1 -V: bogus "" 1 -F: CNSTF "" -I: CNSTI "" -P: CNSTP "" -U: CNSTU "" -V: ARGB(B) "" -V: ARGF(F) "" -V: ARGI(I) "" -V: ARGU(U) "" -V: ARGP(P) "" -V: ASGNB(P,B) "" -V: ASGNF(P,F) "" -V: ASGNI(P,I) "" -V: ASGNU(P,U) "" -V: ASGNP(P,P) "" -B: INDIRB(P) "" -F: INDIRF(P) "" -I: INDIRI(P) "" -U: INDIRU(P) "" -P: INDIRP(P) "" -I: CVII(I) "" -I: CVUI(U) "" -I: CVFI(F) "" -U: CVIU(I) "" -U: CVUU(U) "" -U: CVPU(P) "" -F: CVIF(I) "" -F: CVFF(F) "" -P: CVUP(U) "" -P: CVPP(P) "" -F: NEGF(F) "" -I: NEGI(I) "" -V: CALLB(P,P) "" -F: CALLF(P) "" -I: CALLI(P) "" -U: CALLU(P) "" -P: CALLP(P) "" -V: CALLV(P) "" -V: RETF(F) "" -V: RETI(I) "" -V: RETU(U) "" -V: RETP(P) "" -V: RETV "" -P: ADDRGP "" -P: ADDRFP "" -P: ADDRLP "" -F: ADDF(F,F) "" -I: ADDI(I,I) "" -P: ADDP(P,I) "" -P: ADDP(I,P) "" -P: ADDP(U,P) "" -P: ADDP(P,U) "" -U: ADDU(U,U) "" -F: SUBF(F,F) "" -I: SUBI(I,I) "" -P: SUBP(P,I) "" -P: SUBP(P,U) "" -U: SUBU(U,U) "" -I: LSHI(I,I) "" -U: LSHU(U,I) "" -I: MODI(I,I) "" -U: MODU(U,U) "" -I: RSHI(I,I) "" -U: RSHU(U,I) "" -U: BANDU(U,U) "" -I: BANDI(I,I) "" -U: BCOMU(U) "" -I: BCOMI(I) "" -I: BORI(I,I) "" -U: BORU(U,U) "" -U: BXORU(U,U) "" -I: BXORI(I,I) "" -F: DIVF(F,F) "" -I: DIVI(I,I) "" -U: DIVU(U,U) "" -F: MULF(F,F) "" -I: MULI(I,I) "" -U: MULU(U,U) "" -V: EQF(F,F) "" -V: EQI(I,I) "" -V: EQU(U,U) "" -V: GEF(F,F) "" -V: GEI(I,I) "" -V: GEU(U,U) "" -V: GTF(F,F) "" -V: GTI(I,I) "" -V: GTU(U,U) "" -V: LEF(F,F) "" -V: LEI(I,I) "" -V: LEU(U,U) "" -V: LTF(F,F) "" -V: LTI(I,I) "" -V: LTU(U,U) "" -V: NEF(F,F) "" -V: NEI(I,I) "" -V: NEU(U,U) "" -V: JUMPV(P) "" -V: LABELV "" -%% - -static void reduce(NODEPTR_TYPE p, int goalnt) { - int i, sz = opsize(p->op), rulenumber = _rule(p->x.state, goalnt); - short *nts = _nts[rulenumber]; - NODEPTR_TYPE kids[10]; - - assert(rulenumber); - _kids(p, rulenumber, kids); - for (i = 0; nts[i]; i++) - reduce(kids[i], nts[i]); - switch (optype(p->op)) { -#define xx(ty) if (sz == ty->size) return - case I: - case U: - xx(chartype); - xx(shorttype); - xx(inttype); - xx(longtype); - xx(longlong); - break; - case F: - xx(floattype); - xx(doubletype); - xx(longdouble); - break; - case P: - xx(voidptype); - xx(funcptype); - break; - case V: - case B: if (sz == 0) return; -#undef xx - } - printdag(p, 2); - assert(0); -} - -void check(Node p) { - struct _state { short cost[1]; }; - - _label(p); - if (((struct _state *)p->x.state)->cost[1] > 0) { - printdag(p, 2); - assert(0); - } - reduce(p, 1); -} diff --git a/lcc/src/decl.c b/lcc/src/decl.c deleted file mode 100644 index 132241e..0000000 --- a/lcc/src/decl.c +++ /dev/null @@ -1,1162 +0,0 @@ -#include "c.h" - - -#define add(x,n) (x > inttype->u.sym->u.limits.max.i-(n) ? (overflow=1,x) : x+(n)) -#define chkoverflow(x,n) ((void)add(x,n)) -#define bits2bytes(n) (((n) + 7)/8) -static int regcount; - -static List autos, registers; -Symbol cfunc; /* current function */ -Symbol retv; /* return value location for structs */ - -static void checkref(Symbol, void *); -static Symbol dclglobal(int, char *, Type, Coordinate *); -static Symbol dcllocal(int, char *, Type, Coordinate *); -static Symbol dclparam(int, char *, Type, Coordinate *); -static Type dclr(Type, char **, Symbol **, int); -static Type dclr1(char **, Symbol **, int); -static void decl(Symbol (*)(int, char *, Type, Coordinate *)); -extern void doconst(Symbol, void *); -static void doglobal(Symbol, void *); -static void doextern(Symbol, void *); -static void exitparams(Symbol []); -static void fields(Type); -static void funcdefn(int, char *, Type, Symbol [], Coordinate); -static void initglobal(Symbol, int); -static void oldparam(Symbol, void *); -static Symbol *parameters(Type); -static Type specifier(int *); -static Type structdcl(int); -static Type tnode(int, Type); -void program(void) { - int n; - - level = GLOBAL; - for (n = 0; t != EOI; n++) - if (kind[t] == CHAR || kind[t] == STATIC - || t == ID || t == '*' || t == '(') { - decl(dclglobal); - deallocate(STMT); - if (!(glevel >= 3 || xref)) - deallocate(FUNC); - } else if (t == ';') { - warning("empty declaration\n"); - t = gettok(); - } else { - error("unrecognized declaration\n"); - t = gettok(); - } - if (n == 0) - warning("empty input file\n"); -} -static Type specifier(int *sclass) { - int cls, cons, sign, size, type, vol; - Type ty = NULL; - - cls = vol = cons = sign = size = type = 0; - if (sclass == NULL) - cls = AUTO; - for (;;) { - int *p, tt = t; - switch (t) { - case AUTO: - case REGISTER: if (level <= GLOBAL && cls == 0) - error("invalid use of `%k'\n", t); - p = &cls; t = gettok(); break; - case STATIC: case EXTERN: - case TYPEDEF: p = &cls; t = gettok(); break; - case CONST: p = &cons; t = gettok(); break; - case VOLATILE: p = &vol; t = gettok(); break; - case SIGNED: - case UNSIGNED: p = &sign; t = gettok(); break; - case LONG: if (size == LONG) { - size = 0; - tt = LONG+LONG; - } - p = &size; t = gettok(); break; - case SHORT: p = &size; t = gettok(); break; - case VOID: case CHAR: case INT: case FLOAT: - case DOUBLE: p = &type; ty = tsym->type; - t = gettok(); break; - case ENUM: p = &type; ty = enumdcl(); break; - case STRUCT: - case UNION: p = &type; ty = structdcl(t); break; - case ID: - if (istypename(t, tsym) && type == 0 - && sign == 0 && size == 0) { - use(tsym, src); - ty = tsym->type; - if (isqual(ty) - && ty->size != ty->type->size) { - ty = unqual(ty); - if (isconst(tsym->type)) - ty = qual(CONST, ty); - if (isvolatile(tsym->type)) - ty = qual(VOLATILE, ty); - tsym->type = ty; - } - p = &type; - t = gettok(); - } else - p = NULL; - break; - default: p = NULL; - } - if (p == NULL) - break; - if (*p) - error("invalid use of `%k'\n", tt); - *p = tt; - } - if (sclass) - *sclass = cls; - if (type == 0) { - type = INT; - ty = inttype; - } - if ((size == SHORT && type != INT) - || (size == LONG+LONG && type != INT) - || (size == LONG && type != INT && type != DOUBLE) - || (sign && type != INT && type != CHAR)) - error("invalid type specification\n"); - if (type == CHAR && sign) - ty = sign == UNSIGNED ? unsignedchar : signedchar; - else if (size == SHORT) - ty = sign == UNSIGNED ? unsignedshort : shorttype; - else if (size == LONG && type == DOUBLE) - ty = longdouble; - else if (size == LONG+LONG) { - ty = sign == UNSIGNED ? unsignedlonglong : longlong; - if (Aflag >= 1) - warning("`%t' is a non-ANSI type\n", ty); - } else if (size == LONG) - ty = sign == UNSIGNED ? unsignedlong : longtype; - else if (sign == UNSIGNED && type == INT) - ty = unsignedtype; - if (cons == CONST) - ty = qual(CONST, ty); - if (vol == VOLATILE) - ty = qual(VOLATILE, ty); - return ty; -} -static void decl(Symbol (*dcl)(int, char *, Type, Coordinate *)) { - int sclass; - Type ty, ty1; - static char stop[] = { CHAR, STATIC, ID, 0 }; - - ty = specifier(&sclass); - if (t == ID || t == '*' || t == '(' || t == '[') { - char *id; - Coordinate pos; - id = NULL; - pos = src; - if (level == GLOBAL) { - Symbol *params = NULL; - ty1 = dclr(ty, &id, ¶ms, 0); - if (params && id && isfunc(ty1) - && (t == '{' || istypename(t, tsym) - || (kind[t] == STATIC && t != TYPEDEF))) { - if (sclass == TYPEDEF) { - error("invalid use of `typedef'\n"); - sclass = EXTERN; - } - if (ty1->u.f.oldstyle) - exitscope(); - funcdefn(sclass, id, ty1, params, pos); - return; - } else if (params) - exitparams(params); - } else - ty1 = dclr(ty, &id, NULL, 0); - for (;;) { - if (Aflag >= 1 && !hasproto(ty1)) - warning("missing prototype\n"); - if (id == NULL) - error("missing identifier\n"); - else if (sclass == TYPEDEF) - { - Symbol p = lookup(id, identifiers); - if (p && p->scope == level) - error("redeclaration of `%s'\n", id); - p = install(id, &identifiers, level, - level < LOCAL ? PERM : FUNC); - p->type = ty1; - p->sclass = TYPEDEF; - p->src = pos; - } - else - (void)(*dcl)(sclass, id, ty1, &pos); - if (t != ',') - break; - t = gettok(); - id = NULL; - pos = src; - ty1 = dclr(ty, &id, NULL, 0); - } - } else if (ty == NULL - || !(isenum(ty) || - (isstruct(ty) && (*unqual(ty)->u.sym->name < '1' || *unqual(ty)->u.sym->name > '9')))) - error("empty declaration\n"); - test(';', stop); -} -static Symbol dclglobal(int sclass, char *id, Type ty, Coordinate *pos) { - Symbol p; - - if (sclass == 0) - sclass = AUTO; - else if (sclass != EXTERN && sclass != STATIC) { - error("invalid storage class `%k' for `%t %s'\n", - sclass, ty, id); - sclass = AUTO; - } - p = lookup(id, identifiers); - if (p && p->scope == GLOBAL) { - if (p->sclass != TYPEDEF && eqtype(ty, p->type, 1)) - ty = compose(ty, p->type); - else - error("redeclaration of `%s' previously declared at %w\n", p->name, &p->src); - - if (!isfunc(ty) && p->defined && t == '=') - error("redefinition of `%s' previously defined at %w\n", p->name, &p->src); - - if ((p->sclass == EXTERN && sclass == STATIC) - || (p->sclass == STATIC && sclass == AUTO) - || (p->sclass == AUTO && sclass == STATIC)) - warning("inconsistent linkage for `%s' previously declared at %w\n", p->name, &p->src); - - } - if (p == NULL || p->scope != GLOBAL) { - Symbol q = lookup(id, externals); - if (q) { - if (sclass == STATIC || !eqtype(ty, q->type, 1)) - warning("declaration of `%s' does not match previous declaration at %w\n", id, &q->src); - - p = relocate(id, externals, globals); - p->sclass = sclass; - } else { - p = install(id, &globals, GLOBAL, PERM); - p->sclass = sclass; - (*IR->defsymbol)(p); - } - if (p->sclass != STATIC) { - static int nglobals; - nglobals++; - if (Aflag >= 2 && nglobals == 512) - warning("more than 511 external identifiers\n"); - } - } else if (p->sclass == EXTERN) - p->sclass = sclass; - p->type = ty; - p->src = *pos; - if (t == '=' && isfunc(p->type)) { - error("illegal initialization for `%s'\n", p->name); - t = gettok(); - initializer(p->type, 0); - } else if (t == '=') { - initglobal(p, 0); - if (glevel > 0 && IR->stabsym) { - (*IR->stabsym)(p); swtoseg(p->u.seg); } - } else if (p->sclass == STATIC && !isfunc(p->type) - && p->type->size == 0) - error("undefined size for `%t %s'\n", p->type, p->name); - return p; -} -static void initglobal(Symbol p, int flag) { - Type ty; - - if (t == '=' || flag) { - if (p->sclass == STATIC) { - for (ty = p->type; isarray(ty); ty = ty->type) - ; - defglobal(p, isconst(ty) ? LIT : DATA); - } else - defglobal(p, DATA); - if (t == '=') - t = gettok(); - ty = initializer(p->type, 0); - if (isarray(p->type) && p->type->size == 0) - p->type = ty; - if (p->sclass == EXTERN) - p->sclass = AUTO; - } -} -void defglobal(Symbol p, int seg) { - p->u.seg = seg; - swtoseg(p->u.seg); - if (p->sclass != STATIC) - (*IR->export)(p); - (*IR->global)(p); - p->defined = 1; -} - -static Type dclr(Type basety, char **id, Symbol **params, int abstract) { - Type ty = dclr1(id, params, abstract); - - for ( ; ty; ty = ty->type) - switch (ty->op) { - case POINTER: - basety = ptr(basety); - break; - case FUNCTION: - basety = func(basety, ty->u.f.proto, - ty->u.f.oldstyle); - break; - case ARRAY: - basety = array(basety, ty->size, 0); - break; - case CONST: case VOLATILE: - basety = qual(ty->op, basety); - break; - default: assert(0); - } - if (Aflag >= 2 && basety->size > 32767) - warning("more than 32767 bytes in `%t'\n", basety); - return basety; -} -static Type tnode(int op, Type type) { - Type ty; - - NEW0(ty, STMT); - ty->op = op; - ty->type = type; - return ty; -} -static Type dclr1(char **id, Symbol **params, int abstract) { - Type ty = NULL; - - switch (t) { - case ID: if (id) - *id = token; - else - error("extraneous identifier `%s'\n", token); - t = gettok(); break; - case '*': t = gettok(); if (t == CONST || t == VOLATILE) { - Type ty1; - ty1 = ty = tnode(t, NULL); - while ((t = gettok()) == CONST || t == VOLATILE) - ty1 = tnode(t, ty1); - ty->type = dclr1(id, params, abstract); - ty = ty1; - } else - ty = dclr1(id, params, abstract); - ty = tnode(POINTER, ty); break; - case '(': t = gettok(); if (abstract - && (t == REGISTER || istypename(t, tsym) || t == ')')) { - Symbol *args; - ty = tnode(FUNCTION, ty); - enterscope(); - if (level > PARAM) - enterscope(); - args = parameters(ty); - exitparams(args); - } else { - ty = dclr1(id, params, abstract); - expect(')'); - if (abstract && ty == NULL - && (id == NULL || *id == NULL)) - return tnode(FUNCTION, NULL); - } break; - case '[': break; - default: return ty; - } - while (t == '(' || t == '[') - switch (t) { - case '(': t = gettok(); { Symbol *args; - ty = tnode(FUNCTION, ty); - enterscope(); - if (level > PARAM) - enterscope(); - args = parameters(ty); - if (params && *params == NULL) - *params = args; - else - exitparams(args); - } - break; - case '[': t = gettok(); { int n = 0; - if (kind[t] == ID) { - n = intexpr(']', 1); - if (n <= 0) { - error("`%d' is an illegal array size\n", n); - n = 1; - } - } else - expect(']'); - ty = tnode(ARRAY, ty); - ty->size = n; } break; - default: assert(0); - } - return ty; -} -static Symbol *parameters(Type fty) { - List list = NULL; - Symbol *params; - - if (kind[t] == STATIC || istypename(t, tsym)) { - int n = 0; - Type ty1 = NULL; - for (;;) { - Type ty; - int sclass = 0; - char *id = NULL; - if (ty1 && t == ELLIPSIS) { - static struct symbol sentinel; - if (sentinel.type == NULL) { - sentinel.type = voidtype; - sentinel.defined = 1; - } - if (ty1 == voidtype) - error("illegal formal parameter types\n"); - list = append(&sentinel, list); - t = gettok(); - break; - } - if (!istypename(t, tsym) && t != REGISTER) - error("missing parameter type\n"); - n++; - ty = dclr(specifier(&sclass), &id, NULL, 1); - if ( (ty == voidtype && (ty1 || id)) - || ty1 == voidtype) - error("illegal formal parameter types\n"); - if (id == NULL) - id = stringd(n); - if (ty != voidtype) - list = append(dclparam(sclass, id, ty, &src), list); - if (Aflag >= 1 && !hasproto(ty)) - warning("missing prototype\n"); - if (ty1 == NULL) - ty1 = ty; - if (t != ',') - break; - t = gettok(); - } - fty->u.f.proto = newarray(length(list) + 1, - sizeof (Type *), PERM); - params = ltov(&list, FUNC); - for (n = 0; params[n]; n++) - fty->u.f.proto[n] = params[n]->type; - fty->u.f.proto[n] = NULL; - fty->u.f.oldstyle = 0; - } else { - if (t == ID) - for (;;) { - Symbol p; - if (t != ID) { - error("expecting an identifier\n"); - break; - } - p = dclparam(0, token, inttype, &src); - p->defined = 0; - list = append(p, list); - t = gettok(); - if (t != ',') - break; - t = gettok(); - } - params = ltov(&list, FUNC); - fty->u.f.proto = NULL; - fty->u.f.oldstyle = 1; - } - if (t != ')') { - static char stop[] = { CHAR, STATIC, IF, ')', 0 }; - expect(')'); - skipto('{', stop); - } - if (t == ')') - t = gettok(); - return params; -} -static void exitparams(Symbol params[]) { - assert(params); - if (params[0] && !params[0]->defined) - error("extraneous old-style parameter list\n"); - if (level > PARAM) - exitscope(); - exitscope(); -} - -static Symbol dclparam(int sclass, char *id, Type ty, Coordinate *pos) { - Symbol p; - - if (isfunc(ty)) - ty = ptr(ty); - else if (isarray(ty)) - ty = atop(ty); - if (sclass == 0) - sclass = AUTO; - else if (sclass != REGISTER) { - error("invalid storage class `%k' for `%t%s\n", - sclass, ty, stringf(id ? " %s'" : "' parameter", id)); - sclass = AUTO; - } else if (isvolatile(ty) || isstruct(ty)) { - warning("register declaration ignored for `%t%s\n", - ty, stringf(id ? " %s'" : "' parameter", id)); - sclass = AUTO; - } - - p = lookup(id, identifiers); - if (p && p->scope == level) - error("duplicate declaration for `%s' previously declared at %w\n", id, &p->src); - - else - p = install(id, &identifiers, level, FUNC); - p->sclass = sclass; - p->src = *pos; - p->type = ty; - p->defined = 1; - if (t == '=') { - error("illegal initialization for parameter `%s'\n", id); - t = gettok(); - (void)expr1(0); - } - return p; -} -static Type structdcl(int op) { - char *tag; - Type ty; - Symbol p; - Coordinate pos; - - t = gettok(); - pos = src; - if (t == ID) { - tag = token; - t = gettok(); - } else - tag = ""; - if (t == '{') { - static char stop[] = { IF, ',', 0 }; - ty = newstruct(op, tag); - ty->u.sym->src = pos; - ty->u.sym->defined = 1; - t = gettok(); - if (istypename(t, tsym)) - fields(ty); - else - error("invalid %k field declarations\n", op); - test('}', stop); - } - else if (*tag && (p = lookup(tag, types)) != NULL - && p->type->op == op) { - ty = p->type; - if (t == ';' && p->scope < level) - ty = newstruct(op, tag); - } - else { - if (*tag == 0) - error("missing %k tag\n", op); - ty = newstruct(op, tag); - } - if (*tag && xref) - use(ty->u.sym, pos); - return ty; -} -static void fields(Type ty) { - { int n = 0; - while (istypename(t, tsym)) { - static char stop[] = { IF, CHAR, '}', 0 }; - Type ty1 = specifier(NULL); - for (;;) { - Field p; - char *id = NULL; - Type fty = dclr(ty1, &id, NULL, 0); - p = newfield(id, ty, fty); - if (Aflag >= 1 && !hasproto(p->type)) - warning("missing prototype\n"); - if (t == ':') { - if (unqual(p->type) != inttype - && unqual(p->type) != unsignedtype) { - error("`%t' is an illegal bit-field type\n", - p->type); - p->type = inttype; - } - t = gettok(); - p->bitsize = intexpr(0, 0); - if (p->bitsize > 8*inttype->size || p->bitsize < 0) { - error("`%d' is an illegal bit-field size\n", - p->bitsize); - p->bitsize = 8*inttype->size; - } else if (p->bitsize == 0 && id) { - warning("extraneous 0-width bit field `%t %s' ignored\n", p->type, id); - - p->name = stringd(genlabel(1)); - } - p->lsb = 1; - } - else { - if (id == NULL) - error("field name missing\n"); - else if (isfunc(p->type)) - error("`%t' is an illegal field type\n", p->type); - else if (p->type->size == 0) - error("undefined size for field `%t %s'\n", - p->type, id); - } - if (isconst(p->type)) - ty->u.sym->u.s.cfields = 1; - if (isvolatile(p->type)) - ty->u.sym->u.s.vfields = 1; - n++; - if (Aflag >= 2 && n == 128) - warning("more than 127 fields in `%t'\n", ty); - if (t != ',') - break; - t = gettok(); - } - test(';', stop); - } } - { int bits = 0, off = 0, overflow = 0; - Field p, *q = &ty->u.sym->u.s.flist; - ty->align = IR->structmetric.align; - for (p = *q; p; p = p->link) { - int a = p->type->align ? p->type->align : 1; - if (p->lsb) - a = unsignedtype->align; - if (ty->op == UNION) - off = bits = 0; - else if (p->bitsize == 0 || bits == 0 - || bits - 1 + p->bitsize > 8*unsignedtype->size) { - off = add(off, bits2bytes(bits-1)); - bits = 0; - chkoverflow(off, a - 1); - off = roundup(off, a); - } - if (a > ty->align) - ty->align = a; - p->offset = off; - - if (p->lsb) { - if (bits == 0) - bits = 1; - if (IR->little_endian) - p->lsb = bits; - else - p->lsb = 8*unsignedtype->size - bits + 1 - - p->bitsize + 1; - bits += p->bitsize; - } else - off = add(off, p->type->size); - if (off + bits2bytes(bits-1) > ty->size) - ty->size = off + bits2bytes(bits-1); - if (p->name == NULL - || !('1' <= *p->name && *p->name <= '9')) { - *q = p; - q = &p->link; - } - } - *q = NULL; - chkoverflow(ty->size, ty->align - 1); - ty->size = roundup(ty->size, ty->align); - if (overflow) { - error("size of `%t' exceeds %d bytes\n", ty, inttype->u.sym->u.limits.max.i); - ty->size = inttype->u.sym->u.limits.max.i&(~(ty->align - 1)); - } } -} -static void funcdefn(int sclass, char *id, Type ty, Symbol params[], Coordinate pt) { - int i, n; - Symbol *callee, *caller, p; - Type rty = freturn(ty); - - if (isstruct(rty) && rty->size == 0) - error("illegal use of incomplete type `%t'\n", rty); - for (n = 0; params[n]; n++) - ; - if (n > 0 && params[n-1]->name == NULL) - params[--n] = NULL; - if (Aflag >= 2 && n > 31) - warning("more than 31 parameters in function `%s'\n", id); - if (ty->u.f.oldstyle) { - if (Aflag >= 1) - warning("old-style function definition for `%s'\n", id); - caller = params; - callee = newarray(n + 1, sizeof *callee, FUNC); - memcpy(callee, caller, (n+1)*sizeof *callee); - enterscope(); - assert(level == PARAM); - while (kind[t] == STATIC || istypename(t, tsym)) - decl(dclparam); - foreach(identifiers, PARAM, oldparam, callee); - - for (i = 0; (p = callee[i]) != NULL; i++) { - if (!p->defined) - callee[i] = dclparam(0, p->name, inttype, &p->src); - *caller[i] = *p; - caller[i]->sclass = AUTO; - caller[i]->type = promote(p->type); - } - p = lookup(id, identifiers); - if (p && p->scope == GLOBAL && isfunc(p->type) - && p->type->u.f.proto) { - Type *proto = p->type->u.f.proto; - for (i = 0; caller[i] && proto[i]; i++) { - Type ty = unqual(proto[i]); - if (eqtype(isenum(ty) ? ty->type : ty, - unqual(caller[i]->type), 1) == 0) - break; - else if (isenum(ty) && !isenum(unqual(caller[i]->type))) - warning("compatibility of `%t' and `%t' is compiler dependent\n", - proto[i], caller[i]->type); - } - if (proto[i] || caller[i]) - error("conflicting argument declarations for function `%s'\n", id); - - } - else { - Type *proto = newarray(n + 1, sizeof *proto, PERM); - if (Aflag >= 1) - warning("missing prototype for `%s'\n", id); - for (i = 0; i < n; i++) - proto[i] = caller[i]->type; - proto[i] = NULL; - ty = func(rty, proto, 1); - } - } else { - callee = params; - caller = newarray(n + 1, sizeof *caller, FUNC); - for (i = 0; (p = callee[i]) != NULL && p->name; i++) { - NEW(caller[i], FUNC); - *caller[i] = *p; - if (isint(p->type)) - caller[i]->type = promote(p->type); - caller[i]->sclass = AUTO; - if ('1' <= *p->name && *p->name <= '9') - error("missing name for parameter %d to function `%s'\n", i + 1, id); - - } - caller[i] = NULL; - } - for (i = 0; (p = callee[i]) != NULL; i++) - if (p->type->size == 0) { - error("undefined size for parameter `%t %s'\n", - p->type, p->name); - caller[i]->type = p->type = inttype; - } - if (Aflag >= 2 && sclass != STATIC && strcmp(id, "main") == 0) { - if (ty->u.f.oldstyle) - warning("`%t %s()' is a non-ANSI definition\n", rty, id); - else if (!(rty == inttype - && ((n == 0 && callee[0] == NULL) - || (n == 2 && callee[0]->type == inttype - && isptr(callee[1]->type) && callee[1]->type->type == charptype - && !variadic(ty))))) - warning("`%s' is a non-ANSI definition\n", typestring(ty, id)); - } - p = lookup(id, identifiers); - if (p && isfunc(p->type) && p->defined) - error("redefinition of `%s' previously defined at %w\n", - p->name, &p->src); - cfunc = dclglobal(sclass, id, ty, &pt); - cfunc->u.f.label = genlabel(1); - cfunc->u.f.callee = callee; - cfunc->u.f.pt = src; - cfunc->defined = 1; - if (xref) - use(cfunc, cfunc->src); - if (Pflag) - printproto(cfunc, cfunc->u.f.callee); - if (ncalled >= 0) - ncalled = findfunc(cfunc->name, pt.file); - labels = table(NULL, LABELS); - stmtlabs = table(NULL, LABELS); - refinc = 1.0; - regcount = 0; - codelist = &codehead; - codelist->next = NULL; - if (!IR->wants_callb && isstruct(rty)) - retv = genident(AUTO, ptr(rty), PARAM); - compound(0, NULL, 0); - - { - Code cp; - for (cp = codelist; cp->kind < Label; cp = cp->prev) - ; - if (cp->kind != Jump) { - if (rty != voidtype) { - warning("missing return value\n"); - retcode(cnsttree(inttype, 0L)); - } else - retcode(NULL); - } - } - definelab(cfunc->u.f.label); - if (events.exit) - apply(events.exit, cfunc, NULL); - walk(NULL, 0, 0); - exitscope(); - assert(level == PARAM); - foreach(identifiers, level, checkref, NULL); - if (!IR->wants_callb && isstruct(rty)) { - Symbol *a; - a = newarray(n + 2, sizeof *a, FUNC); - a[0] = retv; - memcpy(&a[1], callee, (n+1)*sizeof *callee); - callee = a; - a = newarray(n + 2, sizeof *a, FUNC); - NEW(a[0], FUNC); - *a[0] = *retv; - memcpy(&a[1], caller, (n+1)*sizeof *callee); - caller = a; - } - if (!IR->wants_argb) - for (i = 0; caller[i]; i++) - if (isstruct(caller[i]->type)) { - caller[i]->type = ptr(caller[i]->type); - callee[i]->type = ptr(callee[i]->type); - caller[i]->structarg = callee[i]->structarg = 1; - } - if (glevel > 1) for (i = 0; callee[i]; i++) callee[i]->sclass = AUTO; - if (cfunc->sclass != STATIC) - (*IR->export)(cfunc); - if (glevel && IR->stabsym) { - swtoseg(CODE); (*IR->stabsym)(cfunc); } - swtoseg(CODE); - (*IR->function)(cfunc, caller, callee, cfunc->u.f.ncalls); - if (glevel && IR->stabfend) - (*IR->stabfend)(cfunc, lineno); - foreach(stmtlabs, LABELS, checklab, NULL); - exitscope(); - expect('}'); - labels = stmtlabs = NULL; - retv = NULL; - cfunc = NULL; -} -static void oldparam(Symbol p, void *cl) { - int i; - Symbol *callee = cl; - - for (i = 0; callee[i]; i++) - if (p->name == callee[i]->name) { - callee[i] = p; - return; - } - error("declared parameter `%s' is missing\n", p->name); -} -void compound(int loop, struct swtch *swp, int lev) { - Code cp; - int nregs; - - walk(NULL, 0, 0); - cp = code(Blockbeg); - enterscope(); - assert(level >= LOCAL); - if (level == LOCAL && events.entry) - apply(events.entry, cfunc, NULL); - definept(NULL); - expect('{'); - autos = registers = NULL; - if (level == LOCAL && IR->wants_callb - && isstruct(freturn(cfunc->type))) { - retv = genident(AUTO, ptr(freturn(cfunc->type)), level); - retv->defined = 1; - retv->ref = 1; - registers = append(retv, registers); - } - while (kind[t] == CHAR || kind[t] == STATIC - || (istypename(t, tsym) && getchr() != ':')) - decl(dcllocal); - { - int i; - Symbol *a = ltov(&autos, STMT); - nregs = length(registers); - for (i = 0; a[i]; i++) - registers = append(a[i], registers); - cp->u.block.locals = ltov(®isters, FUNC); - } - if (events.blockentry) - apply(events.blockentry, cp->u.block.locals, NULL); - while (kind[t] == IF || kind[t] == ID) - statement(loop, swp, lev); - walk(NULL, 0, 0); - foreach(identifiers, level, checkref, NULL); - { - int i = nregs, j; - Symbol p; - for ( ; (p = cp->u.block.locals[i]) != NULL; i++) { - for (j = i; j > nregs - && cp->u.block.locals[j-1]->ref < p->ref; j--) - cp->u.block.locals[j] = cp->u.block.locals[j-1]; - cp->u.block.locals[j] = p; - } - } - if (events.blockexit) - apply(events.blockexit, cp->u.block.locals, NULL); - cp->u.block.level = level; - cp->u.block.identifiers = identifiers; - cp->u.block.types = types; - code(Blockend)->u.begin = cp; - if (reachable(Gen)) - definept(NULL); - if (level > LOCAL) { - exitscope(); - expect('}'); - } -} -static void checkref(Symbol p, void *cl) { - if (p->scope >= PARAM - && (isvolatile(p->type) || isfunc(p->type))) - p->addressed = 1; - if (Aflag >= 2 && p->defined && p->ref == 0) { - if (p->sclass == STATIC) - warning("static `%t %s' is not referenced\n", - p->type, p->name); - else if (p->scope == PARAM) - warning("parameter `%t %s' is not referenced\n", - p->type, p->name); - else if (p->scope >= LOCAL && p->sclass != EXTERN) - warning("local `%t %s' is not referenced\n", - p->type, p->name); - } - if (p->sclass == AUTO - && ((p->scope == PARAM && regcount == 0) - || p->scope >= LOCAL) - && !p->addressed && isscalar(p->type) && p->ref >= 3.0) - p->sclass = REGISTER; - if (level == GLOBAL && p->sclass == STATIC && !p->defined - && isfunc(p->type) && p->ref) - error("undefined static `%t %s'\n", p->type, p->name); - assert(!(level == GLOBAL && p->sclass == STATIC && !p->defined && !isfunc(p->type))); -} -static Symbol dcllocal(int sclass, char *id, Type ty, Coordinate *pos) { - Symbol p, q; - - if (sclass == 0) - sclass = isfunc(ty) ? EXTERN : AUTO; - else if (isfunc(ty) && sclass != EXTERN) { - error("invalid storage class `%k' for `%t %s'\n", - sclass, ty, id); - sclass = EXTERN; - } else if (sclass == REGISTER - && (isvolatile(ty) || isstruct(ty) || isarray(ty))) { - warning("register declaration ignored for `%t %s'\n", - ty, id); - sclass = AUTO; - } - q = lookup(id, identifiers); - if ((q && q->scope >= level) - || (q && q->scope == PARAM && level == LOCAL)) { - if (sclass == EXTERN && q->sclass == EXTERN - && eqtype(q->type, ty, 1)) - ty = compose(ty, q->type); - else - error("redeclaration of `%s' previously declared at %w\n", q->name, &q->src); - } - - assert(level >= LOCAL); - p = install(id, &identifiers, level, sclass == STATIC || sclass == EXTERN ? PERM : FUNC); - p->type = ty; - p->sclass = sclass; - p->src = *pos; - switch (sclass) { - case EXTERN: q = lookup(id, globals); - if (q == NULL || q->sclass == TYPEDEF || q->sclass == ENUM) { - q = lookup(id, externals); - if (q == NULL) { - q = install(p->name, &externals, GLOBAL, PERM); - q->type = p->type; - q->sclass = EXTERN; - q->src = src; - (*IR->defsymbol)(q); - } - } - if (!eqtype(p->type, q->type, 1)) - warning("declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src); - - p->u.alias = q; break; - case STATIC: (*IR->defsymbol)(p); - initglobal(p, 0); - if (!p->defined) { - if (p->type->size > 0) { - defglobal(p, BSS); - (*IR->space)(p->type->size); - } else - error("undefined size for `%t %s'\n", - p->type, p->name); - } - p->defined = 1; break; - case REGISTER: registers = append(p, registers); - regcount++; - p->defined = 1; - break; - case AUTO: autos = append(p, autos); - p->defined = 1; break; - default: assert(0); - } - if (t == '=') { - Tree e; - if (sclass == EXTERN) - error("illegal initialization of `extern %s'\n", id); - t = gettok(); - definept(NULL); - if (isscalar(p->type) - || (isstruct(p->type) && t != '{')) { - if (t == '{') { - t = gettok(); - e = expr1(0); - expect('}'); - } else - e = expr1(0); - } else { - Symbol t1; - Type ty = p->type, ty1 = ty; - while (isarray(ty1)) - ty1 = ty1->type; - if (!isconst(ty) && (!isarray(ty) || !isconst(ty1))) - ty = qual(CONST, ty); - t1 = genident(STATIC, ty, GLOBAL); - initglobal(t1, 1); - if (isarray(p->type) && p->type->size == 0 - && t1->type->size > 0) - p->type = array(p->type->type, - t1->type->size/t1->type->type->size, 0); - e = idtree(t1); - } - walk(root(asgn(p, e)), 0, 0); - p->ref = 1; - } - if (!isfunc(p->type) && p->defined && p->type->size <= 0) - error("undefined size for `%t %s'\n", p->type, id); - return p; -} -void finalize(void) { - foreach(externals, GLOBAL, doextern, NULL); - foreach(identifiers, GLOBAL, doglobal, NULL); - foreach(identifiers, GLOBAL, checkref, NULL); - foreach(constants, CONSTANTS, doconst, NULL); -} -static void doextern(Symbol p, void *cl) { - (*IR->import)(p); -} -static void doglobal(Symbol p, void *cl) { - if (!p->defined && (p->sclass == EXTERN - || (isfunc(p->type) && p->sclass == AUTO))) - (*IR->import)(p); - else if (!p->defined && !isfunc(p->type) - && (p->sclass == AUTO || p->sclass == STATIC)) { - if (isarray(p->type) - && p->type->size == 0 && p->type->type->size > 0) - p->type = array(p->type->type, 1, 0); - if (p->type->size > 0) { - defglobal(p, BSS); - (*IR->space)(p->type->size); - if (glevel > 0 && IR->stabsym) - (*IR->stabsym)(p); - } else - error("undefined size for `%t %s'\n", - p->type, p->name); - p->defined = 1; - } - if (Pflag - && !isfunc(p->type) - && !p->generated && p->sclass != EXTERN) - printdecl(p, p->type); -} -void doconst(Symbol p, void *cl) { - if (p->u.c.loc) { - assert(p->u.c.loc->u.seg == 0); - defglobal(p->u.c.loc, LIT); - if (isarray(p->type) && p->type->type == widechar) { - unsigned int *s = p->u.c.v.p; - int n = p->type->size/widechar->size; - while (n-- > 0) { - Value v; - v.u = *s++; - (*IR->defconst)(widechar->op, widechar->size, v); - } - } else if (isarray(p->type)) - (*IR->defstring)(p->type->size, p->u.c.v.p); - else - (*IR->defconst)(p->type->op, p->type->size, p->u.c.v); - p->u.c.loc = NULL; - } -} -void checklab(Symbol p, void *cl) { - if (!p->defined) - error("undefined label `%s'\n", p->name); - p->defined = 1; -} - -Type enumdcl(void) { - char *tag; - Type ty; - Symbol p = {0}; - Coordinate pos; - - t = gettok(); - pos = src; - if (t == ID) { - tag = token; - t = gettok(); - } else - tag = ""; - if (t == '{') { - static char follow[] = { IF, 0 }; - int n = 0; - long k = -1; - List idlist = 0; - ty = newstruct(ENUM, tag); - t = gettok(); - if (t != ID) - error("expecting an enumerator identifier\n"); - while (t == ID) { - char *id = token; - Coordinate s; - if (tsym && tsym->scope == level) - error("redeclaration of `%s' previously declared at %w\n", - token, &tsym->src); - s = src; - t = gettok(); - if (t == '=') { - t = gettok(); - k = intexpr(0, 0); - } else { - if (k == inttype->u.sym->u.limits.max.i) - error("overflow in value for enumeration constant `%s'\n", id); - k++; - } - p = install(id, &identifiers, level, level < LOCAL ? PERM : FUNC); - p->src = s; - p->type = ty; - p->sclass = ENUM; - p->u.value = k; - idlist = append(p, idlist); - n++; - if (Aflag >= 2 && n == 128) - warning("more than 127 enumeration constants in `%t'\n", ty); - if (t != ',') - break; - t = gettok(); - if (Aflag >= 2 && t == '}') - warning("non-ANSI trailing comma in enumerator list\n"); - } - test('}', follow); - ty->type = inttype; - ty->size = ty->type->size; - ty->align = ty->type->align; - ty->u.sym->u.idlist = ltov(&idlist, PERM); - ty->u.sym->defined = 1; - } else if ((p = lookup(tag, types)) != NULL && p->type->op == ENUM) { - ty = p->type; - if (t == ';') - error("empty declaration\n"); - } else { - error("unknown enumeration `%s'\n", tag); - ty = newstruct(ENUM, tag); - ty->type = inttype; - } - if (*tag && xref) - use(p, pos); - return ty; -} - -Type typename(void) { - Type ty = specifier(NULL); - - if (t == '*' || t == '(' || t == '[') { - ty = dclr(ty, NULL, NULL, 1); - if (Aflag >= 1 && !hasproto(ty)) - warning("missing prototype\n"); - } - return ty; -} - diff --git a/lcc/src/enode.c b/lcc/src/enode.c deleted file mode 100644 index 0f2adbd..0000000 --- a/lcc/src/enode.c +++ /dev/null @@ -1,545 +0,0 @@ -#include "c.h" - - -static Tree addtree(int, Tree, Tree); -static Tree andtree(int, Tree, Tree); -static Tree cmptree(int, Tree, Tree); -static int compatible(Type, Type); -static int isnullptr(Tree e); -static Tree multree(int, Tree, Tree); -static Tree subtree(int, Tree, Tree); -#define isvoidptr(ty) \ - (isptr(ty) && unqual(ty->type) == voidtype) - -Tree (*optree[])(int, Tree, Tree) = { -#define xx(a,b,c,d,e,f,g) e, -#define yy(a,b,c,d,e,f,g) e, -#include "token.h" -}; -Tree call(Tree f, Type fty, Coordinate src) { - int n = 0; - Tree args = NULL, r = NULL, e; - Type *proto, rty = unqual(freturn(fty)); - Symbol t3 = NULL; - - if (fty->u.f.oldstyle) - proto = NULL; - else - proto = fty->u.f.proto; - if (hascall(f)) - r = f; - if (isstruct(rty)) - { - t3 = temporary(AUTO, unqual(rty)); - if (rty->size == 0) - error("illegal use of incomplete type `%t'\n", rty); - } - if (t != ')') - for (;;) { - Tree q = pointer(expr1(0)); - if (proto && *proto && *proto != voidtype) - { - Type aty; - q = value(q); - aty = assign(*proto, q); - if (aty) - q = cast(q, aty); - else - error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f), - - q->type, *proto); - if ((isint(q->type) || isenum(q->type)) - && q->type->size != inttype->size) - q = cast(q, promote(q->type)); - ++proto; - } - else - { - if (!fty->u.f.oldstyle && *proto == NULL) - error("too many arguments to %s\n", funcname(f)); - q = value(q); - if (isarray(q->type) || q->type->size == 0) - error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type); - - else - q = cast(q, promote(q->type)); - } - if (!IR->wants_argb && isstruct(q->type)) { - if (iscallb(q)) - q = addrof(q); - else { - Symbol t1 = temporary(AUTO, unqual(q->type)); - q = asgn(t1, q); - q = tree(RIGHT, ptr(t1->type), - root(q), lvalue(idtree(t1))); - } - } - if (q->type->size == 0) - q->type = inttype; - if (hascall(q)) - r = r ? tree(RIGHT, voidtype, r, q) : q; - args = tree(mkop(ARG, q->type), q->type, q, args); - n++; - if (Aflag >= 2 && n == 32) - warning("more than 31 arguments in a call to %s\n", - funcname(f)); - if (t != ',') - break; - t = gettok(); - } - expect(')'); - if (proto && *proto && *proto != voidtype) - error("insufficient number of arguments to %s\n", - funcname(f)); - if (r) - args = tree(RIGHT, voidtype, r, args); - e = calltree(f, rty, args, t3); - if (events.calls) - apply(events.calls, &src, &e); - return e; -} -Tree calltree(Tree f, Type ty, Tree args, Symbol t3) { - Tree p; - - if (args) - f = tree(RIGHT, f->type, args, f); - if (isstruct(ty)) - assert(t3), - p = tree(RIGHT, ty, - tree(CALL+B, ty, f, addrof(idtree(t3))), - idtree(t3)); - else { - Type rty = ty; - if (isenum(ty)) - rty = unqual(ty)->type; - if (!isfloat(rty)) - rty = promote(rty); - p = tree(mkop(CALL, rty), rty, f, NULL); - if (isptr(ty) || p->type->size > ty->size) - p = cast(p, ty); - } - return p; -} -Tree vcall(Symbol func, Type ty, ...) { - va_list ap; - Tree args = NULL, e, f = pointer(idtree(func)), r = NULL; - - assert(isfunc(func->type)); - if (ty == NULL) - ty = freturn(func->type); - va_start(ap, ty); - while ((e = va_arg(ap, Tree)) != NULL) { - if (hascall(e)) - r = r == NULL ? e : tree(RIGHT, voidtype, r, e); - args = tree(mkop(ARG, e->type), e->type, e, args); - } - va_end(ap); - if (r != NULL) - args = tree(RIGHT, voidtype, r, args); - return calltree(f, ty, args, NULL); -} -int iscallb(Tree e) { - return e->op == RIGHT && e->kids[0] && e->kids[1] - && e->kids[0]->op == CALL+B - && e->kids[1]->op == INDIR+B - && isaddrop(e->kids[1]->kids[0]->op) - && e->kids[1]->kids[0]->u.sym->temporary; -} - -static Tree addtree(int op, Tree l, Tree r) { - Type ty = inttype; - - if (isarith(l->type) && isarith(r->type)) { - ty = binary(l->type, r->type); - l = cast(l, ty); - r = cast(r, ty); - } else if (isptr(l->type) && isint(r->type)) - return addtree(ADD, r, l); - else if ( isptr(r->type) && isint(l->type) - && !isfunc(r->type->type)) - { - long n; - ty = unqual(r->type); - n = unqual(ty->type)->size; - if (n == 0) - error("unknown size for type `%t'\n", ty->type); - l = cast(l, promote(l->type)); - if (n > 1) - l = multree(MUL, cnsttree(signedptr, n), l); - if (YYcheck && !isaddrop(r->op)) /* omit */ - return nullcall(ty, YYcheck, r, l); /* omit */ - return simplify(ADD, ty, l, r); - } - - else - typeerror(op, l, r); - return simplify(op, ty, l, r); -} - -Tree cnsttree(Type ty, ...) { - Tree p = tree(mkop(CNST,ty), ty, NULL, NULL); - va_list ap; - - va_start(ap, ty); - switch (ty->op) { - case INT: p->u.v.i = va_arg(ap, long); break; - case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break; - case FLOAT: p->u.v.d = va_arg(ap, long double); break; - case POINTER: p->u.v.p = va_arg(ap, void *); break; - default: assert(0); - } - va_end(ap); - return p; -} - -Tree consttree(unsigned n, Type ty) { - if (isarray(ty)) - ty = atop(ty); - else assert(isint(ty)); - return cnsttree(ty, (unsigned long)n); -} -static Tree cmptree(int op, Tree l, Tree r) { - Type ty; - - if (isarith(l->type) && isarith(r->type)) { - ty = binary(l->type, r->type); - l = cast(l, ty); - r = cast(r, ty); - } else if (compatible(l->type, r->type)) { - ty = unsignedptr; - l = cast(l, ty); - r = cast(r, ty); - } else { - ty = unsignedtype; - typeerror(op, l, r); - } - return simplify(mkop(op,ty), inttype, l, r); -} -static int compatible(Type ty1, Type ty2) { - return isptr(ty1) && !isfunc(ty1->type) - && isptr(ty2) && !isfunc(ty2->type) - && eqtype(unqual(ty1->type), unqual(ty2->type), 0); -} -static int isnullptr(Tree e) { - Type ty = unqual(e->type); - - return generic(e->op) == CNST - && ((ty->op == INT && e->u.v.i == 0) - || (ty->op == UNSIGNED && e->u.v.u == 0) - || (isvoidptr(ty) && e->u.v.p == NULL)); -} -Tree eqtree(int op, Tree l, Tree r) { - Type xty = l->type, yty = r->type; - - if ((isptr(xty) && isnullptr(r)) - || (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)) - || (isptr(xty) && isptr(yty) - && eqtype(unqual(xty->type), unqual(yty->type), 1))) { - Type ty = unsignedptr; - l = cast(l, ty); - r = cast(r, ty); - return simplify(mkop(op,ty), inttype, l, r); - } - if ((isptr(yty) && isnullptr(l)) - || (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))) - return eqtree(op, r, l); - return cmptree(op, l, r); -} - -Type assign(Type xty, Tree e) { - Type yty = unqual(e->type); - - xty = unqual(xty); - if (isenum(xty)) - xty = xty->type; - if (xty->size == 0 || yty->size == 0) - return NULL; - if ( (isarith(xty) && isarith(yty)) - || (isstruct(xty) && xty == yty)) - return xty; - if (isptr(xty) && isnullptr(e)) - return xty; - if (((isvoidptr(xty) && isptr(yty)) - || (isptr(xty) && isvoidptr(yty))) - && ( (isconst(xty->type) || !isconst(yty->type)) - && (isvolatile(xty->type) || !isvolatile(yty->type)))) - return xty; - - if ((isptr(xty) && isptr(yty) - && eqtype(unqual(xty->type), unqual(yty->type), 1)) - && ( (isconst(xty->type) || !isconst(yty->type)) - && (isvolatile(xty->type) || !isvolatile(yty->type)))) - return xty; - if (isptr(xty) && isptr(yty) - && ( (isconst(xty->type) || !isconst(yty->type)) - && (isvolatile(xty->type) || !isvolatile(yty->type)))) { - Type lty = unqual(xty->type), rty = unqual(yty->type); - if ((isenum(lty) && rty == inttype) - || (isenum(rty) && lty == inttype)) { - if (Aflag >= 1) - warning("assignment between `%t' and `%t' is compiler-dependent\n", - xty, yty); - return xty; - } - } - return NULL; -} -Tree asgntree(int op, Tree l, Tree r) { - Type aty, ty; - - r = pointer(r); - ty = assign(l->type, r); - if (ty) - r = cast(r, ty); - else { - typeerror(ASGN, l, r); - if (r->type == voidtype) - r = retype(r, inttype); - ty = r->type; - } - if (l->op != FIELD) - l = lvalue(l); - aty = l->type; - if (isptr(aty)) - aty = unqual(aty)->type; - if ( isconst(aty) - || (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) { - if (isaddrop(l->op) - && !l->u.sym->computed && !l->u.sym->generated) - error("assignment to const identifier `%s'\n", - l->u.sym->name); - else - error("assignment to const location\n"); - } - if (l->op == FIELD) { - long n = 8*l->u.field->type->size - fieldsize(l->u.field); - if (n > 0 && isunsigned(l->u.field->type)) - r = bittree(BAND, r, - cnsttree(r->type, (unsigned long)fieldmask(l->u.field))); - else if (n > 0) { - if (r->op == CNST+I) { - n = r->u.v.i; - if (n&(1<<(fieldsize(l->u.field)-1))) - n |= ~0UL<<fieldsize(l->u.field); - r = cnsttree(r->type, n); - } else - r = shtree(RSH, - shtree(LSH, r, cnsttree(inttype, n)), - cnsttree(inttype, n)); - } - } - if (isstruct(ty) && isaddrop(l->op) && iscallb(r)) - return tree(RIGHT, ty, - tree(CALL+B, ty, r->kids[0]->kids[0], l), - idtree(l->u.sym)); - return tree(mkop(op,ty), ty, l, r); -} -Tree condtree(Tree e, Tree l, Tree r) { - Symbol t1; - Type ty, xty = l->type, yty = r->type; - Tree p; - - if (isarith(xty) && isarith(yty)) - ty = binary(xty, yty); - else if (eqtype(xty, yty, 1)) - ty = unqual(xty); - else if (isptr(xty) && isnullptr(r)) - ty = xty; - else if (isnullptr(l) && isptr(yty)) - ty = yty; - else if ((isptr(xty) && !isfunc(xty->type) && isvoidptr(yty)) - || (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty))) - ty = voidptype; - else if ((isptr(xty) && isptr(yty) - && eqtype(unqual(xty->type), unqual(yty->type), 1))) - ty = xty; - else { - typeerror(COND, l, r); - return consttree(0, inttype); - } - if (isptr(ty)) { - ty = unqual(unqual(ty)->type); - if ((isptr(xty) && isconst(unqual(xty)->type)) - || (isptr(yty) && isconst(unqual(yty)->type))) - ty = qual(CONST, ty); - if ((isptr(xty) && isvolatile(unqual(xty)->type)) - || (isptr(yty) && isvolatile(unqual(yty)->type))) - ty = qual(VOLATILE, ty); - ty = ptr(ty); - } - switch (e->op) { - case CNST+I: return cast(e->u.v.i != 0 ? l : r, ty); - case CNST+U: return cast(e->u.v.u != 0 ? l : r, ty); - case CNST+P: return cast(e->u.v.p != 0 ? l : r, ty); - case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty); - } - if (ty != voidtype && ty->size > 0) { - t1 = genident(REGISTER, unqual(ty), level); - /* t1 = temporary(REGISTER, unqual(ty)); */ - l = asgn(t1, l); - r = asgn(t1, r); - } else - t1 = NULL; - p = tree(COND, ty, cond(e), - tree(RIGHT, ty, root(l), root(r))); - p->u.sym = t1; - return p; -} -/* addrof - address of p */ -Tree addrof(Tree p) { - Tree q = p; - - for (;;) - switch (generic(q->op)) { - case RIGHT: - assert(q->kids[0] || q->kids[1]); - q = q->kids[1] ? q->kids[1] : q->kids[0]; - continue; - case ASGN: - q = q->kids[1]; - continue; - case COND: { - Symbol t1 = q->u.sym; - q->u.sym = 0; - q = idtree(t1); - /* fall thru */ - } - case INDIR: - if (p == q) - return q->kids[0]; - q = q->kids[0]; - return tree(RIGHT, q->type, root(p), q); - default: - error("addressable object required\n"); - return value(p); - } -} - -/* andtree - construct tree for l [&& ||] r */ -static Tree andtree(int op, Tree l, Tree r) { - if (!isscalar(l->type) || !isscalar(r->type)) - typeerror(op, l, r); - return simplify(op, inttype, cond(l), cond(r)); -} - -/* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */ -Tree asgn(Symbol p, Tree e) { - if (isarray(p->type)) - e = tree(ASGN+B, p->type, idtree(p), - tree(INDIR+B, e->type, e, NULL)); - else { - Type ty = p->type; - p->type = unqual(p->type); - if (isstruct(p->type) && p->type->u.sym->u.s.cfields) { - p->type->u.sym->u.s.cfields = 0; - e = asgntree(ASGN, idtree(p), e); - p->type->u.sym->u.s.cfields = 1; - } else - e = asgntree(ASGN, idtree(p), e); - p->type = ty; - } - return e; -} - -/* bittree - construct tree for l [& | ^ %] r */ -Tree bittree(int op, Tree l, Tree r) { - Type ty = inttype; - - if (isint(l->type) && isint(r->type)) { - ty = binary(l->type, r->type); - l = cast(l, ty); - r = cast(r, ty); - } else - typeerror(op, l, r); - return simplify(op, ty, l, r); -} - -/* multree - construct tree for l [* /] r */ -static Tree multree(int op, Tree l, Tree r) { - Type ty = inttype; - - if (isarith(l->type) && isarith(r->type)) { - ty = binary(l->type, r->type); - l = cast(l, ty); - r = cast(r, ty); - } else - typeerror(op, l, r); - return simplify(op, ty, l, r); -} - -/* shtree - construct tree for l [>> <<] r */ -Tree shtree(int op, Tree l, Tree r) { - Type ty = inttype; - - if (isint(l->type) && isint(r->type)) { - ty = promote(l->type); - l = cast(l, ty); - r = cast(r, inttype); - } else - typeerror(op, l, r); - return simplify(op, ty, l, r); -} - -/* subtree - construct tree for l - r */ -static Tree subtree(int op, Tree l, Tree r) { - long n; - Type ty = inttype; - - if (isarith(l->type) && isarith(r->type)) { - ty = binary(l->type, r->type); - l = cast(l, ty); - r = cast(r, ty); - } else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) { - ty = unqual(l->type); - n = unqual(ty->type)->size; - if (n == 0) - error("unknown size for type `%t'\n", ty->type); - r = cast(r, promote(r->type)); - if (n > 1) - r = multree(MUL, cnsttree(signedptr, n), r); - if (isunsigned(r->type)) - r = cast(r, unsignedptr); - else - r = cast(r, signedptr); - return simplify(SUB+P, ty, l, r); - } else if (compatible(l->type, r->type)) { - ty = unqual(l->type); - n = unqual(ty->type)->size; - if (n == 0) - error("unknown size for type `%t'\n", ty->type); - l = simplify(SUB+U, unsignedptr, - cast(l, unsignedptr), cast(r, unsignedptr)); - return simplify(DIV+I, longtype, - cast(l, longtype), cnsttree(longtype, n)); - } else - typeerror(op, l, r); - return simplify(op, ty, l, r); -} - -/* typeerror - issue "operands of op have illegal types `l' and `r'" */ -void typeerror(int op, Tree l, Tree r) { - int i; - static struct { int op; char *name; } ops[] = { - {ASGN, "="}, {INDIR, "*"}, {NEG, "-"}, - {ADD, "+"}, {SUB, "-"}, {LSH, "<<"}, - {MOD, "%"}, {RSH, ">>"}, {BAND, "&"}, - {BCOM, "~"}, {BOR, "|"}, {BXOR, "^"}, - {DIV, "/"}, {MUL, "*"}, {EQ, "=="}, - {GE, ">="}, {GT, ">"}, {LE, "<="}, - {LT, "<"}, {NE, "!="}, {AND, "&&"}, - {NOT, "!"}, {OR, "||"}, {COND, "?:"}, - {0, 0} - }; - - op = generic(op); - for (i = 0; ops[i].op; i++) - if (op == ops[i].op) - break; - assert(ops[i].name); - if (r) - error("operands of %s have illegal types `%t' and `%t'\n", - ops[i].name, l->type, r->type); - else - error("operand of unary %s has illegal type `%t'\n", ops[i].name, - l->type); -} diff --git a/lcc/src/error.c b/lcc/src/error.c deleted file mode 100644 index 2187c10..0000000 --- a/lcc/src/error.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "c.h" - - -static void printtoken(void); -int errcnt = 0; -int errlimit = 20; -char kind[] = { -#define xx(a,b,c,d,e,f,g) f, -#define yy(a,b,c,d,e,f,g) f, -#include "token.h" -}; -int wflag; /* != 0 to suppress warning messages */ - -void test(int tok, char set[]) { - if (t == tok) - t = gettok(); - else { - expect(tok); - skipto(tok, set); - if (t == tok) - t = gettok(); - } -} -void expect(int tok) { - if (t == tok) - t = gettok(); - else { - error("syntax error; found"); - printtoken(); - fprint(stderr, " expecting `%k'\n", tok); - } -} -void error(const char *fmt, ...) { - va_list ap; - - if (errcnt++ >= errlimit) { - errcnt = -1; - error("too many errors\n"); - exit(1); - } - va_start(ap, fmt); - if (firstfile != file && firstfile && *firstfile) - fprint(stderr, "%s: ", firstfile); - fprint(stderr, "%w: ", &src); - vfprint(stderr, NULL, fmt, ap); - va_end(ap); -} - -void skipto(int tok, char set[]) { - int n; - char *s; - - assert(set); - for (n = 0; t != EOI && t != tok; t = gettok()) { - for (s = set; *s && kind[t] != *s; s++) - ; - if (kind[t] == *s) - break; - if (n++ == 0) - error("skipping"); - if (n <= 8) - printtoken(); - else if (n == 9) - fprint(stderr, " ..."); - } - if (n > 8) { - fprint(stderr, " up to"); - printtoken(); - } - if (n > 0) - fprint(stderr, "\n"); -} -/* fatal - issue fatal error message and exit */ -int fatal(const char *name, const char *fmt, int n) { - print("\n"); - errcnt = -1; - error("compiler error in %s--", name); - fprint(stderr, fmt, n); - exit(EXIT_FAILURE); - return 0; -} - -/* printtoken - print current token preceeded by a space */ -static void printtoken(void) { - switch (t) { - case ID: fprint(stderr, " `%s'", token); break; - case ICON: - fprint(stderr, " `%s'", vtoa(tsym->type, tsym->u.c.v)); - break; - case SCON: { - int i, n; - if (ischar(tsym->type->type)) { - char *s = tsym->u.c.v.p; - n = tsym->type->size; - fprint(stderr, " \""); - for (i = 0; i < 20 && i < n && *s; s++, i++) - if (*s < ' ' || *s >= 0177) - fprint(stderr, "\\%o", *s); - else - fprint(stderr, "%c", *s); - } else { /* wchar_t string */ - unsigned int *s = tsym->u.c.v.p; - assert(tsym->type->type->size == widechar->size); - n = tsym->type->size/widechar->size; - fprint(stderr, " L\""); - for (i = 0; i < 20 && i < n && *s; s++, i++) - if (*s < ' ' || *s >= 0177) - fprint(stderr, "\\x%x", *s); - else - fprint(stderr, "%c", *s); - } - if (i < n) - fprint(stderr, " ..."); - else - fprint(stderr, "\""); - break; - } - case FCON: - fprint(stderr, " `%S'", token, (char*)cp - token); - break; - case '`': case '\'': fprint(stderr, " \"%k\"", t); break; - default: fprint(stderr, " `%k'", t); - } -} - -/* warning - issue warning error message */ -void warning(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - if (wflag == 0) { - errcnt--; - error("warning: "); - vfprint(stderr, NULL, fmt, ap); - } - va_end(ap); -} diff --git a/lcc/src/event.c b/lcc/src/event.c deleted file mode 100644 index 4549e3f..0000000 --- a/lcc/src/event.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "c.h" - - -struct entry { - Apply func; - void *cl; -}; - -Events events; -void attach(Apply func, void *cl, List *list) { - struct entry *p; - - NEW(p, PERM); - p->func = func; - p->cl = cl; - *list = append(p, *list); -} -void apply(List event, void *arg1, void *arg2) { - if (event) { - List lp = event; - do { - struct entry *p = lp->x; - (*p->func)(p->cl, arg1, arg2); - lp = lp->link; - } while (lp != event); - } -} - diff --git a/lcc/src/expr.c b/lcc/src/expr.c deleted file mode 100644 index f20a090..0000000 --- a/lcc/src/expr.c +++ /dev/null @@ -1,711 +0,0 @@ -#include "c.h" - - -static char prec[] = { -#define xx(a,b,c,d,e,f,g) c, -#define yy(a,b,c,d,e,f,g) c, -#include "token.h" -}; -static int oper[] = { -#define xx(a,b,c,d,e,f,g) d, -#define yy(a,b,c,d,e,f,g) d, -#include "token.h" -}; -float refinc = 1.0; -static Tree expr2(void); -static Tree expr3(int); -static Tree nullcheck(Tree); -static Tree postfix(Tree); -static Tree unary(void); -static Tree primary(void); -static Type super(Type ty); - -static Type super(Type ty) { - switch (ty->op) { - case INT: - if (ty->size < inttype->size) - return inttype; - break; - case UNSIGNED: - if (ty->size < unsignedtype->size) - return unsignedtype; - break; - case POINTER: - return unsignedptr; - } - return ty; -} -Tree expr(int tok) { - static char stop[] = { IF, ID, '}', 0 }; - Tree p = expr1(0); - - while (t == ',') { - Tree q; - t = gettok(); - q = pointer(expr1(0)); - p = tree(RIGHT, q->type, root(value(p)), q); - } - if (tok) - test(tok, stop); - return p; -} -Tree expr0(int tok) { - return root(expr(tok)); -} -Tree expr1(int tok) { - static char stop[] = { IF, ID, 0 }; - Tree p = expr2(); - - if (t == '=' - || (prec[t] >= 6 && prec[t] <= 8) - || (prec[t] >= 11 && prec[t] <= 13)) { - int op = t; - t = gettok(); - if (oper[op] == ASGN) - p = asgntree(ASGN, p, value(expr1(0))); - else - { - expect('='); - p = incr(op, p, expr1(0)); - } - } - if (tok) - test(tok, stop); - return p; -} -Tree incr(int op, Tree v, Tree e) { - return asgntree(ASGN, v, (*optree[op])(oper[op], v, e)); -} -static Tree expr2(void) { - Tree p = expr3(4); - - if (t == '?') { - Tree l, r; - Coordinate pts[2]; - if (Aflag > 1 && isfunc(p->type)) - warning("%s used in a conditional expression\n", - funcname(p)); - p = pointer(p); - t = gettok(); - pts[0] = src; - l = pointer(expr(':')); - pts[1] = src; - r = pointer(expr2()); - if (events.points) - { - apply(events.points, &pts[0], &l); - apply(events.points, &pts[1], &r); - } - p = condtree(p, l, r); - } - return p; -} -Tree value(Tree p) { - int op = generic(rightkid(p)->op); - - if (p->type != voidtype - && (op==AND || op==OR || op==NOT || op==EQ || op==NE - || op== LE || op==LT || op== GE || op==GT)) - p = condtree(p, consttree(1, inttype), - consttree(0, inttype)); - return p; -} -static Tree expr3(int k) { - int k1; - Tree p = unary(); - - for (k1 = prec[t]; k1 >= k; k1--) - while (prec[t] == k1 && *cp != '=') { - Tree r; - Coordinate pt; - int op = t; - t = gettok(); - pt = src; - p = pointer(p); - if (op == ANDAND || op == OROR) { - r = pointer(expr3(k1)); - if (events.points) - apply(events.points, &pt, &r); - } else - r = pointer(expr3(k1 + 1)); - p = (*optree[op])(oper[op], p, r); - } - return p; -} -static Tree unary(void) { - Tree p; - - switch (t) { - case '*': t = gettok(); p = unary(); p = pointer(p); - if (isptr(p->type) - && (isfunc(p->type->type) || isarray(p->type->type))) - p = retype(p, p->type->type); - else { - if (YYnull) - p = nullcheck(p); - p = rvalue(p); - } break; - case '&': t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type)) - p = retype(p, ptr(p->type)); - else - p = lvalue(p); - if (isaddrop(p->op) && p->u.sym->sclass == REGISTER) - error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name); - - else if (isaddrop(p->op)) - p->u.sym->addressed = 1; - break; - case '+': t = gettok(); p = unary(); p = pointer(p); - if (isarith(p->type)) - p = cast(p, promote(p->type)); - else - typeerror(ADD, p, NULL); break; - case '-': t = gettok(); p = unary(); p = pointer(p); - if (isarith(p->type)) { - Type ty = promote(p->type); - p = cast(p, ty); - if (isunsigned(ty)) { - warning("unsigned operand of unary -\n"); - p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL)); - } else - p = simplify(NEG, ty, p, NULL); - } else - typeerror(SUB, p, NULL); break; - case '~': t = gettok(); p = unary(); p = pointer(p); - if (isint(p->type)) { - Type ty = promote(p->type); - p = simplify(BCOM, ty, cast(p, ty), NULL); - } else - typeerror(BCOM, p, NULL); break; - case '!': t = gettok(); p = unary(); p = pointer(p); - if (isscalar(p->type)) - p = simplify(NOT, inttype, cond(p), NULL); - else - typeerror(NOT, p, NULL); break; - case INCR: t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break; - case DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break; - case TYPECODE: case SIZEOF: { int op = t; - Type ty; - p = NULL; - t = gettok(); - if (t == '(') { - t = gettok(); - if (istypename(t, tsym)) { - ty = typename(); - expect(')'); - } else { - p = postfix(expr(')')); - ty = p->type; - } - } else { - p = unary(); - ty = p->type; - } - assert(ty); - if (op == TYPECODE) - p = cnsttree(inttype, (long)ty->op); - else { - if (isfunc(ty) || ty->size == 0) - error("invalid type argument `%t' to `sizeof'\n", ty); - else if (p && rightkid(p)->op == FIELD) - error("`sizeof' applied to a bit field\n"); - p = cnsttree(unsignedlong, (unsigned long)ty->size); - } } break; - case '(': - t = gettok(); - if (istypename(t, tsym)) { - Type ty, ty1 = typename(), pty; - expect(')'); - ty = unqual(ty1); - if (isenum(ty)) { - Type ty2 = ty->type; - if (isconst(ty1)) - ty2 = qual(CONST, ty2); - if (isvolatile(ty1)) - ty2 = qual(VOLATILE, ty2); - ty1 = ty2; - ty = ty->type; - } - p = pointer(unary()); - pty = p->type; - if (isenum(pty)) - pty = pty->type; - if ((isarith(pty) && isarith(ty)) - || (isptr(pty) && isptr(ty))) { - explicitCast++; - p = cast(p, ty); - explicitCast--; - } else if ((isptr(pty) && isint(ty)) - || (isint(pty) && isptr(ty))) { - if (Aflag >= 1 && ty->size < pty->size) - warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, ty); - - p = cast(p, ty); - } else if (ty != voidtype) { - error("cast from `%t' to `%t' is illegal\n", - p->type, ty1); - ty1 = inttype; - } - if (generic(p->op) == INDIR || ty->size == 0) - p = tree(RIGHT, ty1, NULL, p); - else - p = retype(p, ty1); - } else - p = postfix(expr(')')); - break; - default: - p = postfix(primary()); - } - return p; -} - -static Tree postfix(Tree p) { - for (;;) - switch (t) { - case INCR: p = tree(RIGHT, p->type, - tree(RIGHT, p->type, - p, - incr(t, p, consttree(1, inttype))), - p); - t = gettok(); break; - case DECR: p = tree(RIGHT, p->type, - tree(RIGHT, p->type, - p, - incr(t, p, consttree(1, inttype))), - p); - t = gettok(); break; - case '[': { - Tree q; - t = gettok(); - q = expr(']'); - if (YYnull) { - if (isptr(p->type)) - p = nullcheck(p); - else if (isptr(q->type)) - q = nullcheck(q); - } - p = (*optree['+'])(ADD, pointer(p), pointer(q)); - if (isptr(p->type) && isarray(p->type->type)) - p = retype(p, p->type->type); - else - p = rvalue(p); - } break; - case '(': { - Type ty; - Coordinate pt; - p = pointer(p); - if (isptr(p->type) && isfunc(p->type->type)) - ty = p->type->type; - else { - error("found `%t' expected a function\n", p->type); - ty = func(voidtype, NULL, 1); - p = retype(p, ptr(ty)); - } - pt = src; - t = gettok(); - p = call(p, ty, pt); - } break; - case '.': t = gettok(); - if (t == ID) { - if (isstruct(p->type)) { - Tree q = addrof(p); - p = field(q, token); - q = rightkid(q); - if (isaddrop(q->op) && q->u.sym->temporary) - p = tree(RIGHT, p->type, p, NULL); - } else - error("left operand of . has incompatible type `%t'\n", - p->type); - t = gettok(); - } else - error("field name expected\n"); break; - case DEREF: t = gettok(); - p = pointer(p); - if (t == ID) { - if (isptr(p->type) && isstruct(p->type->type)) { - if (YYnull) - p = nullcheck(p); - p = field(p, token); - } else - error("left operand of -> has incompatible type `%t'\n", p->type); - - t = gettok(); - } else - error("field name expected\n"); break; - default: - return p; - } -} -static Tree primary(void) { - Tree p; - - assert(t != '('); - switch (t) { - case ICON: - case FCON: p = tree(mkop(CNST,tsym->type), tsym->type, NULL, NULL); - p->u.v = tsym->u.c.v; - break; - case SCON: if (ischar(tsym->type->type)) - tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size); - else - tsym->u.c.v.p = memcpy(allocate(tsym->type->size, PERM), tsym->u.c.v.p, tsym->type->size); - tsym = constant(tsym->type, tsym->u.c.v); - if (tsym->u.c.loc == NULL) - tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL); - p = idtree(tsym->u.c.loc); break; - case ID: if (tsym == NULL) - { - Symbol p = install(token, &identifiers, level, FUNC); - p->src = src; - if (getchr() == '(') { - Symbol q = lookup(token, externals); - p->type = func(inttype, NULL, 1); - p->sclass = EXTERN; - if (Aflag >= 1) - warning("missing prototype\n"); - if (q && !eqtype(q->type, p->type, 1)) - warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src); - - if (q == NULL) { - q = install(p->name, &externals, GLOBAL, PERM); - q->type = p->type; - q->sclass = EXTERN; - q->src = src; - (*IR->defsymbol)(q); - } - p->u.alias = q; - } else { - error("undeclared identifier `%s'\n", p->name); - p->sclass = AUTO; - p->type = inttype; - if (p->scope == GLOBAL) - (*IR->defsymbol)(p); - else - addlocal(p); - } - t = gettok(); - if (xref) - use(p, src); - return idtree(p); - } - if (xref) - use(tsym, src); - if (tsym->sclass == ENUM) - p = consttree(tsym->u.value, inttype); - else { - if (tsym->sclass == TYPEDEF) - error("illegal use of type name `%s'\n", tsym->name); - p = idtree(tsym); - } break; - case FIRSTARG: - if (level > PARAM && cfunc && cfunc->u.f.callee[0]) - p = idtree(cfunc->u.f.callee[0]); - else { - error("illegal use of `%k'\n", FIRSTARG); - p = cnsttree(inttype, 0L); - } - break; - default: - error("illegal expression\n"); - p = cnsttree(inttype, 0L); - } - t = gettok(); - return p; -} -Tree idtree(Symbol p) { - int op; - Tree e; - Type ty = p->type ? unqual(p->type) : voidptype; - - if (p->scope == GLOBAL || p->sclass == STATIC) - op = ADDRG; - else if (p->scope == PARAM) { - op = ADDRF; - if (isstruct(p->type) && !IR->wants_argb) - { - e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL); - e->u.sym = p; - return rvalue(rvalue(e)); - } - } else if (p->sclass == EXTERN) { - assert(p->u.alias); - p = p->u.alias; - op = ADDRG; - } else - op = ADDRL; - p->ref += refinc; - if (isarray(ty)) - e = tree(mkop(op,voidptype), p->type, NULL, NULL); - else if (isfunc(ty)) - e = tree(mkop(op,funcptype), p->type, NULL, NULL); - else - e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL); - e->u.sym = p; - if (isptr(e->type)) - e = rvalue(e); - return e; -} - -Tree rvalue(Tree p) { - Type ty = deref(p->type); - - ty = unqual(ty); - return tree(mkop(INDIR,ty), ty, p, NULL); -} -Tree lvalue(Tree p) { - if (generic(p->op) != INDIR) { - error("lvalue required\n"); - return value(p); - } else if (unqual(p->type) == voidtype) - warning("`%t' used as an lvalue\n", p->type); - return p->kids[0]; -} -Tree retype(Tree p, Type ty) { - Tree q; - - if (p->type == ty) - return p; - q = tree(p->op, ty, p->kids[0], p->kids[1]); - q->node = p->node; - q->u = p->u; - return q; -} -Tree rightkid(Tree p) { - while (p && p->op == RIGHT) - if (p->kids[1]) - p = p->kids[1]; - else if (p->kids[0]) - p = p->kids[0]; - else - assert(0); - assert(p); - return p; -} -int hascall(Tree p) { - if (p == 0) - return 0; - if (generic(p->op) == CALL || (IR->mulops_calls && - (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I - || p->op == DIV+U || p->op == MOD+U || p->op == MUL+U))) - return 1; - return hascall(p->kids[0]) || hascall(p->kids[1]); -} -Type binary(Type xty, Type yty) { -#define xx(t) if (xty == t || yty == t) return t - xx(longdouble); - xx(doubletype); - xx(floattype); - xx(unsignedlonglong); - xx(longlong); - xx(unsignedlong); - if ((xty == longtype && yty == unsignedtype) - || (xty == unsignedtype && yty == longtype)) { - if (longtype->size > unsignedtype->size) - return longtype; - else - return unsignedlong; - } - xx(longtype); - xx(unsignedtype); - return inttype; -#undef xx -} -Tree pointer(Tree p) { - if (isarray(p->type)) - /* assert(p->op != RIGHT || p->u.sym == NULL), */ - p = retype(p, atop(p->type)); - else if (isfunc(p->type)) - p = retype(p, ptr(p->type)); - return p; -} -Tree cond(Tree p) { - int op = generic(rightkid(p)->op); - - if (op == AND || op == OR || op == NOT - || op == EQ || op == NE - || op == LE || op == LT || op == GE || op == GT) - return p; - p = pointer(p); - return (*optree[NEQ])(NE, p, consttree(0, inttype)); -} -Tree cast(Tree p, Type type) { - Type src, dst; - - p = value(p); - if (p->type == type) - return p; - dst = unqual(type); - src = unqual(p->type); - if (src->op != dst->op || src->size != dst->size) { - switch (src->op) { - case INT: - if (src->size < inttype->size) - p = simplify(CVI, inttype, p, NULL); - break; - case UNSIGNED: - if (src->size < inttype->size) - p = simplify(CVU, inttype, p, NULL); - else if (src->size < unsignedtype->size) - p = simplify(CVU, unsignedtype, p, NULL); - break; - case ENUM: - p = retype(p, inttype); - break; - case POINTER: - if (isint(dst) && src->size > dst->size) - warning("conversion from `%t' to `%t' is undefined\n", p->type, type); - p = simplify(CVP, super(src), p, NULL); - break; - case FLOAT: - break; - default: assert(0); - } - { - src = unqual(p->type); - dst = super(dst); - if (src->op != dst->op) - switch (src->op) { - case INT: - p = simplify(CVI, dst, p, NULL); - break; - case UNSIGNED: - if (isfloat(dst)) { - Type ssrc = signedint(src); - Tree two = cnsttree(longdouble, (long double)2.0); - p = (*optree['+'])(ADD, - (*optree['*'])(MUL, - two, - simplify(CVU, ssrc, - simplify(RSH, src, - p, consttree(1, inttype)), NULL)), - simplify(CVU, ssrc, - simplify(BAND, src, - p, consttree(1, unsignedtype)), NULL)); - } else - p = simplify(CVU, dst, p, NULL); - break; - case FLOAT: - if (isunsigned(dst)) { - Type sdst = signedint(dst); - Tree c = cast(cnsttree(longdouble, (long double)sdst->u.sym->u.limits.max.i + 1), src); - p = condtree( - simplify(GE, src, p, c), - (*optree['+'])(ADD, - cast(cast(simplify(SUB, src, p, c), sdst), dst), - cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)), - simplify(CVF, sdst, p, NULL)); - } else - p = simplify(CVF, dst, p, NULL); - break; - default: assert(0); - } - dst = unqual(type); - } - } - src = unqual(p->type); - switch (src->op) { - case INT: - if (src->op != dst->op || src->size != dst->size) - p = simplify(CVI, dst, p, NULL); - break; - case UNSIGNED: - if (src->op != dst->op || src->size != dst->size) - p = simplify(CVU, dst, p, NULL); - break; - case FLOAT: - if (src->op != dst->op || src->size != dst->size) - p = simplify(CVF, dst, p, NULL); - break; - case POINTER: - if (src->op != dst->op) - p = simplify(CVP, dst, p, NULL); - else { - if ((isfunc(src->type) && !isfunc(dst->type)) - || (!isfunc(src->type) && isfunc(dst->type))) - warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type); - - if (src->size != dst->size) - p = simplify(CVP, dst, p, NULL); - } - break; - default: assert(0); - } - return retype(p, type); -} -Tree field(Tree p, const char *name) { - Field q; - Type ty1, ty = p->type; - - if (isptr(ty)) - ty = deref(ty); - ty1 = ty; - ty = unqual(ty); - if ((q = fieldref(name, ty)) != NULL) { - if (isarray(q->type)) { - ty = q->type->type; - if (isconst(ty1) && !isconst(ty)) - ty = qual(CONST, ty); - if (isvolatile(ty1) && !isvolatile(ty)) - ty = qual(VOLATILE, ty); - ty = array(ty, q->type->size/ty->size, q->type->align); - } else { - ty = q->type; - if (isconst(ty1) && !isconst(ty)) - ty = qual(CONST, ty); - if (isvolatile(ty1) && !isvolatile(ty)) - ty = qual(VOLATILE, ty); - ty = ptr(ty); - } - if (YYcheck && !isaddrop(p->op) && q->offset > 0) /* omit */ - p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype)); /* omit */ - else /* omit */ - p = simplify(ADD+P, ty, p, consttree(q->offset, inttype)); - - if (q->lsb) { - p = tree(FIELD, ty->type, rvalue(p), NULL); - p->u.field = q; - } else if (!isarray(q->type)) - p = rvalue(p); - - } else { - error("unknown field `%s' of `%t'\n", name, ty); - p = rvalue(retype(p, ptr(inttype))); - } - return p; -} -/* funcname - return name of function f or a function' */ -char *funcname(Tree f) { - if (isaddrop(f->op)) - return stringf("`%s'", f->u.sym->name); - return "a function"; -} -static Tree nullcheck(Tree p) { - if (!needconst && YYnull && isptr(p->type)) { - p = value(p); - if (strcmp(YYnull->name, "_YYnull") == 0) { - Symbol t1 = temporary(REGISTER, voidptype); - p = tree(RIGHT, p->type, - tree(OR, voidtype, - cond(asgn(t1, cast(p, voidptype))), - vcall(YYnull, voidtype, (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL)), - idtree(t1)); - } - - else - p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L)); - - } - return p; -} -Tree nullcall(Type pty, Symbol f, Tree p, Tree e) { - Type ty; - - if (isarray(pty)) - return retype(nullcall(atop(pty), f, p, e), pty); - ty = unqual(unqual(p->type)->type); - return vcall(f, pty, - p, e, - cnsttree(inttype, (long)ty->size), - cnsttree(inttype, (long)ty->align), - (file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno) , NULL); -} diff --git a/lcc/src/gen.c b/lcc/src/gen.c deleted file mode 100644 index 4ee170d..0000000 --- a/lcc/src/gen.c +++ /dev/null @@ -1,830 +0,0 @@ -#include "c.h" - - -#define readsreg(p) \ - (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P) -#define setsrc(d) ((d) && (d)->x.regnode && \ - (d)->x.regnode->set == src->x.regnode->set && \ - (d)->x.regnode->mask&src->x.regnode->mask) - -#define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b)) - -static Symbol askfixedreg(Symbol); -static Symbol askreg(Symbol, unsigned*); -static void blkunroll(int, int, int, int, int, int, int[]); -static void docall(Node); -static void dumpcover(Node, int, int); -static void dumpregs(char *, char *, char *); -static void dumprule(int); -static void dumptree(Node); -static unsigned emitasm(Node, int); -static void genreload(Node, Symbol, int); -static void genspill(Symbol, Node, Symbol); -static Symbol getreg(Symbol, unsigned*, Node); -static int getrule(Node, int); -static void linearize(Node, Node); -static int moveself(Node); -static void prelabel(Node); -static Node* prune(Node, Node*); -static void putreg(Symbol); -static void ralloc(Node); -static void reduce(Node, int); -static int reprune(Node*, int, int, Node); -static int requate(Node); -static Node reuse(Node, int); -static void rewrite(Node); -static Symbol spillee(Symbol, unsigned mask[], Node); -static void spillr(Symbol, Node); -static int uses(Node, Regnode); - -int offset; - -int maxoffset; - -int framesize; -int argoffset; - -int maxargoffset; - -int dalign, salign; -int bflag = 0; /* omit */ -int dflag = 0; - -int swap; - -unsigned (*emitter)(Node, int) = emitasm; -static char NeedsReg[] = { - 0, /* unused */ - 1, /* CNST */ - 0, 0, /* ARG ASGN */ - 1, /* INDIR */ - 0, 0, 1, 1, /* - - CVF CVI */ - 1, 0, 1, 1, /* CVP - CVU NEG */ - 1, /* CALL */ - 1, /* LOAD */ - 0, /* RET */ - 1, 1, 1, /* ADDRG ADDRF ADDRL */ - 1, 1, 1, 1, 1, /* ADD SUB LSH MOD RSH */ - 1, 1, 1, 1, /* BAND BCOM BOR BXOR */ - 1, 1, /* DIV MUL */ - 0, 0, 0, 0, 0, 0, /* EQ GE GT LE LT NE */ - 0, 0 /* JUMP LABEL */ -}; -Node head; - -unsigned freemask[2]; -unsigned usedmask[2]; -unsigned tmask[2]; -unsigned vmask[2]; -Symbol mkreg(char *fmt, int n, int mask, int set) { - Symbol p; - - NEW0(p, PERM); - p->name = p->x.name = stringf(fmt, n); - NEW0(p->x.regnode, PERM); - p->x.regnode->number = n; - p->x.regnode->mask = mask<<n; - p->x.regnode->set = set; - return p; -} -Symbol mkwildcard(Symbol *syms) { - Symbol p; - - NEW0(p, PERM); - p->name = p->x.name = "wildcard"; - p->x.wildcard = syms; - return p; -} -void mkauto(Symbol p) { - assert(p->sclass == AUTO); - offset = roundup(offset + p->type->size, p->type->align); - p->x.offset = -offset; - p->x.name = stringd(-offset); -} -void blockbeg(Env *e) { - e->offset = offset; - e->freemask[IREG] = freemask[IREG]; - e->freemask[FREG] = freemask[FREG]; -} -void blockend(Env *e) { - if (offset > maxoffset) - maxoffset = offset; - offset = e->offset; - freemask[IREG] = e->freemask[IREG]; - freemask[FREG] = e->freemask[FREG]; -} -int mkactual(int align, int size) { - int n = roundup(argoffset, align); - - argoffset = n + size; - return n; -} -static void docall(Node p) { - p->syms[1] = p->syms[0]; - p->syms[0] = intconst(argoffset); - if (argoffset > maxargoffset) - maxargoffset = argoffset; - argoffset = 0; -} -void blkcopy(int dreg, int doff, int sreg, int soff, int size, int tmp[]) { - assert(size >= 0); - if (size == 0) - return; - else if (size <= 2) - blkunroll(size, dreg, doff, sreg, soff, size, tmp); - else if (size == 3) { - blkunroll(2, dreg, doff, sreg, soff, 2, tmp); - blkunroll(1, dreg, doff+2, sreg, soff+2, 1, tmp); - } - else if (size <= 16) { - blkunroll(4, dreg, doff, sreg, soff, size&~3, tmp); - blkcopy(dreg, doff+(size&~3), - sreg, soff+(size&~3), size&3, tmp); - } - else - (*IR->x.blkloop)(dreg, doff, sreg, soff, size, tmp); -} -static void blkunroll(int k, int dreg, int doff, int sreg, int soff, int size, int tmp[]) { - int i; - - assert(IR->x.max_unaligned_load); - if (k > IR->x.max_unaligned_load - && (k > salign || k > dalign)) - k = IR->x.max_unaligned_load; - for (i = 0; i+k < size; i += 2*k) { - (*IR->x.blkfetch)(k, soff+i, sreg, tmp[0]); - (*IR->x.blkfetch)(k, soff+i+k, sreg, tmp[1]); - (*IR->x.blkstore)(k, doff+i, dreg, tmp[0]); - (*IR->x.blkstore)(k, doff+i+k, dreg, tmp[1]); - } - if (i < size) { - (*IR->x.blkfetch)(k, i+soff, sreg, tmp[0]); - (*IR->x.blkstore)(k, i+doff, dreg, tmp[0]); - } -} -void parseflags(int argc, char *argv[]) { - int i; - - for (i = 0; i < argc; i++) - if (strcmp(argv[i], "-d") == 0) - dflag = 1; - else if (strcmp(argv[i], "-b") == 0) /* omit */ - bflag = 1; /* omit */ -} -static int getrule(Node p, int nt) { - int rulenum; - - assert(p); - rulenum = (*IR->x._rule)(p->x.state, nt); - if (!rulenum) { - fprint(stderr, "(%x->op=%s at %w is corrupt.)\n", p, opname(p->op), &src); - assert(0); - } - return rulenum; -} -static void reduce(Node p, int nt) { - int rulenum, i; - short *nts; - Node kids[10]; - - p = reuse(p, nt); - rulenum = getrule(p, nt); - nts = IR->x._nts[rulenum]; - (*IR->x._kids)(p, rulenum, kids); - for (i = 0; nts[i]; i++) - reduce(kids[i], nts[i]); - if (IR->x._isinstruction[rulenum]) { - assert(p->x.inst == 0 || p->x.inst == nt); - p->x.inst = nt; - if (p->syms[RX] && p->syms[RX]->temporary) { - debug(fprint(stderr, "(using %s)\n", p->syms[RX]->name)); - p->syms[RX]->x.usecount++; - } - } -} -static Node reuse(Node p, int nt) { - struct _state { - short cost[1]; - }; - Symbol r = p->syms[RX]; - - if (generic(p->op) == INDIR && p->kids[0]->op == VREG+P - && r->u.t.cse && p->x.mayrecalc - && ((struct _state*)r->u.t.cse->x.state)->cost[nt] == 0) - return r->u.t.cse; - else - return p; -} - -int mayrecalc(Node p) { - int op; - - assert(p && p->syms[RX]); - if (p->syms[RX]->u.t.cse == NULL) - return 0; - op = generic(p->syms[RX]->u.t.cse->op); - if (op == CNST || op == ADDRF || op == ADDRG || op == ADDRL) { - p->x.mayrecalc = 1; - return 1; - } else - return 0; -} -static Node *prune(Node p, Node pp[]) { - if (p == NULL) - return pp; - p->x.kids[0] = p->x.kids[1] = p->x.kids[2] = NULL; - if (p->x.inst == 0) - return prune(p->kids[1], prune(p->kids[0], pp)); - else if (p->syms[RX] && p->syms[RX]->temporary - && p->syms[RX]->x.usecount < 2) { - p->x.inst = 0; - debug(fprint(stderr, "(clobbering %s)\n", p->syms[RX]->name)); - return prune(p->kids[1], prune(p->kids[0], pp)); - } - else { - prune(p->kids[1], prune(p->kids[0], &p->x.kids[0])); - *pp = p; - return pp + 1; - } -} - -#define ck(i) return (i) ? 0 : LBURG_MAX - -int range(Node p, int lo, int hi) { - Symbol s = p->syms[0]; - - switch (specific(p->op)) { - case ADDRF+P: - case ADDRL+P: ck(s->x.offset >= lo && s->x.offset <= hi); - case CNST+I: ck(s->u.c.v.i >= lo && s->u.c.v.i <= hi); - case CNST+U: ck(s->u.c.v.u >= lo && s->u.c.v.u <= hi); - case CNST+P: ck(s->u.c.v.p == 0 && lo <= 0 && hi >= 0); - } - return LBURG_MAX; -} -static void dumptree(Node p) { - if (p->op == VREG+P && p->syms[0]) { - fprint(stderr, "VREGP(%s)", p->syms[0]->name); - return; - } else if (generic(p->op) == LOAD) { - fprint(stderr, "LOAD("); - dumptree(p->kids[0]); - fprint(stderr, ")"); - return; - } - fprint(stderr, "%s(", opname(p->op)); - switch (generic(p->op)) { - case CNST: case LABEL: - case ADDRG: case ADDRF: case ADDRL: - if (p->syms[0]) - fprint(stderr, "%s", p->syms[0]->name); - break; - case RET: - if (p->kids[0]) - dumptree(p->kids[0]); - break; - case CVF: case CVI: case CVP: case CVU: case JUMP: - case ARG: case BCOM: case NEG: case INDIR: - dumptree(p->kids[0]); - break; - case CALL: - if (optype(p->op) != B) { - dumptree(p->kids[0]); - break; - } - /* else fall thru */ - case EQ: case NE: case GT: case GE: case LE: case LT: - case ASGN: case BOR: case BAND: case BXOR: case RSH: case LSH: - case ADD: case SUB: case DIV: case MUL: case MOD: - dumptree(p->kids[0]); - fprint(stderr, ", "); - dumptree(p->kids[1]); - break; - default: assert(0); - } - fprint(stderr, ")"); -} -static void dumpcover(Node p, int nt, int in) { - int rulenum, i; - short *nts; - Node kids[10]; - - p = reuse(p, nt); - rulenum = getrule(p, nt); - nts = IR->x._nts[rulenum]; - fprint(stderr, "dumpcover(%x) = ", p); - for (i = 0; i < in; i++) - fprint(stderr, " "); - dumprule(rulenum); - (*IR->x._kids)(p, rulenum, kids); - for (i = 0; nts[i]; i++) - dumpcover(kids[i], nts[i], in+1); -} - -static void dumprule(int rulenum) { - assert(rulenum); - fprint(stderr, "%s / %s", IR->x._string[rulenum], - IR->x._templates[rulenum]); - if (!IR->x._isinstruction[rulenum]) - fprint(stderr, "\n"); -} -static unsigned emitasm(Node p, int nt) { - int rulenum; - short *nts; - char *fmt; - Node kids[10]; - - p = reuse(p, nt); - rulenum = getrule(p, nt); - nts = IR->x._nts[rulenum]; - fmt = IR->x._templates[rulenum]; - assert(fmt); - if (IR->x._isinstruction[rulenum] && p->x.emitted) - print("%s", p->syms[RX]->x.name); - else if (*fmt == '#') - (*IR->x.emit2)(p); - else { - if (*fmt == '?') { - fmt++; - assert(p->kids[0]); - if (p->syms[RX] == p->x.kids[0]->syms[RX]) - while (*fmt++ != '\n') - ; - } - for ((*IR->x._kids)(p, rulenum, kids); *fmt; fmt++) - if (*fmt != '%') - (void)putchar(*fmt); - else if (*++fmt == 'F') - print("%d", framesize); - else if (*fmt >= '0' && *fmt <= '9') - emitasm(kids[*fmt - '0'], nts[*fmt - '0']); - else if (*fmt >= 'a' && *fmt < 'a' + NELEMS(p->syms)) - fputs(p->syms[*fmt - 'a']->x.name, stdout); - else - (void)putchar(*fmt); - } - return 0; -} -void emit(Node p) { - for (; p; p = p->x.next) { - assert(p->x.registered); - if ((p->x.equatable && requate(p)) || moveself(p)) - ; - else - (*emitter)(p, p->x.inst); - p->x.emitted = 1; - } -} -static int moveself(Node p) { - return p->x.copy - && p->syms[RX]->x.name == p->x.kids[0]->syms[RX]->x.name; -} -int move(Node p) { - p->x.copy = 1; - return 1; -} -static int requate(Node q) { - Symbol src = q->x.kids[0]->syms[RX]; - Symbol tmp = q->syms[RX]; - Node p; - int n = 0; - - debug(fprint(stderr, "(requate(%x): tmp=%s src=%s)\n", q, tmp->x.name, src->x.name)); - for (p = q->x.next; p; p = p->x.next) - if (p->x.copy && p->syms[RX] == src - && p->x.kids[0]->syms[RX] == tmp) - debug(fprint(stderr, "(requate arm 0 at %x)\n", p)), - p->syms[RX] = tmp; - else if (setsrc(p->syms[RX]) && !moveself(p) && !readsreg(p)) - return 0; - else if (p->x.spills) - return 0; - else if (generic(p->op) == CALL && p->x.next) - return 0; - else if (p->op == LABEL+V && p->x.next) - return 0; - else if (p->syms[RX] == tmp && readsreg(p)) - debug(fprint(stderr, "(requate arm 5 at %x)\n", p)), - n++; - else if (p->syms[RX] == tmp) - break; - debug(fprint(stderr, "(requate arm 7 at %x)\n", p)); - assert(n > 0); - for (p = q->x.next; p; p = p->x.next) - if (p->syms[RX] == tmp && readsreg(p)) { - p->syms[RX] = src; - if (--n <= 0) - break; - } - return 1; -} -static void prelabel(Node p) { - if (p == NULL) - return; - prelabel(p->kids[0]); - prelabel(p->kids[1]); - if (NeedsReg[opindex(p->op)]) - setreg(p, (*IR->x.rmap)(opkind(p->op))); - switch (generic(p->op)) { - case ADDRF: case ADDRL: - if (p->syms[0]->sclass == REGISTER) - p->op = VREG+P; - break; - case INDIR: - if (p->kids[0]->op == VREG+P) - setreg(p, p->kids[0]->syms[0]); - break; - case ASGN: - if (p->kids[0]->op == VREG+P) - rtarget(p, 1, p->kids[0]->syms[0]); - break; - case CVI: case CVU: case CVP: - if (optype(p->op) != F - && opsize(p->op) <= p->syms[0]->u.c.v.i) - p->op = LOAD + opkind(p->op); - break; - } - (IR->x.target)(p); -} -void setreg(Node p, Symbol r) { - p->syms[RX] = r; -} -void rtarget(Node p, int n, Symbol r) { - Node q = p->kids[n]; - - assert(q); - assert(r); - assert(r->sclass == REGISTER || !r->x.wildcard); - assert(q->syms[RX]); - if (r != q->syms[RX] && !q->syms[RX]->x.wildcard) { - q = newnode(LOAD + opkind(q->op), - q, NULL, q->syms[0]); - if (r->u.t.cse == p->kids[n]) - r->u.t.cse = q; - p->kids[n] = p->x.kids[n] = q; - q->x.kids[0] = q->kids[0]; - } - setreg(q, r); - debug(fprint(stderr, "(targeting %x->x.kids[%d]=%x to %s)\n", p, n, p->kids[n], r->x.name)); -} -static void rewrite(Node p) { - assert(p->x.inst == 0); - prelabel(p); - debug(dumptree(p)); - debug(fprint(stderr, "\n")); - (*IR->x._label)(p); - debug(dumpcover(p, 1, 0)); - reduce(p, 1); -} -Node gen(Node forest) { - int i; - struct node sentinel; - Node dummy, p; - - head = forest; - for (p = forest; p; p = p->link) { - assert(p->count == 0); - if (generic(p->op) == CALL) - docall(p); - else if ( generic(p->op) == ASGN - && generic(p->kids[1]->op) == CALL) - docall(p->kids[1]); - else if (generic(p->op) == ARG) - (*IR->x.doarg)(p); - rewrite(p); - p->x.listed = 1; - } - for (p = forest; p; p = p->link) - prune(p, &dummy); - relink(&sentinel, &sentinel); - for (p = forest; p; p = p->link) - linearize(p, &sentinel); - forest = sentinel.x.next; - assert(forest); - sentinel.x.next->x.prev = NULL; - sentinel.x.prev->x.next = NULL; - for (p = forest; p; p = p->x.next) - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { - assert(p->x.kids[i]->syms[RX]); - if (p->x.kids[i]->syms[RX]->temporary) { - p->x.kids[i]->x.prevuse = - p->x.kids[i]->syms[RX]->x.lastuse; - p->x.kids[i]->syms[RX]->x.lastuse = p->x.kids[i]; - } - } - for (p = forest; p; p = p->x.next) { - ralloc(p); - if (p->x.listed && NeedsReg[opindex(p->op)] - && (*IR->x.rmap)(opkind(p->op))) { - assert(generic(p->op) == CALL || generic(p->op) == LOAD); - putreg(p->syms[RX]); - } - } - return forest; -} -int notarget(Node p) { - return p->syms[RX]->x.wildcard ? 0 : LBURG_MAX; -} -static void putreg(Symbol r) { - assert(r && r->x.regnode); - freemask[r->x.regnode->set] |= r->x.regnode->mask; - debug(dumpregs("(freeing %s)\n", r->x.name, NULL)); -} -static Symbol askfixedreg(Symbol s) { - Regnode r = s->x.regnode; - int n = r->set; - - if (r->mask&~freemask[n]) - return NULL; - else { - freemask[n] &= ~r->mask; - usedmask[n] |= r->mask; - return s; - } -} -static Symbol askreg(Symbol rs, unsigned rmask[]) { - int i; - - if (rs->x.wildcard == NULL) - return askfixedreg(rs); - for (i = 31; i >= 0; i--) { - Symbol r = rs->x.wildcard[i]; - if (r != NULL - && !(r->x.regnode->mask&~rmask[r->x.regnode->set]) - && askfixedreg(r)) - return r; - } - return NULL; -} - -static Symbol getreg(Symbol s, unsigned mask[], Node p) { - Symbol r = askreg(s, mask); - if (r == NULL) { - r = spillee(s, mask, p); - assert(r && r->x.regnode); - spill(r->x.regnode->mask, r->x.regnode->set, p); - r = askreg(s, mask); - } - assert(r && r->x.regnode); - r->x.regnode->vbl = NULL; - return r; -} -int askregvar(Symbol p, Symbol regs) { - Symbol r; - - assert(p); - if (p->sclass != REGISTER) - return 0; - else if (!isscalar(p->type)) { - p->sclass = AUTO; - return 0; - } - else if (p->temporary) { - p->x.name = "?"; - return 1; - } - else if ((r = askreg(regs, vmask)) != NULL) { - p->x.regnode = r->x.regnode; - p->x.regnode->vbl = p; - p->x.name = r->x.name; - debug(dumpregs("(allocating %s to symbol %s)\n", p->x.name, p->name)); - return 1; - } - else { - p->sclass = AUTO; - return 0; - } -} -static void linearize(Node p, Node next) { - int i; - - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) - linearize(p->x.kids[i], next); - relink(next->x.prev, p); - relink(p, next); - debug(fprint(stderr, "(listing %x)\n", p)); -} -static void ralloc(Node p) { - int i; - unsigned mask[2]; - - mask[0] = tmask[0]; - mask[1] = tmask[1]; - assert(p); - debug(fprint(stderr, "(rallocing %x)\n", p)); - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { - Node kid = p->x.kids[i]; - Symbol r = kid->syms[RX]; - assert(r && kid->x.registered); - if (r->sclass != REGISTER && r->x.lastuse == kid) - putreg(r); - } - if (!p->x.registered && NeedsReg[opindex(p->op)] - && (*IR->x.rmap)(opkind(p->op))) { - Symbol sym = p->syms[RX], set = sym; - assert(sym); - if (sym->temporary) - set = (*IR->x.rmap)(opkind(p->op)); - assert(set); - if (set->sclass != REGISTER) { - Symbol r; - if (*IR->x._templates[getrule(p, p->x.inst)] == '?') - for (i = 1; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { - Symbol r = p->x.kids[i]->syms[RX]; - assert(p->x.kids[i]->x.registered); - assert(r && r->x.regnode); - assert(sym->x.wildcard || sym != r); - mask[r->x.regnode->set] &= ~r->x.regnode->mask; - } - r = getreg(set, mask, p); - if (sym->temporary) { - Node q; - r->x.lastuse = sym->x.lastuse; - for (q = sym->x.lastuse; q; q = q->x.prevuse) { - q->syms[RX] = r; - q->x.registered = 1; - if (sym->u.t.cse && q->x.copy) - q->x.equatable = 1; - } - } else { - p->syms[RX] = r; - r->x.lastuse = p; - } - debug(dumpregs("(allocating %s to node %x)\n", r->x.name, (char *) p)); - } - } - p->x.registered = 1; - (*IR->x.clobber)(p); -} -static Symbol spillee(Symbol set, unsigned mask[], Node here) { - Symbol bestreg = NULL; - int bestdist = -1, i; - - assert(set); - if (!set->x.wildcard) - bestreg = set; - else { - for (i = 31; i >= 0; i--) { - Symbol ri = set->x.wildcard[i]; - if ( - ri != NULL && - ri->x.lastuse && - (ri->x.regnode->mask&tmask[ri->x.regnode->set]&mask[ri->x.regnode->set]) - ) { - Regnode rn = ri->x.regnode; - Node q = here; - int dist = 0; - for (; q && !uses(q, rn); q = q->x.next) - dist++; - if (q && dist > bestdist) { - bestdist = dist; - bestreg = ri; - } - } - } - } - assert(bestreg); /* Must be able to spill something. Reconfigure the register allocator - to ensure that we can allocate a register for all nodes without spilling - the node's necessary input regs. */ - assert(bestreg->x.regnode->vbl == NULL); /* Can't spill register variables because - the reload site might be in other blocks. Reconfigure the register allocator - to ensure that this register is never allocated to a variable. */ - return bestreg; -} -static int uses(Node p, Regnode rn) { - int i; - - for (i = 0; i < NELEMS(p->x.kids); i++) - if ( - p->x.kids[i] && - p->x.kids[i]->x.registered && - rn->set == p->x.kids[i]->syms[RX]->x.regnode->set && - (rn->mask&p->x.kids[i]->syms[RX]->x.regnode->mask) - ) - return 1; - return 0; -} -static void spillr(Symbol r, Node here) { - int i; - Symbol tmp; - Node p = r->x.lastuse; - assert(p); - while (p->x.prevuse) - assert(r == p->syms[RX]), - p = p->x.prevuse; - assert(p->x.registered && !readsreg(p)); - tmp = newtemp(AUTO, optype(p->op), opsize(p->op)); - genspill(r, p, tmp); - for (p = here->x.next; p; p = p->x.next) - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { - Node k = p->x.kids[i]; - if (k->x.registered && k->syms[RX] == r) - genreload(p, tmp, i); - } - putreg(r); -} -static void genspill(Symbol r, Node last, Symbol tmp) { - Node p, q; - Symbol s; - unsigned ty; - - debug(fprint(stderr, "(spilling %s to local %s)\n", r->x.name, tmp->x.name)); - debug(fprint(stderr, "(genspill: ")); - debug(dumptree(last)); - debug(fprint(stderr, ")\n")); - ty = opkind(last->op); - NEW0(s, FUNC); - s->sclass = REGISTER; - s->name = s->x.name = r->x.name; - s->x.regnode = r->x.regnode; - q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, s); - q = newnode(INDIR + ty, q, NULL, NULL); - p = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp); - p = newnode(ASGN + ty, p, q, NULL); - p->x.spills = 1; - rewrite(p); - prune(p, &q); - q = last->x.next; - linearize(p, q); - for (p = last->x.next; p != q; p = p->x.next) { - ralloc(p); - assert(!p->x.listed || !NeedsReg[opindex(p->op)] || !(*IR->x.rmap)(opkind(p->op))); - } -} - -static void genreload(Node p, Symbol tmp, int i) { - Node q; - int ty; - - debug(fprint(stderr, "(replacing %x with a reload from %s)\n", p->x.kids[i], tmp->x.name)); - debug(fprint(stderr, "(genreload: ")); - debug(dumptree(p->x.kids[i])); - debug(fprint(stderr, ")\n")); - ty = opkind(p->x.kids[i]->op); - q = newnode(ADDRL+P + sizeop(IR->ptrmetric.size), NULL, NULL, tmp); - p->x.kids[i] = newnode(INDIR + ty, q, NULL, NULL); - rewrite(p->x.kids[i]); - prune(p->x.kids[i], &q); - reprune(&p->kids[1], reprune(&p->kids[0], 0, i, p), i, p); - prune(p, &q); - linearize(p->x.kids[i], p); -} -static int reprune(Node *pp, int k, int n, Node p) { - struct node x, *q = *pp; - - if (q == NULL || k > n) - return k; - else if (q->x.inst == 0) - return reprune(&q->kids[1], - reprune(&q->kids[0], k, n, p), n, p); - if (k == n) { - debug(fprint(stderr, "(reprune changes %x from %x to %x)\n", pp, *pp, p->x.kids[n])); - *pp = p->x.kids[n]; - x = *p; - (IR->x.target)(&x); - } - return k + 1; -} -void spill(unsigned mask, int n, Node here) { - int i; - Node p; - - here->x.spills = 1; - usedmask[n] |= mask; - if (mask&~freemask[n]) { - - assert( /* It makes no sense for a node to clobber() its target. */ - here->x.registered == 0 || /* call isn't coming through clobber() */ - here->syms[RX] == NULL || - here->syms[RX]->x.regnode == NULL || - here->syms[RX]->x.regnode->set != n || - (here->syms[RX]->x.regnode->mask&mask) == 0 - ); - - for (p = here; p; p = p->x.next) - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { - Symbol r = p->x.kids[i]->syms[RX]; - assert(r); - if (p->x.kids[i]->x.registered && r->x.regnode->set == n - && r->x.regnode->mask&mask) - spillr(r, here); - } - } -} -static void dumpregs(char *msg, char *a, char *b) { - fprint(stderr, msg, a, b); - fprint(stderr, "(free[0]=%x)\n", freemask[0]); - fprint(stderr, "(free[1]=%x)\n", freemask[1]); -} - -int getregnum(Node p) { - assert(p && p->syms[RX] && p->syms[RX]->x.regnode); - return p->syms[RX]->x.regnode->number; -} - - -unsigned regloc(Symbol p) { - assert(p && p->sclass == REGISTER && p->sclass == REGISTER && p->x.regnode); - return p->x.regnode->set<<8 | p->x.regnode->number; -} - diff --git a/lcc/src/init.c b/lcc/src/init.c deleted file mode 100644 index 172d7c0..0000000 --- a/lcc/src/init.c +++ /dev/null @@ -1,318 +0,0 @@ -#include "c.h" - - -static int curseg; /* current segment */ - -/* defpointer - initialize a pointer to p or to 0 if p==0 */ -void defpointer(Symbol p) { - if (p) { - (*IR->defaddress)(p); - p->ref++; - } else { - static Value v; - (*IR->defconst)(P, voidptype->size, v); - } -} - -/* genconst - generate/check constant expression e; return size */ -static int genconst(Tree e, int def) { - for (;;) - switch (generic(e->op)) { - case ADDRG: - if (def) - (*IR->defaddress)(e->u.sym); - return e->type->size; - case CNST: - if (e->op == CNST+P && isarray(e->type)) { - e = cvtconst(e); - continue; - } - if (def) - (*IR->defconst)(e->type->op, e->type->size, e->u.v); - return e->type->size; - case RIGHT: - assert(e->kids[0] || e->kids[1]); - if (e->kids[1] && e->kids[0]) - error("initializer must be constant\n"); - e = e->kids[1] ? e->kids[1] : e->kids[0]; - continue; - case CVP: - if (isarith(e->type)) - error("cast from `%t' to `%t' is illegal in constant expressions\n", - e->kids[0]->type, e->type); - /* fall thru */ - case CVI: case CVU: case CVF: - e = e->kids[0]; - continue; - default: - error("initializer must be constant\n"); - if (def) - genconst(consttree(0, inttype), def); - return inttype->size; - } -} - -/* initvalue - evaluate a constant expression for a value of integer type ty */ -static Tree initvalue(Type ty) { - Type aty; - Tree e; - - needconst++; - e = expr1(0); - if ((aty = assign(ty, e)) != NULL) - e = cast(e, aty); - else { - error("invalid initialization type; found `%t' expected `%t'\n", - e->type, ty); - e = retype(consttree(0, inttype), ty); - } - needconst--; - if (generic(e->op) != CNST) { - error("initializer must be constant\n"); - e = retype(consttree(0, inttype), ty); - } - return e; -} - -/* initarray - initialize array of ty of <= len bytes; if len == 0, go to } */ -static int initarray(int len, Type ty, int lev) { - int n = 0; - - do { - initializer(ty, lev); - n += ty->size; - if ((len > 0 && n >= len) || t != ',') - break; - t = gettok(); - } while (t != '}'); - return n; -} - -/* initchar - initialize array of <= len ty characters; if len == 0, go to } */ -static int initchar(int len, Type ty) { - int n = 0; - char buf[16], *s = buf; - - do { - *s++ = initvalue(ty)->u.v.i; - if (++n%inttype->size == 0) { - (*IR->defstring)(inttype->size, buf); - s = buf; - } - if ((len > 0 && n >= len) || t != ',') - break; - t = gettok(); - } while (t != '}'); - if (s > buf) - (*IR->defstring)(s - buf, buf); - return n; -} - -/* initend - finish off an initialization at level lev; accepts trailing comma */ -static void initend(int lev, char follow[]) { - if (lev == 0 && t == ',') - t = gettok(); - test('}', follow); -} - -/* initfields - initialize <= an unsigned's worth of bit fields in fields p to q */ -static int initfields(Field p, Field q) { - unsigned int bits = 0; - int i, n = 0; - - do { - i = initvalue(inttype)->u.v.i; - if (fieldsize(p) < 8*p->type->size) { - if ((p->type == inttype && - (i < -(int)(fieldmask(p)>>1)-1 || i > (int)(fieldmask(p)>>1))) - || (p->type == unsignedtype && (i&~fieldmask(p)) != 0)) - warning("initializer exceeds bit-field width\n"); - i &= fieldmask(p); - } - bits |= i<<fieldright(p); - if (IR->little_endian) { - if (fieldsize(p) + fieldright(p) > n) - n = fieldsize(p) + fieldright(p); - } else { - if (fieldsize(p) + fieldleft(p) > n) - n = fieldsize(p) + fieldleft(p); - } - if (p->link == q) - break; - p = p->link; - } while (t == ',' && (t = gettok()) != 0); - n = (n + 7)/8; - for (i = 0; i < n; i++) { - Value v; - if (IR->little_endian) { - v.u = (unsigned char)bits; - bits >>= 8; - } else { /* a big endian */ - v.u = (unsigned char)(bits>>(8*(unsignedtype->size - 1))); - bits <<= 8; - } - (*IR->defconst)(U, unsignedchar->size, v); - } - return n; -} - -/* initstruct - initialize a struct ty of <= len bytes; if len == 0, go to } */ -static int initstruct(int len, Type ty, int lev) { - int a, n = 0; - Field p = ty->u.sym->u.s.flist; - - do { - if (p->offset > n) { - (*IR->space)(p->offset - n); - n += p->offset - n; - } - if (p->lsb) { - Field q = p; - while (q->link && q->link->offset == p->offset) - q = q->link; - n += initfields(p, q->link); - p = q; - } else { - initializer(p->type, lev); - n += p->type->size; - } - if (p->link) { - p = p->link; - a = p->type->align; - } else - a = ty->align; - if (a && n%a) { - (*IR->space)(a - n%a); - n = roundup(n, a); - } - if ((len > 0 && n >= len) || t != ',') - break; - t = gettok(); - } while (t != '}'); - return n; -} - -/* initializer - constexpr | { constexpr ( , constexpr )* [ , ] } */ -Type initializer(Type ty, int lev) { - int n = 0; - Tree e; - Type aty = NULL; - static char follow[] = { IF, CHAR, STATIC, 0 }; - - ty = unqual(ty); - if (isscalar(ty)) { - needconst++; - if (t == '{') { - t = gettok(); - e = expr1(0); - initend(lev, follow); - } else - e = expr1(0); - e = pointer(e); - if ((aty = assign(ty, e)) != NULL) - e = cast(e, aty); - else - error("invalid initialization type; found `%t' expected `%t'\n", - e->type, ty); - n = genconst(e, 1); - deallocate(STMT); - needconst--; - } - if ((isunion(ty) || isstruct(ty)) && ty->size == 0) { - static char follow[] = { CHAR, STATIC, 0 }; - error("cannot initialize undefined `%t'\n", ty); - skipto(';', follow); - return ty; - } else if (isunion(ty)) { - if (t == '{') { - t = gettok(); - n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1); - initend(lev, follow); - } else { - if (lev == 0) - error("missing { in initialization of `%t'\n", ty); - n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1); - } - } else if (isstruct(ty)) { - if (t == '{') { - t = gettok(); - n = initstruct(0, ty, lev + 1); - test('}', follow); - } else if (lev > 0) - n = initstruct(ty->size, ty, lev + 1); - else { - error("missing { in initialization of `%t'\n", ty); - n = initstruct(ty->u.sym->u.s.flist->type->size, ty, lev + 1); - } - } - if (isarray(ty)) - aty = unqual(ty->type); - if (isarray(ty) && ischar(aty)) { - if (t == SCON) { - if (ty->size > 0 && ty->size == tsym->type->size - 1) - tsym->type = array(chartype, ty->size, 0); - n = tsym->type->size; - (*IR->defstring)(tsym->type->size, tsym->u.c.v.p); - t = gettok(); - } else if (t == '{') { - t = gettok(); - if (t == SCON) { - ty = initializer(ty, lev + 1); - initend(lev, follow); - return ty; - } - n = initchar(0, aty); - test('}', follow); - } else if (lev > 0 && ty->size > 0) - n = initchar(ty->size, aty); - else { /* eg, char c[] = 0; */ - error("missing { in initialization of `%t'\n", ty); - n = initchar(1, aty); - } - } else if (isarray(ty)) { - if (t == SCON && aty == widechar) { - int i; - unsigned int *s = tsym->u.c.v.p; - if (ty->size > 0 && ty->size == tsym->type->size - widechar->size) - tsym->type = array(widechar, ty->size/widechar->size, 0); - n = tsym->type->size; - for (i = 0; i < n; i += widechar->size) { - Value v; - v.u = *s++; - (*IR->defconst)(widechar->op, widechar->size, v); - } - t = gettok(); - } else if (t == '{') { - t = gettok(); - if (t == SCON && aty == widechar) { - ty = initializer(ty, lev + 1); - initend(lev, follow); - return ty; - } - n = initarray(0, aty, lev + 1); - test('}', follow); - } else if (lev > 0 && ty->size > 0) - n = initarray(ty->size, aty, lev + 1); - else { - error("missing { in initialization of `%t'\n", ty); - n = initarray(aty->size, aty, lev + 1); - } - } - if (ty->size) { - if (n > ty->size) - error("too many initializers\n"); - else if (n < ty->size) - (*IR->space)(ty->size - n); - } else if (isarray(ty) && ty->type->size > 0) - ty = array(ty->type, n/ty->type->size, 0); - else - ty->size = n; - return ty; -} - -/* swtoseg - switch to segment seg, if necessary */ -void swtoseg(int seg) { - if (curseg != seg) - (*IR->segment)(seg); - curseg = seg; -} diff --git a/lcc/src/inits.c b/lcc/src/inits.c deleted file mode 100644 index c42f61e..0000000 --- a/lcc/src/inits.c +++ /dev/null @@ -1,7 +0,0 @@ -void init(int argc, char *argv[]) { - {extern void input_init(int, char *[]); input_init(argc, argv);} - {extern void main_init(int, char *[]); main_init(argc, argv);} - {extern void prof_init(int, char *[]); prof_init(argc, argv);} - {extern void trace_init(int, char *[]); trace_init(argc, argv);} - {extern void type_init(int, char *[]); type_init(argc, argv);} -} diff --git a/lcc/src/input.c b/lcc/src/input.c deleted file mode 100644 index c2a084e..0000000 --- a/lcc/src/input.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "c.h" - - -static void pragma(void); -static void resynch(void); - -static int bsize; -static unsigned char buffer[MAXLINE+1 + BUFSIZE+1]; -unsigned char *cp; /* current input character */ -char *file; /* current input file name */ -char *firstfile; /* first input file */ -unsigned char *limit; /* points to last character + 1 */ -char *line; /* current line */ -int lineno; /* line number of current line */ - -void nextline(void) { - do { - if (cp >= limit) { - fillbuf(); - if (cp >= limit) - cp = limit; - if (cp == limit) - return; - } else { - lineno++; - for (line = (char *)cp; *cp==' ' || *cp=='\t'; cp++) - ; - if (*cp == '#') { - resynch(); - nextline(); - } - } - } while (*cp == '\n' && cp == limit); -} -void fillbuf(void) { - if (bsize == 0) - return; - if (cp >= limit) - cp = &buffer[MAXLINE+1]; - else - { - int n = limit - cp; - unsigned char *s = &buffer[MAXLINE+1] - n; - assert(s >= buffer); - line = (char *)s - ((char *)cp - line); - while (cp < limit) - *s++ = *cp++; - cp = &buffer[MAXLINE+1] - n; - } - if (feof(stdin)) - bsize = 0; - else - bsize = fread(&buffer[MAXLINE+1], 1, BUFSIZE, stdin); - if (bsize < 0) { - error("read error\n"); - exit(EXIT_FAILURE); - } - limit = &buffer[MAXLINE+1+bsize]; - *limit = '\n'; -} -void input_init(int argc, char *argv[]) { - static int inited; - - if (inited) - return; - inited = 1; - main_init(argc, argv); - limit = cp = &buffer[MAXLINE+1]; - bsize = -1; - lineno = 0; - file = NULL; - fillbuf(); - if (cp >= limit) - cp = limit; - nextline(); -} - -/* pragma - handle #pragma ref id... */ -static void pragma(void) { - if ((t = gettok()) == ID && strcmp(token, "ref") == 0) - for (;;) { - while (*cp == ' ' || *cp == '\t') - cp++; - if (*cp == '\n' || *cp == 0) - break; - if ((t = gettok()) == ID && tsym) { - tsym->ref++; - use(tsym, src); - } - } -} - -/* resynch - set line number/file name in # n [ "file" ] and #pragma ... */ -static void resynch(void) { - for (cp++; *cp == ' ' || *cp == '\t'; ) - cp++; - if (limit - cp < MAXLINE) - fillbuf(); - if (strncmp((char *)cp, "pragma", 6) == 0) { - cp += 6; - pragma(); - } else if (*cp >= '0' && *cp <= '9') { - line: for (lineno = 0; *cp >= '0' && *cp <= '9'; ) - lineno = 10*lineno + *cp++ - '0'; - lineno--; - while (*cp == ' ' || *cp == '\t') - cp++; - if (*cp == '"') { - file = (char *)++cp; - while (*cp && *cp != '"' && *cp != '\n') - cp++; - file = stringn(file, (char *)cp - file); - if (*cp == '\n') - warning("missing \" in preprocessor line\n"); - if (firstfile == 0) - firstfile = file; - } - } else if (strncmp((char *)cp, "line", 4) == 0) { - for (cp += 4; *cp == ' ' || *cp == '\t'; ) - cp++; - if (*cp >= '0' && *cp <= '9') - goto line; - if (Aflag >= 2) - warning("unrecognized control line\n"); - } else if (Aflag >= 2 && *cp != '\n') - warning("unrecognized control line\n"); - while (*cp) - if (*cp++ == '\n') { - if (cp == limit + 1) - nextline(); - else - break; - } -} - diff --git a/lcc/src/lex.c b/lcc/src/lex.c deleted file mode 100644 index ec2f1ec..0000000 --- a/lcc/src/lex.c +++ /dev/null @@ -1,923 +0,0 @@ -#include "c.h" -#include <float.h> -#include <errno.h> - - -#define MAXTOKEN 32 - -enum { BLANK=01, NEWLINE=02, LETTER=04, - DIGIT=010, HEX=020, OTHER=040 }; - -static unsigned char map[256] = { /* 000 nul */ 0, - /* 001 soh */ 0, - /* 002 stx */ 0, - /* 003 etx */ 0, - /* 004 eot */ 0, - /* 005 enq */ 0, - /* 006 ack */ 0, - /* 007 bel */ 0, - /* 010 bs */ 0, - /* 011 ht */ BLANK, - /* 012 nl */ NEWLINE, - /* 013 vt */ BLANK, - /* 014 ff */ BLANK, - /* 015 cr */ 0, - /* 016 so */ 0, - /* 017 si */ 0, - /* 020 dle */ 0, - /* 021 dc1 */ 0, - /* 022 dc2 */ 0, - /* 023 dc3 */ 0, - /* 024 dc4 */ 0, - /* 025 nak */ 0, - /* 026 syn */ 0, - /* 027 etb */ 0, - /* 030 can */ 0, - /* 031 em */ 0, - /* 032 sub */ 0, - /* 033 esc */ 0, - /* 034 fs */ 0, - /* 035 gs */ 0, - /* 036 rs */ 0, - /* 037 us */ 0, - /* 040 sp */ BLANK, - /* 041 ! */ OTHER, - /* 042 " */ OTHER, - /* 043 # */ OTHER, - /* 044 $ */ 0, - /* 045 % */ OTHER, - /* 046 & */ OTHER, - /* 047 ' */ OTHER, - /* 050 ( */ OTHER, - /* 051 ) */ OTHER, - /* 052 * */ OTHER, - /* 053 + */ OTHER, - /* 054 , */ OTHER, - /* 055 - */ OTHER, - /* 056 . */ OTHER, - /* 057 / */ OTHER, - /* 060 0 */ DIGIT, - /* 061 1 */ DIGIT, - /* 062 2 */ DIGIT, - /* 063 3 */ DIGIT, - /* 064 4 */ DIGIT, - /* 065 5 */ DIGIT, - /* 066 6 */ DIGIT, - /* 067 7 */ DIGIT, - /* 070 8 */ DIGIT, - /* 071 9 */ DIGIT, - /* 072 : */ OTHER, - /* 073 ; */ OTHER, - /* 074 < */ OTHER, - /* 075 = */ OTHER, - /* 076 > */ OTHER, - /* 077 ? */ OTHER, - /* 100 @ */ 0, - /* 101 A */ LETTER|HEX, - /* 102 B */ LETTER|HEX, - /* 103 C */ LETTER|HEX, - /* 104 D */ LETTER|HEX, - /* 105 E */ LETTER|HEX, - /* 106 F */ LETTER|HEX, - /* 107 G */ LETTER, - /* 110 H */ LETTER, - /* 111 I */ LETTER, - /* 112 J */ LETTER, - /* 113 K */ LETTER, - /* 114 L */ LETTER, - /* 115 M */ LETTER, - /* 116 N */ LETTER, - /* 117 O */ LETTER, - /* 120 P */ LETTER, - /* 121 Q */ LETTER, - /* 122 R */ LETTER, - /* 123 S */ LETTER, - /* 124 T */ LETTER, - /* 125 U */ LETTER, - /* 126 V */ LETTER, - /* 127 W */ LETTER, - /* 130 X */ LETTER, - /* 131 Y */ LETTER, - /* 132 Z */ LETTER, - /* 133 [ */ OTHER, - /* 134 \ */ OTHER, - /* 135 ] */ OTHER, - /* 136 ^ */ OTHER, - /* 137 _ */ LETTER, - /* 140 ` */ 0, - /* 141 a */ LETTER|HEX, - /* 142 b */ LETTER|HEX, - /* 143 c */ LETTER|HEX, - /* 144 d */ LETTER|HEX, - /* 145 e */ LETTER|HEX, - /* 146 f */ LETTER|HEX, - /* 147 g */ LETTER, - /* 150 h */ LETTER, - /* 151 i */ LETTER, - /* 152 j */ LETTER, - /* 153 k */ LETTER, - /* 154 l */ LETTER, - /* 155 m */ LETTER, - /* 156 n */ LETTER, - /* 157 o */ LETTER, - /* 160 p */ LETTER, - /* 161 q */ LETTER, - /* 162 r */ LETTER, - /* 163 s */ LETTER, - /* 164 t */ LETTER, - /* 165 u */ LETTER, - /* 166 v */ LETTER, - /* 167 w */ LETTER, - /* 170 x */ LETTER, - /* 171 y */ LETTER, - /* 172 z */ LETTER, - /* 173 { */ OTHER, - /* 174 | */ OTHER, - /* 175 } */ OTHER, - /* 176 ~ */ OTHER, }; -static struct symbol tval; -static char cbuf[BUFSIZE+1]; -static unsigned int wcbuf[BUFSIZE+1]; - -Coordinate src; /* current source coordinate */ -int t; -char *token; /* current token */ -Symbol tsym; /* symbol table entry for current token */ - -static void *cput(int c, void *cl); -static void *wcput(int c, void *cl); -static void *scon(int q, void *put(int c, void *cl), void *cl); -static int backslash(int q); -static Symbol fcon(void); -static Symbol icon(unsigned long, int, int); -static void ppnumber(char *); - -int gettok(void) { - for (;;) { - register unsigned char *rcp = cp; - while (map[*rcp]&BLANK) - rcp++; - if (limit - rcp < MAXTOKEN) { - cp = rcp; - fillbuf(); - rcp = cp; - } - src.file = file; - src.x = (char *)rcp - line; - src.y = lineno; - cp = rcp + 1; - switch (*rcp++) { - case '/': if (*rcp == '*') { - int c = 0; - for (rcp++; *rcp != '/' || c != '*'; ) - if (map[*rcp]&NEWLINE) { - if (rcp < limit) - c = *rcp; - cp = rcp + 1; - nextline(); - rcp = cp; - if (rcp == limit) - break; - } else - c = *rcp++; - if (rcp < limit) - rcp++; - else - error("unclosed comment\n"); - cp = rcp; - continue; - } - return '/'; - case '<': - if (*rcp == '=') return cp++, LEQ; - if (*rcp == '<') return cp++, LSHIFT; - return '<'; - case '>': - if (*rcp == '=') return cp++, GEQ; - if (*rcp == '>') return cp++, RSHIFT; - return '>'; - case '-': - if (*rcp == '>') return cp++, DEREF; - if (*rcp == '-') return cp++, DECR; - return '-'; - case '=': return *rcp == '=' ? cp++, EQL : '='; - case '!': return *rcp == '=' ? cp++, NEQ : '!'; - case '|': return *rcp == '|' ? cp++, OROR : '|'; - case '&': return *rcp == '&' ? cp++, ANDAND : '&'; - case '+': return *rcp == '+' ? cp++, INCR : '+'; - case ';': case ',': case ':': - case '*': case '~': case '%': case '^': case '?': - case '[': case ']': case '{': case '}': case '(': case ')': - return rcp[-1]; - case '\n': case '\v': case '\r': case '\f': - nextline(); - if (cp == limit) { - tsym = NULL; - return EOI; - } - continue; - - case 'i': - if (rcp[0] == 'f' - && !(map[rcp[1]]&(DIGIT|LETTER))) { - cp = rcp + 1; - return IF; - } - if (rcp[0] == 'n' - && rcp[1] == 't' - && !(map[rcp[2]]&(DIGIT|LETTER))) { - cp = rcp + 2; - tsym = inttype->u.sym; - return INT; - } - goto id; - case 'h': case 'j': case 'k': case 'm': case 'n': case 'o': - case 'p': case 'q': case 'x': case 'y': case 'z': - case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': - case 'G': case 'H': case 'I': case 'J': case 'K': - case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': - case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': - case 'Y': case 'Z': - id: - if (limit - rcp < MAXLINE) { - cp = rcp - 1; - fillbuf(); - rcp = ++cp; - } - assert(cp == rcp); - token = (char *)rcp - 1; - while (map[*rcp]&(DIGIT|LETTER)) - rcp++; - token = stringn(token, (char *)rcp - token); - tsym = lookup(token, identifiers); - cp = rcp; - return ID; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - unsigned long n = 0; - if (limit - rcp < MAXLINE) { - cp = rcp - 1; - fillbuf(); - rcp = ++cp; - } - assert(cp == rcp); - token = (char *)rcp - 1; - if (*token == '0' && (*rcp == 'x' || *rcp == 'X')) { - int d, overflow = 0; - while (*++rcp) { - if (map[*rcp]&DIGIT) - d = *rcp - '0'; - else if (*rcp >= 'a' && *rcp <= 'f') - d = *rcp - 'a' + 10; - else if (*rcp >= 'A' && *rcp <= 'F') - d = *rcp - 'A' + 10; - else - break; - if (n&~(~0UL >> 4)) - overflow = 1; - else - n = (n<<4) + d; - } - if ((char *)rcp - token <= 2) - error("invalid hexadecimal constant `%S'\n", token, (char *)rcp-token); - cp = rcp; - tsym = icon(n, overflow, 16); - } else if (*token == '0') { - int err = 0, overflow = 0; - for ( ; map[*rcp]&DIGIT; rcp++) { - if (*rcp == '8' || *rcp == '9') - err = 1; - if (n&~(~0UL >> 3)) - overflow = 1; - else - n = (n<<3) + (*rcp - '0'); - } - if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') { - cp = rcp; - tsym = fcon(); - return FCON; - } - cp = rcp; - tsym = icon(n, overflow, 8); - if (err) - error("invalid octal constant `%S'\n", token, (char*)cp-token); - } else { - int overflow = 0; - for (n = *token - '0'; map[*rcp]&DIGIT; ) { - int d = *rcp++ - '0'; - if (n > (ULONG_MAX - d)/10) - overflow = 1; - else - n = 10*n + d; - } - if (*rcp == '.' || *rcp == 'e' || *rcp == 'E') { - cp = rcp; - tsym = fcon(); - return FCON; - } - cp = rcp; - tsym = icon(n, overflow, 10); - } - return ICON; - } - case '.': - if (rcp[0] == '.' && rcp[1] == '.') { - cp += 2; - return ELLIPSIS; - } - if ((map[*rcp]&DIGIT) == 0) - return '.'; - if (limit - rcp < MAXLINE) { - cp = rcp - 1; - fillbuf(); - rcp = ++cp; - } - assert(cp == rcp); - cp = rcp - 1; - token = (char *)cp; - tsym = fcon(); - return FCON; - case 'L': - if (*rcp == '\'') { - unsigned int *s = scon(*cp, wcput, wcbuf); - if (s - wcbuf > 2) - warning("excess characters in wide-character literal ignored\n"); - tval.type = widechar; - tval.u.c.v.u = wcbuf[0]; - tsym = &tval; - return ICON; - } else if (*rcp == '"') { - unsigned int *s = scon(*cp, wcput, wcbuf); - tval.type = array(widechar, s - wcbuf, 0); - tval.u.c.v.p = wcbuf; - tsym = &tval; - return SCON; - } else - goto id; - case '\'': { - char *s = scon(*--cp, cput, cbuf); - if (s - cbuf > 2) - warning("excess characters in multibyte character literal ignored\n"); - tval.type = inttype; - if (chartype->op == INT) - tval.u.c.v.i = extend(cbuf[0], chartype); - else - tval.u.c.v.i = cbuf[0]&0xFF; - tsym = &tval; - return ICON; - } - case '"': { - char *s = scon(*--cp, cput, cbuf); - tval.type = array(chartype, s - cbuf, 0); - tval.u.c.v.p = cbuf; - tsym = &tval; - return SCON; - } - case 'a': - if (rcp[0] == 'u' - && rcp[1] == 't' - && rcp[2] == 'o' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - return AUTO; - } - goto id; - case 'b': - if (rcp[0] == 'r' - && rcp[1] == 'e' - && rcp[2] == 'a' - && rcp[3] == 'k' - && !(map[rcp[4]]&(DIGIT|LETTER))) { - cp = rcp + 4; - return BREAK; - } - goto id; - case 'c': - if (rcp[0] == 'a' - && rcp[1] == 's' - && rcp[2] == 'e' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - return CASE; - } - if (rcp[0] == 'h' - && rcp[1] == 'a' - && rcp[2] == 'r' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - tsym = chartype->u.sym; - return CHAR; - } - if (rcp[0] == 'o' - && rcp[1] == 'n' - && rcp[2] == 's' - && rcp[3] == 't' - && !(map[rcp[4]]&(DIGIT|LETTER))) { - cp = rcp + 4; - return CONST; - } - if (rcp[0] == 'o' - && rcp[1] == 'n' - && rcp[2] == 't' - && rcp[3] == 'i' - && rcp[4] == 'n' - && rcp[5] == 'u' - && rcp[6] == 'e' - && !(map[rcp[7]]&(DIGIT|LETTER))) { - cp = rcp + 7; - return CONTINUE; - } - goto id; - case 'd': - if (rcp[0] == 'e' - && rcp[1] == 'f' - && rcp[2] == 'a' - && rcp[3] == 'u' - && rcp[4] == 'l' - && rcp[5] == 't' - && !(map[rcp[6]]&(DIGIT|LETTER))) { - cp = rcp + 6; - return DEFAULT; - } - if (rcp[0] == 'o' - && rcp[1] == 'u' - && rcp[2] == 'b' - && rcp[3] == 'l' - && rcp[4] == 'e' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - tsym = doubletype->u.sym; - return DOUBLE; - } - if (rcp[0] == 'o' - && !(map[rcp[1]]&(DIGIT|LETTER))) { - cp = rcp + 1; - return DO; - } - goto id; - case 'e': - if (rcp[0] == 'l' - && rcp[1] == 's' - && rcp[2] == 'e' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - return ELSE; - } - if (rcp[0] == 'n' - && rcp[1] == 'u' - && rcp[2] == 'm' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - return ENUM; - } - if (rcp[0] == 'x' - && rcp[1] == 't' - && rcp[2] == 'e' - && rcp[3] == 'r' - && rcp[4] == 'n' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return EXTERN; - } - goto id; - case 'f': - if (rcp[0] == 'l' - && rcp[1] == 'o' - && rcp[2] == 'a' - && rcp[3] == 't' - && !(map[rcp[4]]&(DIGIT|LETTER))) { - cp = rcp + 4; - tsym = floattype->u.sym; - return FLOAT; - } - if (rcp[0] == 'o' - && rcp[1] == 'r' - && !(map[rcp[2]]&(DIGIT|LETTER))) { - cp = rcp + 2; - return FOR; - } - goto id; - case 'g': - if (rcp[0] == 'o' - && rcp[1] == 't' - && rcp[2] == 'o' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - return GOTO; - } - goto id; - case 'l': - if (rcp[0] == 'o' - && rcp[1] == 'n' - && rcp[2] == 'g' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - return LONG; - } - goto id; - case 'r': - if (rcp[0] == 'e' - && rcp[1] == 'g' - && rcp[2] == 'i' - && rcp[3] == 's' - && rcp[4] == 't' - && rcp[5] == 'e' - && rcp[6] == 'r' - && !(map[rcp[7]]&(DIGIT|LETTER))) { - cp = rcp + 7; - return REGISTER; - } - if (rcp[0] == 'e' - && rcp[1] == 't' - && rcp[2] == 'u' - && rcp[3] == 'r' - && rcp[4] == 'n' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return RETURN; - } - goto id; - case 's': - if (rcp[0] == 'h' - && rcp[1] == 'o' - && rcp[2] == 'r' - && rcp[3] == 't' - && !(map[rcp[4]]&(DIGIT|LETTER))) { - cp = rcp + 4; - return SHORT; - } - if (rcp[0] == 'i' - && rcp[1] == 'g' - && rcp[2] == 'n' - && rcp[3] == 'e' - && rcp[4] == 'd' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return SIGNED; - } - if (rcp[0] == 'i' - && rcp[1] == 'z' - && rcp[2] == 'e' - && rcp[3] == 'o' - && rcp[4] == 'f' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return SIZEOF; - } - if (rcp[0] == 't' - && rcp[1] == 'a' - && rcp[2] == 't' - && rcp[3] == 'i' - && rcp[4] == 'c' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return STATIC; - } - if (rcp[0] == 't' - && rcp[1] == 'r' - && rcp[2] == 'u' - && rcp[3] == 'c' - && rcp[4] == 't' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return STRUCT; - } - if (rcp[0] == 'w' - && rcp[1] == 'i' - && rcp[2] == 't' - && rcp[3] == 'c' - && rcp[4] == 'h' - && !(map[rcp[5]]&(DIGIT|LETTER))) { - cp = rcp + 5; - return SWITCH; - } - goto id; - case 't': - if (rcp[0] == 'y' - && rcp[1] == 'p' - && rcp[2] == 'e' - && rcp[3] == 'd' - && rcp[4] == 'e' - && rcp[5] == 'f' - && !(map[rcp[6]]&(DIGIT|LETTER))) { - cp = rcp + 6; - return TYPEDEF; - } - goto id; - case 'u': - if (rcp[0] == 'n' - && rcp[1] == 'i' - && rcp[2] == 'o' - && rcp[3] == 'n' - && !(map[rcp[4]]&(DIGIT|LETTER))) { - cp = rcp + 4; - return UNION; - } - if (rcp[0] == 'n' - && rcp[1] == 's' - && rcp[2] == 'i' - && rcp[3] == 'g' - && rcp[4] == 'n' - && rcp[5] == 'e' - && rcp[6] == 'd' - && !(map[rcp[7]]&(DIGIT|LETTER))) { - cp = rcp + 7; - return UNSIGNED; - } - goto id; - case 'v': - if (rcp[0] == 'o' - && rcp[1] == 'i' - && rcp[2] == 'd' - && !(map[rcp[3]]&(DIGIT|LETTER))) { - cp = rcp + 3; - tsym = voidtype->u.sym; - return VOID; - } - if (rcp[0] == 'o' - && rcp[1] == 'l' - && rcp[2] == 'a' - && rcp[3] == 't' - && rcp[4] == 'i' - && rcp[5] == 'l' - && rcp[6] == 'e' - && !(map[rcp[7]]&(DIGIT|LETTER))) { - cp = rcp + 7; - return VOLATILE; - } - goto id; - case 'w': - if (rcp[0] == 'h' - && rcp[1] == 'i' - && rcp[2] == 'l' - && rcp[3] == 'e' - && !(map[rcp[4]]&(DIGIT|LETTER))) { - cp = rcp + 4; - return WHILE; - } - goto id; - case '_': - if (rcp[0] == '_' - && rcp[1] == 't' - && rcp[2] == 'y' - && rcp[3] == 'p' - && rcp[4] == 'e' - && rcp[5] == 'c' - && rcp[6] == 'o' - && rcp[7] == 'd' - && rcp[8] == 'e' - && !(map[rcp[9]]&(DIGIT|LETTER))) { - cp = rcp + 9; - return TYPECODE; - } - if (rcp[0] == '_' - && rcp[1] == 'f' - && rcp[2] == 'i' - && rcp[3] == 'r' - && rcp[4] == 's' - && rcp[5] == 't' - && rcp[6] == 'a' - && rcp[7] == 'r' - && rcp[8] == 'g' - && !(map[rcp[9]]&(DIGIT|LETTER))) { - cp = rcp + 9; - return FIRSTARG; - } - goto id; - default: - if ((map[cp[-1]]&BLANK) == 0) { - if (cp[-1] < ' ' || cp[-1] >= 0177) - error("illegal character `\\0%o'\n", cp[-1]); - else - error("illegal character `%c'\n", cp[-1]); - } - } - } -} -static Symbol icon(unsigned long n, int overflow, int base) { - if (((*cp=='u'||*cp=='U') && (cp[1]=='l'||cp[1]=='L')) - || ((*cp=='l'||*cp=='L') && (cp[1]=='u'||cp[1]=='U'))) { - tval.type = unsignedlong; - cp += 2; - } else if (*cp == 'u' || *cp == 'U') { - if (overflow || n > unsignedtype->u.sym->u.limits.max.i) - tval.type = unsignedlong; - else - tval.type = unsignedtype; - cp += 1; - } else if (*cp == 'l' || *cp == 'L') { - if (overflow || n > longtype->u.sym->u.limits.max.i) - tval.type = unsignedlong; - else - tval.type = longtype; - cp += 1; - } else if (overflow || n > longtype->u.sym->u.limits.max.i) - tval.type = unsignedlong; - else if (n > inttype->u.sym->u.limits.max.i) - tval.type = longtype; - else if (base != 10 && n > inttype->u.sym->u.limits.max.i) - tval.type = unsignedtype; - else - tval.type = inttype; - switch (tval.type->op) { - case INT: - if (overflow || n > tval.type->u.sym->u.limits.max.i) { - warning("overflow in constant `%S'\n", token, - (char*)cp - token); - tval.u.c.v.i = tval.type->u.sym->u.limits.max.i; - } else - tval.u.c.v.i = n; - break; - case UNSIGNED: - if (overflow || n > tval.type->u.sym->u.limits.max.u) { - warning("overflow in constant `%S'\n", token, - (char*)cp - token); - tval.u.c.v.u = tval.type->u.sym->u.limits.max.u; - } else - tval.u.c.v.u = n; - break; - default: assert(0); - } - ppnumber("integer"); - return &tval; -} -static void ppnumber(char *which) { - unsigned char *rcp = cp--; - - for ( ; (map[*cp]&(DIGIT|LETTER)) || *cp == '.'; cp++) - if ((cp[0] == 'E' || cp[0] == 'e') - && (cp[1] == '-' || cp[1] == '+')) - cp++; - if (cp > rcp) - error("`%S' is a preprocessing number but an invalid %s constant\n", token, - - (char*)cp-token, which); -} -static Symbol fcon(void) { - if (*cp == '.') - do - cp++; - while (map[*cp]&DIGIT); - if (*cp == 'e' || *cp == 'E') { - if (*++cp == '-' || *cp == '+') - cp++; - if (map[*cp]&DIGIT) - do - cp++; - while (map[*cp]&DIGIT); - else - error("invalid floating constant `%S'\n", token, - (char*)cp - token); - } - - errno = 0; - tval.u.c.v.d = strtod(token, NULL); - if (errno == ERANGE) - warning("overflow in floating constant `%S'\n", token, - (char*)cp - token); - if (*cp == 'f' || *cp == 'F') { - ++cp; - if (tval.u.c.v.d > floattype->u.sym->u.limits.max.d) - warning("overflow in floating constant `%S'\n", token, - (char*)cp - token); - tval.type = floattype; - } else if (*cp == 'l' || *cp == 'L') { - cp++; - tval.type = longdouble; - } else { - if (tval.u.c.v.d > doubletype->u.sym->u.limits.max.d) - warning("overflow in floating constant `%S'\n", token, - (char*)cp - token); - tval.type = doubletype; - } - ppnumber("floating"); - return &tval; -} - -static void *cput(int c, void *cl) { - char *s = cl; - - if (c < 0 || c > 255) - warning("overflow in escape sequence with resulting value `%d'\n", c); - *s++ = c; - return s; -} - -static void *wcput(int c, void *cl) { - unsigned int *s = cl; - - *s++ = c; - return s; -} - -static void *scon(int q, void *put(int c, void *cl), void *cl) { - int n = 0, nbad = 0; - - do { - cp++; - while (*cp != q) { - int c; - if (map[*cp]&NEWLINE) { - if (cp < limit) - break; - cp++; - nextline(); - if (cp == limit) - break; - continue; - } - c = *cp++; - if (c == '\\') { - if (map[*cp]&NEWLINE) { - if (cp < limit) - break; - cp++; - nextline(); - } - if (limit - cp < MAXTOKEN) - fillbuf(); - c = backslash(q); - } else if (c < 0 || c > 255 || map[c] == 0) - nbad++; - if (n++ < BUFSIZE) - cl = put(c, cl); - } - if (*cp == q) - cp++; - else - error("missing %c\n", q); - } while (q == '"' && getchr() == '"'); - cl = put(0, cl); - if (n >= BUFSIZE) - error("%s literal too long\n", q == '"' ? "string" : "character"); - if (Aflag >= 2 && q == '"' && n > 509) - warning("more than 509 characters in a string literal\n"); - if (Aflag >= 2 && nbad > 0) - warning("%s literal contains non-portable characters\n", - q == '"' ? "string" : "character"); - return cl; -} -int getchr(void) { - for (;;) { - while (map[*cp]&BLANK) - cp++; - if (!(map[*cp]&NEWLINE)) - return *cp; - cp++; - nextline(); - if (cp == limit) - return EOI; - } -} -static int backslash(int q) { - unsigned int c; - - switch (*cp++) { - case 'a': return 7; - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'v': return '\v'; - case '\'': case '"': case '\\': case '\?': break; - case 'x': { - int overflow = 0; - if ((map[*cp]&(DIGIT|HEX)) == 0) { - if (*cp < ' ' || *cp == 0177) - error("ill-formed hexadecimal escape sequence\n"); - else - error("ill-formed hexadecimal escape sequence `\\x%c'\n", *cp); - if (*cp != q) - cp++; - return 0; - } - for (c = 0; map[*cp]&(DIGIT|HEX); cp++) { - if (c >> (8*widechar->size - 4)) - overflow = 1; - if (map[*cp]&DIGIT) - c = (c<<4) + *cp - '0'; - else - c = (c<<4) + (*cp&~040) - 'A' + 10; - } - if (overflow) - warning("overflow in hexadecimal escape sequence\n"); - return c&ones(8*widechar->size); - } - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - c = *(cp-1) - '0'; - if (*cp >= '0' && *cp <= '7') { - c = (c<<3) + *cp++ - '0'; - if (*cp >= '0' && *cp <= '7') - c = (c<<3) + *cp++ - '0'; - } - return c; - default: - if (cp[-1] < ' ' || cp[-1] >= 0177) - warning("unrecognized character escape sequence\n"); - else - warning("unrecognized character escape sequence `\\%c'\n", cp[-1]); - } - return cp[-1]; -} diff --git a/lcc/src/list.c b/lcc/src/list.c deleted file mode 100644 index 29e660a..0000000 --- a/lcc/src/list.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "c.h" - - -static List freenodes; /* free list nodes */ - -/* append - append x to list, return new list */ -List append(void *x, List list) { - List new; - - if ((new = freenodes) != NULL) - freenodes = freenodes->link; - else - NEW(new, PERM); - if (list) { - new->link = list->link; - list->link = new; - } else - new->link = new; - new->x = x; - return new; -} - -/* length - # elements in list */ -int length(List list) { - int n = 0; - - if (list) { - List lp = list; - do - n++; - while ((lp = lp->link) != list); - } - return n; -} - -/* ltov - convert list to an NULL-terminated vector allocated in arena */ -void *ltov(List *list, unsigned arena) { - int i = 0; - void **array = newarray(length(*list) + 1, sizeof array[0], arena); - - if (*list) { - List lp = *list; - do { - lp = lp->link; - array[i++] = lp->x; - } while (lp != *list); -#ifndef PURIFY - lp = (*list)->link; - (*list)->link = freenodes; - freenodes = lp; -#endif - } - *list = NULL; - array[i] = NULL; - return array; -} diff --git a/lcc/src/main.c b/lcc/src/main.c deleted file mode 100644 index 63b85f2..0000000 --- a/lcc/src/main.c +++ /dev/null @@ -1,225 +0,0 @@ -#include "c.h" - -static char rcsid[] = "main.c - faked rcsid"; - -static void typestab(Symbol, void *); - -static void stabline(Coordinate *); -static void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -Interface *IR = NULL; - -int Aflag; /* >= 0 if -A specified */ -int Pflag; /* != 0 if -P specified */ -int glevel; /* == [0-9] if -g[0-9] specified */ -int xref; /* != 0 for cross-reference data */ -Symbol YYnull; /* _YYnull symbol if -n or -nvalidate specified */ -Symbol YYcheck; /* _YYcheck symbol if -nvalidate,check specified */ - -static char *comment; -static Interface stabIR; -static char *currentfile; /* current file name */ -static int currentline; /* current line number */ -static FILE *srcfp; /* stream for current file, if non-NULL */ -static int srcpos; /* position of srcfp, if srcfp is non-NULL */ -int main(int argc, char *argv[]) { - int i, j; - for (i = argc - 1; i > 0; i--) - if (strncmp(argv[i], "-target=", 8) == 0) - break; - if (i > 0) { - char *s = strchr(argv[i], '\\'); - if (s != NULL) - *s = '/'; - for (j = 0; bindings[j].name && bindings[j].ir; j++) - if (strcmp(&argv[i][8], bindings[j].name) == 0) { - IR = bindings[j].ir; - break; - } - if (s != NULL) - *s = '\\'; - } - if (!IR) { - fprint(stderr, "%s: unknown target", argv[0]); - if (i > 0) - fprint(stderr, " `%s'", &argv[i][8]); - fprint(stderr, "; must specify one of\n"); - for (i = 0; bindings[i].name; i++) - fprint(stderr, "\t-target=%s\n", bindings[i].name); - exit(EXIT_FAILURE); - } - init(argc, argv); - t = gettok(); - (*IR->progbeg)(argc, argv); - if (glevel && IR->stabinit) - (*IR->stabinit)(firstfile, argc, argv); - program(); - if (events.end) - apply(events.end, NULL, NULL); - memset(&events, 0, sizeof events); - if (glevel || xref) { - Symbol symroot = NULL; - Coordinate src; - foreach(types, GLOBAL, typestab, &symroot); - foreach(identifiers, GLOBAL, typestab, &symroot); - src.file = firstfile; - src.x = 0; - src.y = lineno; - if ((glevel > 2 || xref) && IR->stabend) - (*IR->stabend)(&src, symroot, - ltov(&loci, PERM), - ltov(&symbols, PERM), NULL); - else if (IR->stabend) - (*IR->stabend)(&src, NULL, NULL, NULL, NULL); - } - finalize(); - (*IR->progend)(); - deallocate(PERM); - return errcnt > 0; -} -/* main_init - process program arguments */ -void main_init(int argc, char *argv[]) { - char *infile = NULL, *outfile = NULL; - int i; - static int inited; - - if (inited) - return; - inited = 1; - type_init(argc, argv); - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0) - glevel = 2; - else if (strncmp(argv[i], "-g", 2) == 0) { /* -gn[,x] */ - char *p = strchr(argv[i], ','); - glevel = atoi(argv[i]+2); - if (p) { - comment = p + 1; - if (glevel == 0) - glevel = 1; - if (stabIR.stabline == NULL) { - stabIR.stabline = IR->stabline; - stabIR.stabend = IR->stabend; - IR->stabline = stabline; - IR->stabend = stabend; - } - } - } else if (strcmp(argv[i], "-x") == 0) - xref++; - else if (strcmp(argv[i], "-A") == 0) { - ++Aflag; - } else if (strcmp(argv[i], "-P") == 0) - Pflag++; - else if (strcmp(argv[i], "-w") == 0) - wflag++; - else if (strcmp(argv[i], "-n") == 0) { - if (!YYnull) { - YYnull = install(string("_YYnull"), &globals, GLOBAL, PERM); - YYnull->type = func(voidptype, NULL, 1); - YYnull->sclass = EXTERN; - (*IR->defsymbol)(YYnull); - } - } else if (strncmp(argv[i], "-n", 2) == 0) { /* -nvalid[,check] */ - char *p = strchr(argv[i], ','); - if (p) { - YYcheck = install(string(p+1), &globals, GLOBAL, PERM); - YYcheck->type = func(voidptype, NULL, 1); - YYcheck->sclass = EXTERN; - (*IR->defsymbol)(YYcheck); - p = stringn(argv[i]+2, p - (argv[i]+2)); - } else - p = string(argv[i]+2); - YYnull = install(p, &globals, GLOBAL, PERM); - YYnull->type = func(voidptype, NULL, 1); - YYnull->sclass = EXTERN; - (*IR->defsymbol)(YYnull); - } else if (strcmp(argv[i], "-v") == 0) - fprint(stderr, "%s %s\n", argv[0], rcsid); - else if (strncmp(argv[i], "-s", 2) == 0) - density = strtod(&argv[i][2], NULL); - else if (strncmp(argv[i], "-errout=", 8) == 0) { - FILE *f = fopen(argv[i]+8, "w"); - if (f == NULL) { - fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8); - exit(EXIT_FAILURE); - } - fclose(f); - f = freopen(argv[i]+8, "w", stderr); - assert(f); - } else if (strncmp(argv[i], "-e", 2) == 0) { - int x; - if ((x = strtol(&argv[i][2], NULL, 0)) > 0) - errlimit = x; - } else if (strncmp(argv[i], "-little_endian=", 15) == 0) - IR->little_endian = argv[i][15] - '0'; - else if (strncmp(argv[i], "-mulops_calls=", 18) == 0) - IR->mulops_calls = argv[i][18] - '0'; - else if (strncmp(argv[i], "-wants_callb=", 13) == 0) - IR->wants_callb = argv[i][13] - '0'; - else if (strncmp(argv[i], "-wants_argb=", 12) == 0) - IR->wants_argb = argv[i][12] - '0'; - else if (strncmp(argv[i], "-left_to_right=", 15) == 0) - IR->left_to_right = argv[i][15] - '0'; - else if (strncmp(argv[i], "-wants_dag=", 11) == 0) - IR->wants_dag = argv[i][11] - '0'; - else if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) { - if (infile == NULL) - infile = argv[i]; - else if (outfile == NULL) - outfile = argv[i]; - } - - if (infile != NULL && strcmp(infile, "-") != 0 - && freopen(infile, "r", stdin) == NULL) { - fprint(stderr, "%s: can't read `%s'\n", argv[0], infile); - exit(EXIT_FAILURE); - } - if (outfile != NULL && strcmp(outfile, "-") != 0 - && freopen(outfile, "w", stdout) == NULL) { - fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile); - exit(EXIT_FAILURE); - } -} -/* typestab - emit stab entries for p */ -static void typestab(Symbol p, void *cl) { - if (*(Symbol *)cl == 0 && p->sclass && p->sclass != TYPEDEF) - *(Symbol *)cl = p; - if ((p->sclass == TYPEDEF || p->sclass == 0) && IR->stabtype) - (*IR->stabtype)(p); -} - -/* stabline - emit source code for source coordinate *cp */ -static void stabline(Coordinate *cp) { - if (cp->file && cp->file != currentfile) { - if (srcfp) - fclose(srcfp); - currentfile = cp->file; - srcfp = fopen(currentfile, "r"); - srcpos = 0; - currentline = 0; - } - if (currentline != cp->y && srcfp) { - char buf[512]; - if (srcpos > cp->y) { - rewind(srcfp); - srcpos = 0; - } - for ( ; srcpos < cp->y; srcpos++) - if (fgets(buf, sizeof buf, srcfp) == NULL) { - fclose(srcfp); - srcfp = NULL; - break; - } - if (srcfp && srcpos == cp->y) - print("%s%s", comment, buf); - } - currentline = cp->y; - if (stabIR.stabline) - (*stabIR.stabline)(cp); -} - -static void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) { - if (stabIR.stabend) - (*stabIR.stabend)(cp, p, cpp, sp, stab); - if (srcfp) - fclose(srcfp); -} diff --git a/lcc/src/mips.md b/lcc/src/mips.md deleted file mode 100644 index 41f6d8c..0000000 --- a/lcc/src/mips.md +++ /dev/null @@ -1,1120 +0,0 @@ -%{ -#define INTTMP 0x0100ff00 -#define INTVAR 0x40ff0000 -#define FLTTMP 0x000f0ff0 -#define FLTVAR 0xfff00000 - -#define INTRET 0x00000004 -#define FLTRET 0x00000003 - -#define readsreg(p) \ - (generic((p)->op)==INDIR && (p)->kids[0]->op==VREG+P) -#define setsrc(d) ((d) && (d)->x.regnode && \ - (d)->x.regnode->set == src->x.regnode->set && \ - (d)->x.regnode->mask&src->x.regnode->mask) - -#define relink(a, b) ((b)->x.prev = (a), (a)->x.next = (b)) - -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -static int bitcount (unsigned); -static Symbol argreg (int, int, int, int, int); - -static Symbol ireg[32], freg2[32], d6; -static Symbol iregw, freg2w; -static int tmpregs[] = {3, 9, 10}; -static Symbol blkreg; - -static int gnum = 8; -static int pic; - -static int cseg; -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -acon: con "%0" -acon: ADDRGP4 "%a" -addr: ADDI4(reg,acon) "%1($%0)" -addr: ADDU4(reg,acon) "%1($%0)" -addr: ADDP4(reg,acon) "%1($%0)" -addr: acon "%0" -addr: reg "($%0)" -addr: ADDRFP4 "%a+%F($sp)" -addr: ADDRLP4 "%a+%F($sp)" -reg: addr "la $%c,%0\n" 1 -reg: CNSTI1 "# reg\n" range(a, 0, 0) -reg: CNSTI2 "# reg\n" range(a, 0, 0) -reg: CNSTI4 "# reg\n" range(a, 0, 0) -reg: CNSTU1 "# reg\n" range(a, 0, 0) -reg: CNSTU2 "# reg\n" range(a, 0, 0) -reg: CNSTU4 "# reg\n" range(a, 0, 0) -reg: CNSTP4 "# reg\n" range(a, 0, 0) -stmt: ASGNI1(addr,reg) "sb $%1,%0\n" 1 -stmt: ASGNU1(addr,reg) "sb $%1,%0\n" 1 -stmt: ASGNI2(addr,reg) "sh $%1,%0\n" 1 -stmt: ASGNU2(addr,reg) "sh $%1,%0\n" 1 -stmt: ASGNI4(addr,reg) "sw $%1,%0\n" 1 -stmt: ASGNU4(addr,reg) "sw $%1,%0\n" 1 -stmt: ASGNP4(addr,reg) "sw $%1,%0\n" 1 -reg: INDIRI1(addr) "lb $%c,%0\n" 1 -reg: INDIRU1(addr) "lbu $%c,%0\n" 1 -reg: INDIRI2(addr) "lh $%c,%0\n" 1 -reg: INDIRU2(addr) "lhu $%c,%0\n" 1 -reg: INDIRI4(addr) "lw $%c,%0\n" 1 -reg: INDIRU4(addr) "lw $%c,%0\n" 1 -reg: INDIRP4(addr) "lw $%c,%0\n" 1 - -reg: CVII4(INDIRI1(addr)) "lb $%c,%0\n" 1 -reg: CVII4(INDIRI2(addr)) "lh $%c,%0\n" 1 -reg: CVUU4(INDIRU1(addr)) "lbu $%c,%0\n" 1 -reg: CVUU4(INDIRU2(addr)) "lhu $%c,%0\n" 1 -reg: CVUI4(INDIRU1(addr)) "lbu $%c,%0\n" 1 -reg: CVUI4(INDIRU2(addr)) "lhu $%c,%0\n" 1 -reg: INDIRF4(addr) "l.s $f%c,%0\n" 1 -reg: INDIRF8(addr) "l.d $f%c,%0\n" 1 -stmt: ASGNF4(addr,reg) "s.s $f%1,%0\n" 1 -stmt: ASGNF8(addr,reg) "s.d $f%1,%0\n" 1 -reg: DIVI4(reg,reg) "div $%c,$%0,$%1\n" 1 -reg: DIVU4(reg,reg) "divu $%c,$%0,$%1\n" 1 -reg: MODI4(reg,reg) "rem $%c,$%0,$%1\n" 1 -reg: MODU4(reg,reg) "remu $%c,$%0,$%1\n" 1 -reg: MULI4(reg,reg) "mul $%c,$%0,$%1\n" 1 -reg: MULU4(reg,reg) "mul $%c,$%0,$%1\n" 1 -rc: con "%0" -rc: reg "$%0" - -reg: ADDI4(reg,rc) "addu $%c,$%0,%1\n" 1 -reg: ADDP4(reg,rc) "addu $%c,$%0,%1\n" 1 -reg: ADDU4(reg,rc) "addu $%c,$%0,%1\n" 1 -reg: BANDI4(reg,rc) "and $%c,$%0,%1\n" 1 -reg: BORI4(reg,rc) "or $%c,$%0,%1\n" 1 -reg: BXORI4(reg,rc) "xor $%c,$%0,%1\n" 1 -reg: BANDU4(reg,rc) "and $%c,$%0,%1\n" 1 -reg: BORU4(reg,rc) "or $%c,$%0,%1\n" 1 -reg: BXORU4(reg,rc) "xor $%c,$%0,%1\n" 1 -reg: SUBI4(reg,rc) "subu $%c,$%0,%1\n" 1 -reg: SUBP4(reg,rc) "subu $%c,$%0,%1\n" 1 -reg: SUBU4(reg,rc) "subu $%c,$%0,%1\n" 1 -rc5: CNSTI4 "%a" range(a,0,31) -rc5: reg "$%0" - -reg: LSHI4(reg,rc5) "sll $%c,$%0,%1\n" 1 -reg: LSHU4(reg,rc5) "sll $%c,$%0,%1\n" 1 -reg: RSHI4(reg,rc5) "sra $%c,$%0,%1\n" 1 -reg: RSHU4(reg,rc5) "srl $%c,$%0,%1\n" 1 -reg: BCOMI4(reg) "not $%c,$%0\n" 1 -reg: BCOMU4(reg) "not $%c,$%0\n" 1 -reg: NEGI4(reg) "negu $%c,$%0\n" 1 -reg: LOADI1(reg) "move $%c,$%0\n" move(a) -reg: LOADU1(reg) "move $%c,$%0\n" move(a) -reg: LOADI2(reg) "move $%c,$%0\n" move(a) -reg: LOADU2(reg) "move $%c,$%0\n" move(a) -reg: LOADI4(reg) "move $%c,$%0\n" move(a) -reg: LOADP4(reg) "move $%c,$%0\n" move(a) -reg: LOADU4(reg) "move $%c,$%0\n" move(a) -reg: ADDF4(reg,reg) "add.s $f%c,$f%0,$f%1\n" 1 -reg: ADDF8(reg,reg) "add.d $f%c,$f%0,$f%1\n" 1 -reg: DIVF4(reg,reg) "div.s $f%c,$f%0,$f%1\n" 1 -reg: DIVF8(reg,reg) "div.d $f%c,$f%0,$f%1\n" 1 -reg: MULF4(reg,reg) "mul.s $f%c,$f%0,$f%1\n" 1 -reg: MULF8(reg,reg) "mul.d $f%c,$f%0,$f%1\n" 1 -reg: SUBF4(reg,reg) "sub.s $f%c,$f%0,$f%1\n" 1 -reg: SUBF8(reg,reg) "sub.d $f%c,$f%0,$f%1\n" 1 -reg: LOADF4(reg) "mov.s $f%c,$f%0\n" move(a) -reg: LOADF8(reg) "mov.d $f%c,$f%0\n" move(a) -reg: NEGF4(reg) "neg.s $f%c,$f%0\n" 1 -reg: NEGF8(reg) "neg.d $f%c,$f%0\n" 1 -reg: CVII4(reg) "sll $%c,$%0,8*(4-%a); sra $%c,$%c,8*(4-%a)\n" 2 -reg: CVUI4(reg) "and $%c,$%0,(1<<(8*%a))-1\n" 1 -reg: CVUU4(reg) "and $%c,$%0,(1<<(8*%a))-1\n" 1 -reg: CVFF4(reg) "cvt.s.d $f%c,$f%0\n" 1 -reg: CVFF8(reg) "cvt.d.s $f%c,$f%0\n" 1 -reg: CVIF4(reg) "mtc1 $%0,$f%c; cvt.s.w $f%c,$f%c\n" 2 -reg: CVIF8(reg) "mtc1 $%0,$f%c; cvt.d.w $f%c,$f%c\n" 2 -reg: CVFI4(reg) "trunc.w.s $f2,$f%0,$%c; mfc1 $%c,$f2\n" (a->syms[0]->u.c.v.i==4?2:LBURG_MAX) -reg: CVFI4(reg) "trunc.w.d $f2,$f%0,$%c; mfc1 $%c,$f2\n" (a->syms[0]->u.c.v.i==8?2:LBURG_MAX) -stmt: LABELV "%a:\n" -stmt: JUMPV(acon) "b %0\n" 1 -stmt: JUMPV(reg) ".cpadd $%0\nj $%0\n" !pic -stmt: JUMPV(reg) "j $%0\n" pic -stmt: EQI4(reg,reg) "beq $%0,$%1,%a\n" 1 -stmt: EQU4(reg,reg) "beq $%0,$%1,%a\n" 1 -stmt: GEI4(reg,reg) "bge $%0,$%1,%a\n" 1 -stmt: GEU4(reg,reg) "bgeu $%0,$%1,%a\n" 1 -stmt: GTI4(reg,reg) "bgt $%0,$%1,%a\n" 1 -stmt: GTU4(reg,reg) "bgtu $%0,$%1,%a\n" 1 -stmt: LEI4(reg,reg) "ble $%0,$%1,%a\n" 1 -stmt: LEU4(reg,reg) "bleu $%0,$%1,%a\n" 1 -stmt: LTI4(reg,reg) "blt $%0,$%1,%a\n" 1 -stmt: LTU4(reg,reg) "bltu $%0,$%1,%a\n" 1 -stmt: NEI4(reg,reg) "bne $%0,$%1,%a\n" 1 -stmt: NEU4(reg,reg) "bne $%0,$%1,%a\n" 1 -stmt: EQF4(reg,reg) "c.eq.s $f%0,$f%1; bc1t %a\n" 2 -stmt: EQF8(reg,reg) "c.eq.d $f%0,$f%1; bc1t %a\n" 2 -stmt: LEF4(reg,reg) "c.le.s $f%0,$f%1; bc1t %a\n" 2 -stmt: LEF8(reg,reg) "c.le.d $f%0,$f%1; bc1t %a\n" 2 -stmt: LTF4(reg,reg) "c.lt.s $f%0,$f%1; bc1t %a\n" 2 -stmt: LTF8(reg,reg) "c.lt.d $f%0,$f%1; bc1t %a\n" 2 -stmt: GEF4(reg,reg) "c.lt.s $f%0,$f%1; bc1f %a\n" 2 -stmt: GEF8(reg,reg) "c.lt.d $f%0,$f%1; bc1f %a\n" 2 -stmt: GTF4(reg,reg) "c.le.s $f%0,$f%1; bc1f %a\n" 2 -stmt: GTF8(reg,reg) "c.le.d $f%0,$f%1; bc1f %a\n" 2 -stmt: NEF4(reg,reg) "c.eq.s $f%0,$f%1; bc1f %a\n" 2 -stmt: NEF8(reg,reg) "c.eq.d $f%0,$f%1; bc1f %a\n" 2 -ar: ADDRGP4 "%a" - -reg: CALLF4(ar) "jal %0\n" 1 -reg: CALLF8(ar) "jal %0\n" 1 -reg: CALLI4(ar) "jal %0\n" 1 -reg: CALLP4(ar) "jal %0\n" 1 -reg: CALLU4(ar) "jal %0\n" 1 -stmt: CALLV(ar) "jal %0\n" 1 -ar: reg "$%0" -ar: CNSTP4 "%a" range(a, 0, 0x0fffffff) -stmt: RETF4(reg) "# ret\n" 1 -stmt: RETF8(reg) "# ret\n" 1 -stmt: RETI4(reg) "# ret\n" 1 -stmt: RETU4(reg) "# ret\n" 1 -stmt: RETP4(reg) "# ret\n" 1 -stmt: RETV(reg) "# ret\n" 1 -stmt: ARGF4(reg) "# arg\n" 1 -stmt: ARGF8(reg) "# arg\n" 1 -stmt: ARGI4(reg) "# arg\n" 1 -stmt: ARGP4(reg) "# arg\n" 1 -stmt: ARGU4(reg) "# arg\n" 1 - -stmt: ARGB(INDIRB(reg)) "# argb %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "# asgnb %0 %1\n" 1 -%% -static void progend(void){} -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - print(".set reorder\n"); - pic = !IR->little_endian; - parseflags(argc, argv); - for (i = 0; i < argc; i++) - if (strncmp(argv[i], "-G", 2) == 0) - gnum = atoi(argv[i] + 2); - else if (strcmp(argv[i], "-pic=1") == 0 - || strcmp(argv[i], "-pic=0") == 0) - pic = argv[i][5]-'0'; - for (i = 0; i < 31; i += 2) - freg2[i] = mkreg("%d", i, 3, FREG); - for (i = 0; i < 32; i++) - ireg[i] = mkreg("%d", i, 1, IREG); - ireg[29]->x.name = "sp"; - d6 = mkreg("6", 6, 3, IREG); - freg2w = mkwildcard(freg2); - iregw = mkwildcard(ireg); - tmask[IREG] = INTTMP; tmask[FREG] = FLTTMP; - vmask[IREG] = INTVAR; vmask[FREG] = FLTVAR; - blkreg = mkreg("8", 8, 7, IREG); -} -static Symbol rmap(int opk) { - switch (optype(opk)) { - case I: case U: case P: case B: - return iregw; - case F: - return freg2w; - default: - return 0; - } -} -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case CNST+I: case CNST+U: case CNST+P: - if (range(p, 0, 0) == 0) { - setreg(p, ireg[0]); - p->x.registered = 1; - } - break; - case CALL+V: - rtarget(p, 0, ireg[25]); - break; - case CALL+F: - rtarget(p, 0, ireg[25]); - setreg(p, freg2[0]); - break; - case CALL+I: case CALL+P: case CALL+U: - rtarget(p, 0, ireg[25]); - setreg(p, ireg[2]); - break; - case RET+F: - rtarget(p, 0, freg2[0]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, ireg[2]); - break; - case ARG+F: case ARG+I: case ARG+P: case ARG+U: { - static int ty0; - int ty = optype(p->op); - Symbol q; - - q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, opsize(p->op), ty0); - if (p->x.argno == 0) - ty0 = ty; - if (q && - !(ty == F && q->x.regnode->set == IREG)) - rtarget(p, 0, q); - break; - } - case ASGN+B: rtarget(p->kids[1], 0, blkreg); break; - case ARG+B: rtarget(p->kids[0], 0, blkreg); break; - } -} -static void clobber(Node p) { - assert(p); - switch (specific(p->op)) { - case CALL+F: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP, FREG, p); - break; - case CALL+I: case CALL+P: case CALL+U: - spill(INTTMP, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - case CALL+V: - spill(INTTMP | INTRET, IREG, p); - spill(FLTTMP | FLTRET, FREG, p); - break; - } -} -static void emit2(Node p) { - int dst, n, src, sz, ty; - static int ty0; - Symbol q; - - switch (specific(p->op)) { - case ARG+F: case ARG+I: case ARG+P: case ARG+U: - ty = optype(p->op); - sz = opsize(p->op); - if (p->x.argno == 0) - ty0 = ty; - q = argreg(p->x.argno, p->syms[2]->u.c.v.i, ty, sz, ty0); - src = getregnum(p->x.kids[0]); - if (q == NULL && ty == F && sz == 4) - print("s.s $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i); - else if (q == NULL && ty == F) - print("s.d $f%d,%d($sp)\n", src, p->syms[2]->u.c.v.i); - else if (q == NULL) - print("sw $%d,%d($sp)\n", src, p->syms[2]->u.c.v.i); - else if (ty == F && sz == 4 && q->x.regnode->set == IREG) - print("mfc1 $%d,$f%d\n", q->x.regnode->number, src); - else if (ty == F && q->x.regnode->set == IREG) - print("mfc1.d $%d,$f%d\n", q->x.regnode->number, src); - break; - case ASGN+B: - dalign = salign = p->syms[1]->u.c.v.i; - blkcopy(getregnum(p->x.kids[0]), 0, - getregnum(p->x.kids[1]), 0, - p->syms[0]->u.c.v.i, tmpregs); - break; - case ARG+B: - dalign = 4; - salign = p->syms[1]->u.c.v.i; - blkcopy(29, p->syms[2]->u.c.v.i, - getregnum(p->x.kids[0]), 0, - p->syms[0]->u.c.v.i, tmpregs); - n = p->syms[2]->u.c.v.i + p->syms[0]->u.c.v.i; - dst = p->syms[2]->u.c.v.i; - for ( ; dst <= 12 && dst < n; dst += 4) - print("lw $%d,%d($sp)\n", (dst/4)+4, dst); - break; - } -} -static Symbol argreg(int argno, int offset, int ty, int sz, int ty0) { - assert((offset&3) == 0); - if (offset > 12) - return NULL; - else if (argno == 0 && ty == F) - return freg2[12]; - else if (argno == 1 && ty == F && ty0 == F) - return freg2[14]; - else if (argno == 1 && ty == F && sz == 8) - return d6; /* Pair! */ - else - return ireg[(offset/4) + 4]; -} -static void doarg(Node p) { - static int argno; - int align; - - if (argoffset == 0) - argno = 0; - p->x.argno = argno++; - align = p->syms[1]->u.c.v.i < 4 ? 4 : p->syms[1]->u.c.v.i; - p->syms[2] = intconst(mkactual(align, - p->syms[0]->u.c.v.i)); -} -static void local(Symbol p) { - if (askregvar(p, rmap(ttob(p->type))) == 0) - mkauto(p); -} -static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int i, saved, sizefsave, sizeisave, varargs; - Symbol r, argregs[4]; - - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - offset = maxoffset = maxargoffset = 0; - for (i = 0; callee[i]; i++) - ; - varargs = variadic(f->type) - || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - offset = roundup(offset, q->type->align); - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringd(offset); - r = argreg(i, offset, optype(ttob(q->type)), q->type->size, optype(ttob(caller[0]->type))); - if (i < 4) - argregs[i] = r; - offset = roundup(offset + q->type->size, 4); - if (varargs) - p->sclass = AUTO; - else if (r && ncalls == 0 && - !isstruct(q->type) && !p->addressed && - !(isfloat(q->type) && r->x.regnode->set == IREG) -) { - p->sclass = q->sclass = REGISTER; - askregvar(p, r); - assert(p->x.regnode && p->x.regnode->vbl == p); - q->x = p->x; - q->type = p->type; - } - else if (askregvar(p, rmap(ttob(p->type))) - && r != NULL - && (isint(p->type) || p->type == q->type)) { - assert(q->sclass != REGISTER); - p->sclass = q->sclass = REGISTER; - q->type = p->type; - } - } - assert(!caller[i]); - offset = 0; - gencode(caller, callee); - if (ncalls) - usedmask[IREG] |= ((unsigned)1)<<31; - usedmask[IREG] &= 0xc0ff0000; - usedmask[FREG] &= 0xfff00000; - if (pic && ncalls) - usedmask[IREG] |= 1<<25; - maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 4); - if (ncalls && maxargoffset < 16) - maxargoffset = 16; - sizefsave = 4*bitcount(usedmask[FREG]); - sizeisave = 4*bitcount(usedmask[IREG]); - framesize = roundup(maxargoffset + sizefsave - + sizeisave + maxoffset, 8); - segment(CODE); - print(".align 2\n"); - print(".ent %s\n", f->x.name); - print("%s:\n", f->x.name); - i = maxargoffset + sizefsave - framesize; - print(".frame $sp,%d,$31\n", framesize); - if (pic) - print(".set noreorder\n.cpload $25\n.set reorder\n"); - if (framesize > 0) - print("addu $sp,$sp,%d\n", -framesize); - if (usedmask[FREG]) - print(".fmask 0x%x,%d\n", usedmask[FREG], i - 8); - if (usedmask[IREG]) - print(".mask 0x%x,%d\n", usedmask[IREG], - i + sizeisave - 4); - saved = maxargoffset; - for (i = 20; i <= 30; i += 2) - if (usedmask[FREG]&(3<<i)) { - print("s.d $f%d,%d($sp)\n", i, saved); - saved += 8; - } - - for (i = 16; i <= 31; i++) - if (usedmask[IREG]&(1<<i)) { - if (i == 25) - print(".cprestore %d\n", saved); - else - print("sw $%d,%d($sp)\n", i, saved); - saved += 4; - } - for (i = 0; i < 4 && callee[i]; i++) { - r = argregs[i]; - if (r && r->x.regnode != callee[i]->x.regnode) { - Symbol out = callee[i]; - Symbol in = caller[i]; - int rn = r->x.regnode->number; - int rs = r->x.regnode->set; - int tyin = ttob(in->type); - - assert(out && in && r && r->x.regnode); - assert(out->sclass != REGISTER || out->x.regnode); - if (out->sclass == REGISTER - && (isint(out->type) || out->type == in->type)) { - int outn = out->x.regnode->number; - if (rs == FREG && tyin == F+sizeop(8)) - print("mov.d $f%d,$f%d\n", outn, rn); - else if (rs == FREG && tyin == F+sizeop(4)) - print("mov.s $f%d,$f%d\n", outn, rn); - else if (rs == IREG && tyin == F+sizeop(8)) - print("mtc1.d $%d,$f%d\n", rn, outn); - else if (rs == IREG && tyin == F+sizeop(4)) - print("mtc1 $%d,$f%d\n", rn, outn); - else - print("move $%d,$%d\n", outn, rn); - } else { - int off = in->x.offset + framesize; - if (rs == FREG && tyin == F+sizeop(8)) - print("s.d $f%d,%d($sp)\n", rn, off); - else if (rs == FREG && tyin == F+sizeop(4)) - print("s.s $f%d,%d($sp)\n", rn, off); - else { - int i, n = (in->type->size + 3)/4; - for (i = rn; i < rn+n && i <= 7; i++) - print("sw $%d,%d($sp)\n", i, off + (i-rn)*4); - } - } - } - } - if (varargs && callee[i-1]) { - i = callee[i-1]->x.offset + callee[i-1]->type->size; - for (i = roundup(i, 4)/4; i <= 3; i++) - print("sw $%d,%d($sp)\n", i + 4, framesize + 4*i); - } - emitcode(); - saved = maxargoffset; - for (i = 20; i <= 30; i += 2) - if (usedmask[FREG]&(3<<i)) { - print("l.d $f%d,%d($sp)\n", i, saved); - saved += 8; - } - for (i = 16; i <= 31; i++) - if (usedmask[IREG]&(1<<i)) { - print("lw $%d,%d($sp)\n", i, saved); - saved += 4; - } - if (framesize > 0) - print("addu $sp,$sp,%d\n", framesize); - print("j $31\n"); - print(".end %s\n", f->x.name); -} -static void defconst(int suffix, int size, Value v) { - if (suffix == F && size == 4) { - float f = v.d; - print(".word 0x%x\n", *(unsigned *)&f); - } - else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]); - } - else if (suffix == P) - print(".word 0x%x\n", v.p); - else if (size == 1) - print(".byte 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 2) - print(".half 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 4) - print(".word 0x%x\n", suffix == I ? v.i : v.u); -} -static void defaddress(Symbol p) { - if (pic && p->scope == LABELS) - print(".gpword %s\n", p->x.name); - else - print(".word %s\n", p->x.name); -} -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} -static void export(Symbol p) { - print(".globl %s\n", p->x.name); -} -static void import(Symbol p) { - if (!isfunc(p->type)) - print(".extern %s %d\n", p->name, p->type->size); -} -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("L.%d", genlabel(1)); - else if (p->generated) - p->x.name = stringf("L.%s", p->name); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; -} -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", p->x.name, - n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} -static void global(Symbol p) { - if (p->u.seg == BSS) { - if (p->sclass == STATIC || Aflag >= 2) - print(".lcomm %s,%d\n", p->x.name, p->type->size); - else - print( ".comm %s,%d\n", p->x.name, p->type->size); - } else { - if (p->u.seg == DATA - && (p->type->size == 0 || p->type->size > gnum)) - print(".data\n"); - else if (p->u.seg == DATA) - print(".sdata\n"); - print(".align %c\n", ".01.2...3"[p->type->align]); - print("%s:\n", p->x.name); - } -} -static void segment(int n) { - cseg = n; - switch (n) { - case CODE: print(".text\n"); break; - case LIT: print(".rdata\n"); break; - } -} -static void space(int n) { - if (cseg != BSS) - print(".space %d\n", n); -} -static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { - int lab = genlabel(1); - - print("addu $%d,$%d,%d\n", sreg, sreg, size&~7); - print("addu $%d,$%d,%d\n", tmps[2], dreg, size&~7); - blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); - print("L.%d:\n", lab); - print("addu $%d,$%d,%d\n", sreg, sreg, -8); - print("addu $%d,$%d,%d\n", tmps[2], tmps[2], -8); - blkcopy(tmps[2], doff, sreg, soff, 8, tmps); - print("bltu $%d,$%d,L.%d\n", dreg, tmps[2], lab); -} -static void blkfetch(int size, int off, int reg, int tmp) { - assert(size == 1 || size == 2 || size == 4); - if (size == 1) - print("lbu $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size && size == 2) - print("lhu $%d,%d($%d)\n", tmp, off, reg); - else if (salign >= size) - print("lw $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("ulhu $%d,%d($%d)\n", tmp, off, reg); - else - print("ulw $%d,%d($%d)\n", tmp, off, reg); -} -static void blkstore(int size, int off, int reg, int tmp) { - if (size == 1) - print("sb $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size && size == 2) - print("sh $%d,%d($%d)\n", tmp, off, reg); - else if (dalign >= size) - print("sw $%d,%d($%d)\n", tmp, off, reg); - else if (size == 2) - print("ush $%d,%d($%d)\n", tmp, off, reg); - else - print("usw $%d,%d($%d)\n", tmp, off, reg); -} -static void stabinit(char *, int, char *[]); -static void stabline(Coordinate *); -static void stabsym(Symbol); - -static char *currentfile; - -static int bitcount(unsigned mask) { - unsigned i, n = 0; - - for (i = 1; i; i <<= 1) - if (mask&i) - n++; - return n; -} - -/* stabinit - initialize stab output */ -static void stabinit(char *file, int argc, char *argv[]) { - if (file) { - print(".file 2,\"%s\"\n", file); - currentfile = file; - } -} - -/* stabline - emit stab entry for source coordinate *cp */ -static void stabline(Coordinate *cp) { - if (cp->file && cp->file != currentfile) { - print(".file 2,\"%s\"\n", cp->file); - currentfile = cp->file; - } - print(".loc 2,%d\n", cp->y); -} - -/* stabsym - output a stab entry for symbol p */ -static void stabsym(Symbol p) { - if (p == cfunc && IR->stabline) - (*IR->stabline)(&p->src); -} -Interface mipsebIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, stabinit, stabline, stabsym, 0, - { - 4, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}, mipselIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, stabinit, stabline, stabsym, 0, - { - 4, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}; -static char rcsid[] = "$Id: mips.md 145 2001-10-17 21:53:10Z timo $"; diff --git a/lcc/src/null.c b/lcc/src/null.c deleted file mode 100644 index b9f551c..0000000 --- a/lcc/src/null.c +++ /dev/null @@ -1,74 +0,0 @@ -#include "c.h" -#define I(f) null_##f - -static Node I(gen)(Node p) { return p; } -static void I(address)(Symbol q, Symbol p, long n) {} -static void I(blockbeg)(Env *e) {} -static void I(blockend)(Env *e) {} -static void I(defaddress)(Symbol p) {} -static void I(defconst)(int suffix, int size, Value v) {} -static void I(defstring)(int len, char *s) {} -static void I(defsymbol)(Symbol p) {} -static void I(emit)(Node p) {} -static void I(export)(Symbol p) {} -static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) {} -static void I(global)(Symbol p) {} -static void I(import)(Symbol p) {} -static void I(local)(Symbol p) {} -static void I(progbeg)(int argc, char *argv[]) {} -static void I(progend)(void) {} -static void I(segment)(int s) {} -static void I(space)(int n) {} -static void I(stabblock)(int brace, int lev, Symbol *p) {} -static void I(stabend)(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) {} -static void I(stabfend)(Symbol p, int lineno) {} -static void I(stabinit)(char *file, int argc, char *argv[]) {} -static void I(stabline)(Coordinate *cp) {} -static void I(stabsym)(Symbol p) {} -static void I(stabtype)(Symbol p) {} - - -Interface nullIR = { - {1, 1, 0}, /* char */ - {2, 2, 0}, /* short */ - {4, 4, 0}, /* int */ - {8, 8, 1}, /* long */ - {8 ,8, 1}, /* long long */ - {4, 4, 1}, /* float */ - {8, 8, 1}, /* double */ - {16,16,1}, /* long double */ - {4, 4, 0}, /* T* */ - {0, 4, 0}, /* struct */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 0, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - I(address), - I(blockbeg), - I(blockend), - I(defaddress), - I(defconst), - I(defstring), - I(defsymbol), - I(emit), - I(export), - I(function), - I(gen), - I(global), - I(import), - I(local), - I(progbeg), - I(progend), - I(segment), - I(space), - I(stabblock), - I(stabend), - I(stabfend), - I(stabinit), - I(stabline), - I(stabsym), - I(stabtype) -}; diff --git a/lcc/src/output.c b/lcc/src/output.c deleted file mode 100644 index a9c93e7..0000000 --- a/lcc/src/output.c +++ /dev/null @@ -1,135 +0,0 @@ -#include "c.h" - - -static char *outs(const char *str, FILE *f, char *bp) { - if (f) - fputs(str, f); - else - while ((*bp = *str++)) - bp++; - return bp; -} - -static char *outd(long n, FILE *f, char *bp) { - unsigned long m; - char buf[25], *s = buf + sizeof buf; - - *--s = '\0'; - if (n < 0) - m = -n; - else - m = n; - do - *--s = m%10 + '0'; - while ((m /= 10) != 0); - if (n < 0) - *--s = '-'; - return outs(s, f, bp); -} - -static char *outu(unsigned long n, int base, FILE *f, char *bp) { - char buf[25], *s = buf + sizeof buf; - - *--s = '\0'; - do - *--s = "0123456789abcdef"[n%base]; - while ((n /= base) != 0); - return outs(s, f, bp); -} -void print(const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprint(stdout, NULL, fmt, ap); - va_end(ap); -} -/* fprint - formatted output to f */ -void fprint(FILE *f, const char *fmt, ...) { - va_list ap; - - va_start(ap, fmt); - vfprint(f, NULL, fmt, ap); - va_end(ap); -} - -/* stringf - formatted output to a saved string */ -char *stringf(const char *fmt, ...) { - char buf[1024]; - va_list ap; - - va_start(ap, fmt); - vfprint(NULL, buf, fmt, ap); - va_end(ap); - return string(buf); -} - -/* vfprint - formatted output to f or string bp */ -void vfprint(FILE *f, char *bp, const char *fmt, va_list ap) { - for (; *fmt; fmt++) - if (*fmt == '%') - switch (*++fmt) { - case 'd': bp = outd(va_arg(ap, int), f, bp); break; - case 'D': bp = outd(va_arg(ap, long), f, bp); break; - case 'U': bp = outu(va_arg(ap, unsigned long), 10, f, bp); break; - case 'u': bp = outu(va_arg(ap, unsigned), 10, f, bp); break; - case 'o': bp = outu(va_arg(ap, unsigned), 8, f, bp); break; - case 'X': bp = outu(va_arg(ap, unsigned long), 16, f, bp); break; - case 'x': bp = outu(va_arg(ap, unsigned), 16, f, bp); break; - case 'f': case 'e': - case 'g': { - static char format[] = "%f"; - char buf[128]; - format[1] = *fmt; - sprintf(buf, format, va_arg(ap, double)); - bp = outs(buf, f, bp); - } -; break; - case 's': bp = outs(va_arg(ap, char *), f, bp); break; - case 'p': { - void *p = va_arg(ap, void *); - if (p) - bp = outs("0x", f, bp); - bp = outu((unsigned long)p, 16, f, bp); - break; - } - case 'c': if (f) fputc(va_arg(ap, int), f); else *bp++ = va_arg(ap, int); break; - case 'S': { char *s = va_arg(ap, char *); - int n = va_arg(ap, int); - if (s) { - for ( ; n-- > 0; s++) - if (f) (void)putc(*s, f); else *bp++ = *s; - } - } break; - case 'k': { int t = va_arg(ap, int); - static char *tokens[] = { -#define xx(a,b,c,d,e,f,g) g, -#define yy(a,b,c,d,e,f,g) g, -#include "token.h" - }; - assert(tokens[t&0177]); - bp = outs(tokens[t&0177], f, bp); - } break; - case 't': { Type ty = va_arg(ap, Type); - assert(f); - outtype(ty ? ty : voidtype, f); - } break; - case 'w': { Coordinate *p = va_arg(ap, Coordinate *); - if (p->file && *p->file) { - bp = outs(p->file, f, bp); - bp = outs(":", f, bp); - } - bp = outd(p->y, f, bp); - } break; - case 'I': { int n = va_arg(ap, int); - while (--n >= 0) - if (f) (void)putc(' ', f); else *bp++ = ' '; - } break; - default: if (f) (void)putc(*fmt, f); else *bp++ = *fmt; break; - } - else if (f) - (void)putc(*fmt, f); - else - *bp++ = *fmt; - if (!f) - *bp = '\0'; -} diff --git a/lcc/src/pass2.c b/lcc/src/pass2.c deleted file mode 100644 index 08d73cf..0000000 --- a/lcc/src/pass2.c +++ /dev/null @@ -1,665 +0,0 @@ -#include "c.h" -#include "rcc.h" -#if WIN32 -#include <fcntl.h> -#include <io.h> -#endif - - -Interface *IR = NULL; -int Aflag; /* >= 0 if -A specified */ -int Pflag; /* != 0 if -P specified */ -int glevel; /* == [0-9] if -g[0-9] specified */ -int xref; /* != 0 for cross-reference data */ -Symbol YYnull; /* _YYnull symbol if -n or -nvalidate specified */ -Symbol YYcheck; /* _YYcheck symbol if -nvalidate,check specified */ - -static int verbose = 1; -#define VERBOSE(n,arg) (verbose >= n ? (void)(arg):(void)0) -static int nuids; -static rcc_item_ty *items; -static void **itemmap; - -static void *uid2type(int uid) { - assert(uid >= 0 && uid < nuids); - if (itemmap[uid] == NULL) { - Type ty; - rcc_type_ty type = (void *)items[uid]; - assert(items[uid]); - assert(items[uid]->uid == uid); - assert(items[uid]->kind == rcc_Type_enum); - type = items[uid]->v.rcc_Type.type; - assert(type); - switch (type->kind) { - case rcc_INT_enum: - ty = btot(INT, type->size); - assert(ty->align == type->align); - break; - case rcc_UNSIGNED_enum: - ty = btot(UNSIGNED, type->size); - assert(ty->align == type->align); - break; - case rcc_FLOAT_enum: - ty = btot(FLOAT, type->size); - assert(ty->align == type->align); - break; - case rcc_VOID_enum: - ty = voidtype; - break; - case rcc_POINTER_enum: - ty = ptr(uid2type(type->v.rcc_POINTER.type)); - break; - case rcc_ARRAY_enum: - ty = uid2type(type->v.rcc_ARRAY.type); - assert(ty->size > 0); - ty = array(ty, type->size/ty->size, 0); - break; - case rcc_CONST_enum: - ty = qual(CONST, uid2type(type->v.rcc_CONST.type)); - break; - case rcc_VOLATILE_enum: - ty = qual(VOLATILE, uid2type(type->v.rcc_VOLATILE.type)); - break; - case rcc_ENUM_enum: { - int i, n = Seq_length(type->v.rcc_ENUM.ids); - ty = newstruct(ENUM, string(type->v.rcc_ENUM.tag)); - ty->type = inttype; - ty->size = ty->type->size; - ty->align = ty->type->align; - ty->u.sym->u.idlist = newarray(n + 1, sizeof *ty->u.sym->u.idlist, PERM); - for (i = 0; i < n; i++) { - rcc_enum__ty e = Seq_remlo(type->v.rcc_ENUM.ids); - Symbol p = install(e->id, &identifiers, GLOBAL, PERM); - p->type = ty; - p->sclass = ENUM; - p->u.value = e->value; - ty->u.sym->u.idlist[i] = p; - free(e); - } - ty->u.sym->u.idlist[i] = NULL; - Seq_free(&type->v.rcc_ENUM.ids); - break; - } - case rcc_STRUCT_enum: case rcc_UNION_enum: { - int i, n; - Field *tail; - list_ty fields; - if (type->kind == rcc_STRUCT_enum) { - ty = newstruct(STRUCT, string(type->v.rcc_STRUCT.tag)); - fields = type->v.rcc_STRUCT.fields; - } else { - ty = newstruct(UNION, string(type->v.rcc_UNION.tag)); - fields = type->v.rcc_UNION.fields; - } - itemmap[uid] = ty; /* recursive types */ - ty->size = type->size; - ty->align = type->align; - tail = &ty->u.sym->u.s.flist; - n = Seq_length(fields); - for (i = 0; i < n; i++) { - rcc_field_ty field = Seq_remlo(fields); - NEW0(*tail, PERM); - (*tail)->name = (char *)field->id; - (*tail)->type = uid2type(field->type); - (*tail)->offset = field->offset; - (*tail)->bitsize = field->bitsize; - (*tail)->lsb = field->lsb; - if (isconst((*tail)->type)) - ty->u.sym->u.s.cfields = 1; - if (isvolatile((*tail)->type)) - ty->u.sym->u.s.vfields = 1; - tail = &(*tail)->link; - free(field); - } - Seq_free(&fields); - break; - } - case rcc_FUNCTION_enum: { - int n = Seq_length(type->v.rcc_FUNCTION.formals); - if (n > 0) { - int i; - Type *proto = newarray(n + 1, sizeof *proto, PERM); - for (i = 0; i < n; i++) { - int *formal = Seq_remlo(type->v.rcc_FUNCTION.formals); - proto[i] = uid2type(*formal); - free(formal); - } - proto[i] = NULL; - ty = func(uid2type(type->v.rcc_FUNCTION.type), proto, 0); - } else - ty = func(uid2type(type->v.rcc_FUNCTION.type), NULL, 1); - Seq_free(&type->v.rcc_FUNCTION.formals); - break; - } - default: assert(0); - } - if (itemmap[uid] == NULL) { - itemmap[uid] = ty; - free(type); - free(items[uid]); - items[uid] = NULL; - } else - assert(itemmap[uid] == ty); - } - return itemmap[uid]; -} - -static Symbol uid2symbol(int uid) { - assert(uid >= 0 && uid < nuids); - if (itemmap[uid] == NULL) { - Symbol p; - rcc_symbol_ty symbol; - assert(items[uid]); - assert(items[uid]->uid == uid); - assert(items[uid]->kind == rcc_Symbol_enum); - symbol = items[uid]->v.rcc_Symbol.symbol; - assert(symbol); - NEW0(p, PERM); - p->name = (char *)symbol->id; - p->scope = symbol->scope; - p->sclass = symbol->sclass; - p->type = uid2type(symbol->type); -#define xx(f,n) p->f = symbol->flags>>n; - xx(structarg,0) - xx(addressed,1) - xx(computed,2) - xx(temporary,3) - xx(generated,4) -#undef xx - p->ref = symbol->ref/10000.0; - assert(p->scope != CONSTANTS && p->scope != LABELS); - if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) - (*IR->defsymbol)(p); - itemmap[uid] = p; - free(symbol); - free(items[uid]); - items[uid] = NULL; - } - return itemmap[uid]; -} - -#define xx(s) static void do##s(rcc_interface_ty); -xx(Export) -xx(Import) -xx(Global) -xx(Local) -xx(Address) -xx(Segment) -xx(Defaddress) -xx(Deflabel) -xx(Defconst) -xx(Defconstf) -xx(Defstring) -xx(Space) -xx(Function) -xx(Blockbeg) -xx(Blockend) -xx(Forest) -#undef xx -static void (*doX[])(rcc_interface_ty in) = { -#define xx(s) 0, -xx(Export) -xx(Import) -xx(Global) -xx(Local) -xx(Address) -xx(Segment) -xx(Defaddress) -xx(Deflabel) -xx(Defconst) -xx(Defconstf) -xx(Defstring) -xx(Space) -xx(Function) -xx(Blockbeg) -xx(Blockend) -xx(Forest) - 0 -#undef xx -}; - -static void interface(rcc_interface_ty in) { - assert(in); - (*doX[in->kind])(in); - free(in); -} - -static void doExport(rcc_interface_ty in) { - (*IR->export)(uid2symbol(in->v.rcc_Export.p)); -} - -static void doImport(rcc_interface_ty in) { - Symbol p = uid2symbol(in->v.rcc_Export.p); - - (*IR->import)(p); - p->defined = 1; -} - -static void doGlobal(rcc_interface_ty in) { - Symbol p = uid2symbol(in->v.rcc_Global.p); - - p->u.seg = in->v.rcc_Global.seg; - (*IR->global)(p); - p->defined = 1; -} - -static void doLocal(rcc_interface_ty in) { - int uid = in->v.rcc_Local.uid; - - assert(uid >= 0 && uid < nuids); - assert(items[uid] == NULL); - items[uid] = rcc_Symbol(uid, in->v.rcc_Local.p); - if (in->v.rcc_Local.p->scope >= LOCAL) - addlocal(uid2symbol(uid)); -} - -static void doAddress(rcc_interface_ty in) { - int uid = in->v.rcc_Address.uid; - Symbol p = uid2symbol(in->v.rcc_Address.p); - - assert(uid >= 0 && uid < nuids); - assert(items[uid] == NULL); - items[uid] = rcc_Symbol(uid, in->v.rcc_Address.q); - if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) - (*IR->address)(uid2symbol(uid), p, in->v.rcc_Address.n); - else { - Code cp = code(Address); - cp->u.addr.sym = uid2symbol(uid); - cp->u.addr.base = p; - cp->u.addr.offset = in->v.rcc_Address.n; - } -} - -static void doSegment(rcc_interface_ty in) { - (*IR->segment)(in->v.rcc_Segment.seg); -} - -static void doDefaddress(rcc_interface_ty in) { - (*IR->defaddress)(uid2symbol(in->v.rcc_Defaddress.p)); -} - -static void doDeflabel(rcc_interface_ty in) { - (*IR->defaddress)(findlabel(in->v.rcc_Deflabel.label)); -} - -static void doDefconst(rcc_interface_ty in) { - Value v; - - v.i = in->v.rcc_Defconst.value; - (*IR->defconst)(in->v.rcc_Defconst.suffix, in->v.rcc_Defconst.size, v); -} - -static void doDefconstf(rcc_interface_ty in) { - Value v; - unsigned *p = (unsigned *)&v.d; - - p[swap] = in->v.rcc_Defconstf.value->msb; - p[1-swap] = in->v.rcc_Defconstf.value->lsb; - (*IR->defconst)(F, in->v.rcc_Defconstf.size, v); - free(in->v.rcc_Defconstf.value); -} - -static void doDefstring(rcc_interface_ty in) { - (*IR->defstring)(in->v.rcc_Defstring.s.len, (char *)in->v.rcc_Defstring.s.str); - free((char *)in->v.rcc_Defstring.s.str); -} - -static void doSpace(rcc_interface_ty in) { - (*IR->space)(in->v.rcc_Space.n); -} - -static void doFunction(rcc_interface_ty in) { - int i, n; - Symbol *caller, *callee; - - /* - Initialize: - define the function symbol, - initialize callee and caller arrays. - */ - cfunc = uid2symbol(in->v.rcc_Function.f); - labels = table(NULL, LABELS); - enterscope(); - n = Seq_length(in->v.rcc_Function.caller); - caller = newarray(n + 1, sizeof *caller, FUNC); - for (i = 0; i < n; i++) { - int *uid = Seq_remlo(in->v.rcc_Function.caller); - caller[i] = uid2symbol(*uid); - free(uid); - } - caller[i] = NULL; - Seq_free(&in->v.rcc_Function.caller); - callee = newarray(n + 1, sizeof *callee, FUNC); - for (i = 0; i < n; i++) { - int *uid = Seq_remlo(in->v.rcc_Function.callee); - callee[i] = uid2symbol(*uid); - free(uid); - } - callee[i] = NULL; - Seq_free(&in->v.rcc_Function.callee); - cfunc->u.f.callee = callee; - cfunc->defined = 1; - /* - Initialize the code list, - traverse the interfaces inside the function; - each call appends code list entries. - */ - codelist = &codehead; - codelist->next = NULL; - n = Seq_length(in->v.rcc_Function.codelist); - for (i = 0; i < n; i++) - interface(Seq_remlo(in->v.rcc_Function.codelist)); - Seq_free(&in->v.rcc_Function.codelist); - /* - Call the back end, - Wrap-up. - */ - exitscope(); - (*IR->function)(cfunc, caller, callee, in->v.rcc_Function.ncalls); - cfunc = NULL; - labels = NULL; -} - -static struct block { - Code begin; - struct block *prev; -} *blockstack = NULL; - -static void doBlockbeg(rcc_interface_ty in) { - struct block *b; - Code cp = code(Blockbeg); - - enterscope(); - cp->u.block.level = level; - cp->u.block.locals = newarray(1, sizeof *cp->u.block.locals, FUNC); - cp->u.block.locals[0] = NULL; - cp->u.block.identifiers = NULL; - cp->u.block.types = NULL; - NEW(b, FUNC); - b->begin = cp; - b->prev = blockstack; - blockstack = b; -} - -static void doBlockend(rcc_interface_ty in) { - assert(blockstack); - code(Blockend)->u.begin = blockstack->begin; - blockstack = blockstack->prev; - exitscope(); -} - -static Node visit(rcc_node_ty node) { - int op; - Node left = NULL, right = NULL, p = NULL; - Symbol sym = NULL; - - switch (node->kind) { -#define T(x) rcc_##x##_enum - case T(CSE): { - Symbol q = uid2symbol(node->v.rcc_CSE.uid); - assert(q->temporary); - q->u.t.cse = p = visit(node->v.rcc_CSE.node); - break; - } - case T(CNST): { - Value v; - v.i = node->v.rcc_CNST.value; - sym = constant(btot(node->suffix, node->size), v); - op = CNST; - break; - } - case T(CNSTF): { - Value v; - unsigned *p = (unsigned *)&v.d; - p[swap] = node->v.rcc_CNSTF.value->msb; - p[1-swap] = node->v.rcc_CNSTF.value->lsb; - sym = constant(btot(node->suffix, node->size), v); - free(node->v.rcc_CNSTF.value); - op = CNST; - break; - } - case T(ARG): - p = newnode(ARG + node->suffix + sizeop(node->size), - visit(node->v.rcc_ARG.left), NULL, - intconst(node->v.rcc_ARG.len)); - p->syms[1] = intconst(node->v.rcc_ARG.align); - break; - case T(ASGN): - p = newnode(ASGN + node->suffix + sizeop(node->size), - visit(node->v.rcc_ASGN.left), visit(node->v.rcc_ASGN.right), - intconst(node->v.rcc_ASGN.len)); - p->syms[1] = intconst(node->v.rcc_ASGN.align); - break; - case T(CVT): - op = node->v.rcc_CVT.op; - left = visit(node->v.rcc_CVT.left); - sym = intconst(node->v.rcc_CVT.fromsize); - break; - case T(CALL): - op = CALL; - left = visit(node->v.rcc_CALL.left); - NEW0(sym, FUNC); - sym->type = uid2type(node->v.rcc_CALL.type); - break; - case T(CALLB): - op = CALL; - left = visit(node->v.rcc_CALLB.left); - right = visit(node->v.rcc_CALLB.right); - NEW0(sym, FUNC); - sym->type = uid2type(node->v.rcc_CALLB.type); - break; - case T(RET): - op = RET; - break; - case T(ADDRG): - op = ADDRG; - sym = uid2symbol(node->v.rcc_ADDRG.uid); - break; - case T(ADDRL): - op = ADDRL; - sym = uid2symbol(node->v.rcc_ADDRG.uid); - break; - case T(ADDRF): - op = ADDRF; - sym = uid2symbol(node->v.rcc_ADDRG.uid); - break; - case T(Unary): - op = node->v.rcc_Unary.op; - left = visit(node->v.rcc_Unary.left); - break; - case T(Binary): - op = node->v.rcc_Binary.op; - left = visit(node->v.rcc_Binary.left); - right = visit(node->v.rcc_Binary.right); - break; - case T(Compare): - op = node->v.rcc_Compare.op; - left = visit(node->v.rcc_Compare.left); - right = visit(node->v.rcc_Compare.right); - sym = findlabel(node->v.rcc_Compare.label); - break; - case T(LABEL): - op = LABEL; - sym = findlabel(node->v.rcc_LABEL.label); - break; - case T(BRANCH): - op = JUMP; - left = newnode(ADDRG+P+sizeop(voidptype->size), NULL, NULL, findlabel(node->v.rcc_BRANCH.label)); - break; -#undef T - default: assert(0); - } - if (p == NULL) - p = newnode(op + node->suffix + sizeop(node->size), left, right, sym); - free(node); - return p; -} - -static void doForest(rcc_interface_ty in) { - Node *tail = &code(Gen)->u.forest; - int i, n = Seq_length(in->v.rcc_Forest.nodes); - - for (i = 0; i < n; i++) { - *tail = visit(Seq_remlo(in->v.rcc_Forest.nodes)); - assert(*tail); - tail = &(*tail)->link; - } - *tail = NULL; - Seq_free(&in->v.rcc_Forest.nodes); -} - -int main(int argc, char *argv[]) { - int i, version; - float stamp = (assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL)) -; - char *infile = NULL, *outfile = NULL; - rcc_program_ty pickle; - - for (i = 1; i < argc; i++) - if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) { - if (infile == NULL) - infile = argv[i]; - else if (outfile == NULL) - outfile = argv[i]; - } - if (infile != NULL && strcmp(infile, "-") != 0 - && freopen(infile, "rb", stdin) == NULL) { - fprint(stderr, "%s: can't read `%s'\n", argv[0], infile); - exit(EXIT_FAILURE); - } -#if WIN32 - else - _setmode(_fileno(stdin), _O_BINARY); -#endif - if (outfile != NULL && strcmp(outfile, "-") != 0 - && freopen(outfile, "w", stdout) == NULL) { - fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile); - exit(EXIT_FAILURE); - } - version = read_int(stdin); - assert(version/100 == (int)stamp); - pickle = rcc_read_program(stdin); - argc = pickle->argc; - argv = newarray(argc + 1, sizeof *argv, PERM); - { - for (i = 0; i < argc; i++) { - string_ty *arg = Seq_remlo(pickle->argv); - argv[i] = (char *)arg->str; - free(arg); - } - argv[i] = NULL; - assert(i == argc); - Seq_free(&pickle->argv); - } - for (i = argc - 1; i > 0; i--) - if (strncmp(argv[i], "-target=", 8) == 0) - break; - if (i > 0) { - int j; - for (j = 0; bindings[j].name && bindings[j].ir; j++) - if (strcmp(&argv[i][8], bindings[j].name) == 0) { - IR = bindings[j].ir; - break; - } - } - if (!IR) { - fprint(stderr, "%s: unknown target", argv[0]); - if (i > 0) - fprint(stderr, " `%s'", &argv[i][8]); - fprint(stderr, "; must specify one of\n"); - for (i = 0; bindings[i].name; i++) - fprint(stderr, "\t-target=%s\n", bindings[i].name); - exit(EXIT_FAILURE); - } - IR->wants_dag = 0; /* pickle's hold trees */ - init(argc, argv); - genlabel(pickle->nlabels); - level = GLOBAL; - { - int i, count; - nuids = pickle->nuids; - items = newarray(nuids, sizeof *items, PERM); - itemmap = newarray(nuids, sizeof *items, PERM); - for (i = 0; i < nuids; i++) { - itemmap[i] = NULL; - items[i] = NULL; - } - (*IR->progbeg)(argc, argv); - count = Seq_length(pickle->items); - for (i = 0; i < count; i++) { - rcc_item_ty item = Seq_remlo(pickle->items); - int uid = item->uid; - assert(uid >= 0 && uid < nuids); - assert(items[uid] == NULL); - items[uid] = item; - } - Seq_free(&pickle->items); -#define xx(s) assert(rcc_##s##_enum < sizeof doX/sizeof doX[0] && doX[rcc_##s##_enum]==0); \ - doX[rcc_##s##_enum] = do##s; - xx(Export) - xx(Import) - xx(Global) - xx(Local) - xx(Address) - xx(Segment) - xx(Defaddress) - xx(Deflabel) - xx(Defconst) - xx(Defconstf) - xx(Defstring) - xx(Space) - xx(Function) - xx(Blockbeg) - xx(Blockend) - xx(Forest) -#undef xx - count = Seq_length(pickle->interfaces); - for (i = 0; i < count; i++) - interface(Seq_remlo(pickle->interfaces)); - Seq_free(&pickle->interfaces); - free(pickle); - (*IR->progend)(); - } - deallocate(PERM); - return errcnt > 0; -} - -/* main_init - process program arguments */ -void main_init(int argc, char *argv[]) { - int i; - static int inited; - - if (inited) - return; - inited = 1; - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0) - glevel = 2; - else if (strcmp(argv[i], "-w") == 0) - wflag++; - else if (strcmp(argv[i], "-v") == 0) { - fprint(stderr, "%s %s\n", argv[0], rcsid); - verbose++; - } else if (strncmp(argv[i], "-errout=", 8) == 0) { - FILE *f = fopen(argv[i]+8, "w"); - if (f == NULL) { - fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8); - exit(EXIT_FAILURE); - } - fclose(f); - f = freopen(argv[i]+8, "w", stderr); - assert(f); - } else if (strncmp(argv[i], "-e", 2) == 0) { - int x; - if ((x = strtol(&argv[i][2], NULL, 0)) > 0) - errlimit = x; - } -} - -void init(int argc, char *argv[]) { - {extern void main_init(int, char *[]); main_init(argc, argv);} - {extern void prof_init(int, char *[]); prof_init(argc, argv);} - {extern void trace_init(int, char *[]); trace_init(argc, argv);} - {extern void type_init(int, char *[]); type_init(argc, argv);} - {extern void x86linux_init(int, char *[]); x86linux_init(argc, argv);} -} diff --git a/lcc/src/prof.c b/lcc/src/prof.c deleted file mode 100644 index 02709ed..0000000 --- a/lcc/src/prof.c +++ /dev/null @@ -1,228 +0,0 @@ -#include "c.h" - - -struct callsite { - char *file, *name; - union coordinate { - unsigned int coord; - struct { unsigned int y:16,x:10,index:6; } le; - struct { unsigned int index:6,x:10,y:16; } be; - } u; -}; -struct func { - struct func *link; - struct caller *callers; - char *name; - union coordinate src; -}; -struct map { /* source code map; 200 coordinates/map */ - int size; - union coordinate u[200]; -}; - -int npoints; /* # of execution points if -b specified */ -int ncalled = -1; /* #times prof.out says current function was called */ -static Symbol YYlink; /* symbol for file's struct _bbdata */ -static Symbol YYcounts; /* symbol for _YYcounts if -b specified */ -static List maplist; /* list of struct map *'s */ -static List filelist; /* list of file names */ -static Symbol funclist; /* list of struct func *'s */ -static Symbol afunc; /* current function's struct func */ - -/* bbcall - build tree to set _callsite at call site *cp, emit call site data */ -static void bbcall(Symbol yycounts, Coordinate *cp, Tree *e) { - static Symbol caller; - Value v; - union coordinate u; - Symbol p = genident(STATIC, array(voidptype, 0, 0), GLOBAL); - Tree t = *e; - - defglobal(p, LIT); - defpointer(cp->file ? mkstr(cp->file)->u.c.loc : (Symbol)0); - defpointer(mkstr(cfunc->name)->u.c.loc); - if (IR->little_endian) { - u.le.x = cp->x; - u.le.y = cp->y; - } else { - u.be.x = cp->x; - u.be.y = cp->y; - } - (*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v)); - if (caller == 0) { - caller = mksymbol(EXTERN, "_caller", ptr(voidptype)); - caller->defined = 0; - } - if (generic((*e)->op) != CALL) - t = (*e)->kids[0]; - assert(generic(t->op) == CALL); - t = tree(t->op, t->type, - tree(RIGHT, t->kids[0]->type, - t->kids[0], - tree(RIGHT, t->kids[0]->type, asgn(caller, idtree(p)), t->kids[0])), - t->kids[1]); - if (generic((*e)->op) != CALL) - t = tree((*e)->op, (*e)->type, t, (*e)->kids[1]); - *e = t; -} - -/* bbentry - return tree for _prologue(&afunc, &YYlink)' */ -static void bbentry(Symbol yylink, Symbol f) { - static Symbol prologue; - - afunc = genident(STATIC, array(voidptype, 4, 0), GLOBAL); - if (prologue == 0) { - prologue = mksymbol(EXTERN, "_prologue", ftype(inttype, voidptype)); - prologue->defined = 0; - } - walk(vcall(prologue, voidtype, pointer(idtree(afunc)), pointer(idtree(yylink)), NULL), 0, 0); - -} - -/* bbexit - return tree for _epilogue(&afunc)' */ -static void bbexit(Symbol yylink, Symbol f, Tree e) { - static Symbol epilogue; - - if (epilogue == 0) { - epilogue = mksymbol(EXTERN, "_epilogue", ftype(inttype, voidptype)); - epilogue->defined = 0; - } - walk(vcall(epilogue, voidtype, pointer(idtree(afunc)), NULL), 0, 0); -} - -/* bbfile - add file to list of file names, return its index */ -static int bbfile(char *file) { - if (file) { - List lp; - int i = 1; - if ((lp = filelist) != NULL) - do { - lp = lp->link; - if (((Symbol)lp->x)->u.c.v.p == file) - return i; - i++; - } while (lp != filelist); - filelist = append(mkstr(file), filelist); - return i; - } - return 0; -} - -/* bbfunc - emit function name and src coordinates */ -static void bbfunc(Symbol yylink, Symbol f) { - Value v; - union coordinate u; - - defglobal(afunc, DATA); - defpointer(funclist); - defpointer(NULL); - defpointer(mkstr(f->name)->u.c.loc); - if (IR->little_endian) { - u.le.x = f->u.f.pt.x; - u.le.y = f->u.f.pt.y; - u.le.index = bbfile(f->u.f.pt.file); - } else { - u.be.x = f->u.f.pt.x; - u.be.y = f->u.f.pt.y; - u.be.index = bbfile(f->u.f.pt.file); - } - (*IR->defconst)(U, unsignedtype->size, (v.u = u.coord, v)); - funclist = afunc; -} - -/* bbincr - build tree to increment execution point at *cp */ -static void bbincr(Symbol yycounts, Coordinate *cp, Tree *e) { - struct map *mp = maplist->x; - Tree t; - - /* append *cp to source map */ - if (mp->size >= NELEMS(mp->u)) { - NEW(mp, PERM); - mp->size = 0; - maplist = append(mp, maplist); - } - if (IR->little_endian) { - mp->u[mp->size].le.x = cp->x; - mp->u[mp->size].le.y = cp->y; - mp->u[mp->size++].le.index = bbfile(cp->file); - } else { - mp->u[mp->size].be.x = cp->x; - mp->u[mp->size].be.y = cp->y; - mp->u[mp->size++].be.index = bbfile(cp->file); - } - t = incr('+', rvalue((*optree['+'])(ADD, pointer(idtree(yycounts)), - consttree(npoints++, inttype))), consttree(1, inttype)); - if (*e) - *e = tree(RIGHT, (*e)->type, t, *e); - else - *e = t; -} - -/* bbvars - emit definition for basic block counting data */ -static void bbvars(Symbol yylink) { - int i, j, n = npoints; - Value v; - struct map **mp; - Symbol coords, files, *p; - - if (!YYcounts && !yylink) - return; - if (YYcounts) { - if (n <= 0) - n = 1; - YYcounts->type = array(unsignedtype, n, 0); - defglobal(YYcounts, BSS); - } - files = genident(STATIC, array(charptype, 1, 0), GLOBAL); - defglobal(files, LIT); - for (p = ltov(&filelist, PERM); *p; p++) - defpointer((*p)->u.c.loc); - defpointer(NULL); - coords = genident(STATIC, array(unsignedtype, n, 0), GLOBAL); - defglobal(coords, LIT); - for (i = n, mp = ltov(&maplist, PERM); *mp; i -= (*mp)->size, mp++) - for (j = 0; j < (*mp)->size; j++) - (*IR->defconst)(U, unsignedtype->size, (v.u = (*mp)->u[j].coord, v)); - if (i > 0) - (*IR->space)(i*coords->type->type->size); - defpointer(NULL); - defglobal(yylink, DATA); - defpointer(NULL); - (*IR->defconst)(U, unsignedtype->size, (v.u = n, v)); - defpointer(YYcounts); - defpointer(coords); - defpointer(files); - defpointer(funclist); -} - -/* profInit - initialize basic block profiling options */ -void prof_init(int argc, char *argv[]) { - int i; - static int inited; - - if (inited) - return; - inited = 1; - type_init(argc, argv); - if (IR) { - for (i = 1; i < argc; i++) - if (strncmp(argv[i], "-a", 2) == 0) { - if (ncalled == -1 - && process(argv[i][2] ? &argv[i][2] : "prof.out") > 0) - ncalled = 0; - } else if ((strcmp(argv[i], "-b") == 0 - || strcmp(argv[i], "-C") == 0) && YYlink == 0) { - YYlink = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL); - attach((Apply)bbentry, YYlink, &events.entry); - attach((Apply)bbexit, YYlink, &events.returns); - attach((Apply)bbfunc, YYlink, &events.exit); - attach((Apply)bbvars, YYlink, &events.end); - if (strcmp(argv[i], "-b") == 0) { - YYcounts = genident(STATIC, array(unsignedtype, 0, 0), GLOBAL); - maplist = append(allocate(sizeof (struct map), PERM), maplist); - ((struct map *)maplist->x)->size = 0; - attach((Apply)bbcall, YYcounts, &events.calls); - attach((Apply)bbincr, YYcounts, &events.points); - } - } - } -} diff --git a/lcc/src/profio.c b/lcc/src/profio.c deleted file mode 100644 index 37fc25b..0000000 --- a/lcc/src/profio.c +++ /dev/null @@ -1,276 +0,0 @@ -/* C compiler: prof.out input - -prof.out format: -#files - name - ... (#files-1 times) -#functions - name file# x y count caller file x y - ... (#functions-1 times) -#points - file# x y count - ... (#points-1 times) -*/ -#include "c.h" - - -struct count { /* count data: */ - int x, y; /* source coordinate */ - int count; /* associated execution count */ -}; - -#define MAXTOKEN 64 - -struct file { /* per-file prof.out data: */ - struct file *link; /* link to next file */ - char *name; /* file name */ - int size; /* size of counts[] */ - int count; /* counts[0..count-1] hold valid data */ - struct count *counts; /* count data */ - struct func { /* function data: */ - struct func *link; /* link to next function */ - char *name; /* function name */ - struct count count; /* total number of calls */ - struct caller { /* caller data: */ - struct caller *link; /* link to next caller */ - char *name; /* caller's name */ - char *file; /* call site: file, x, y */ - int x, y; - int count; /* number of calls from this site */ - } *callers; - } *funcs; /* list of functions */ -} *filelist; -FILE *fp; - -/* acaller - add caller and site (file,x,y) to callee's callers list */ -static void acaller(char *caller, char *file, int x, int y, int count, struct func *callee) { - struct caller *q; - - assert(callee); - for (q = callee->callers; q && (caller != q->name - || file != q->file || x != q->x || y != q->y); q = q->link) - ; - if (!q) { - struct caller **r; - NEW(q, PERM); - q->name = caller; - q->file = file; - q->x = x; - q->y = y; - q->count = 0; - for (r = &callee->callers; *r && (strcmp(q->name, (*r)->name) > 0 - || strcmp(q->file, (*r)->file) > 0 || q->y > (*r)->y || q->y > (*r)->y); r = &(*r)->link) - ; - q->link = *r; - *r = q; - } - q->count += count; -} - -/* compare - return <0, 0, >0 if a<b, a==b, a>b, resp. */ -static int compare(struct count *a, struct count *b) { - if (a->y == b->y) - return a->x - b->x; - return a->y - b->y; -} - -/* findfile - return file name's file list entry, or 0 */ -static struct file *findfile(char *name) { - struct file *p; - - for (p = filelist; p; p = p->link) - if (p->name == name) - return p; - return 0; -} - -/* afunction - add function name and its data to file's function list */ -static struct func *afunction(char *name, char *file, int x, int y, int count) { - struct file *p = findfile(file); - struct func *q; - - assert(p); - for (q = p->funcs; q && name != q->name; q = q->link) - ; - if (!q) { - struct func **r; - NEW(q, PERM); - q->name = name; - q->count.x = x; - q->count.y = y; - q->count.count = 0; - q->callers = 0; - for (r = &p->funcs; *r && compare(&q->count, &(*r)->count) > 0; r = &(*r)->link) - ; - q->link = *r; - *r = q; - } - q->count.count += count; - return q; -} - -/* apoint - append execution point i to file's data */ -static void apoint(int i, char *file, int x, int y, int count) { - struct file *p = findfile(file); - - assert(p); - if (i >= p->size) { - int j; - if (p->size == 0) { - p->size = i >= 200 ? 2*i : 200; - p->counts = newarray(p->size, sizeof *p->counts, PERM); - } else { - struct count *new; - p->size = 2*i; - new = newarray(p->size, sizeof *new, PERM); - for (j = 0; j < p->count; j++) - new[j] = p->counts[j]; - p->counts = new; - } - for (j = p->count; j < p->size; j++) { - static struct count z; - p->counts[j] = z; - } - } - p->counts[i].x = x; - p->counts[i].y = y; - p->counts[i].count += count; - if (i >= p->count) - p->count = i + 1; -} - -/* findcount - return count associated with (file,x,y) or -1 */ -int findcount(char *file, int x, int y) { - static struct file *cursor; - - if (cursor == 0 || cursor->name != file) - cursor = findfile(file); - if (cursor) { - int l, u; - struct count *c = cursor->counts; - for (l = 0, u = cursor->count - 1; l <= u; ) { - int k = (l + u)/2; - if (c[k].y > y || (c[k].y == y && c[k].x > x)) - u = k - 1; - else if (c[k].y < y || (c[k].y == y && c[k].x < x)) - l = k + 1; - else - return c[k].count; - } - } - return -1; -} - -/* findfunc - return count associated with function name in file or -1 */ -int findfunc(char *name, char *file) { - static struct file *cursor; - - if (cursor == 0 || cursor->name != file) - cursor = findfile(file); - if (cursor) { - struct func *p; - for (p = cursor->funcs; p; p = p->link) - if (p->name == name) - return p->count.count; - } - return -1; -} - -/* getd - read a nonnegative number */ -static int getd(void) { - int c, n = 0; - - while ((c = getc(fp)) != EOF && (c == ' ' || c == '\n' || c == '\t')) - ; - if (c >= '0' && c <= '9') { - do - n = 10*n + (c - '0'); - while ((c = getc(fp)) >= '0' && c <= '9'); - return n; - } - return -1; -} - -/* getstr - read a string */ -static char *getstr(void) { - int c; - char buf[MAXTOKEN], *s = buf; - - while ((c = getc(fp)) != EOF && c != ' ' && c != '\n' && c != '\t') - if (s - buf < (int)sizeof buf - 2) - *s++ = c; - *s = 0; - return s == buf ? (char *)0 : string(buf); -} - -/* gather - read prof.out data from fd */ -static int gather(void) { - int i, nfiles, nfuncs, npoints; - char *files[64]; - - if ((nfiles = getd()) < 0) - return 0; - assert(nfiles < NELEMS(files)); - for (i = 0; i < nfiles; i++) { - if ((files[i] = getstr()) == 0) - return -1; - if (!findfile(files[i])) { - struct file *new; - NEW(new, PERM); - new->name = files[i]; - new->size = new->count = 0; - new->counts = 0; - new->funcs = 0; - new->link = filelist; - filelist = new; - } - } - if ((nfuncs = getd()) < 0) - return -1; - for (i = 0; i < nfuncs; i++) { - struct func *q; - char *name, *file; - int f, x, y, count; - if ((name = getstr()) == 0 || (f = getd()) <= 0 - || (x = getd()) < 0 || (y = getd()) < 0 || (count = getd()) < 0) - return -1; - q = afunction(name, files[f-1], x, y, count); - if ((name = getstr()) == 0 || (file = getstr()) == 0 - || (x = getd()) < 0 || (y = getd()) < 0) - return -1; - if (*name != '?') - acaller(name, file, x, y, count, q); - } - if ((npoints = getd()) < 0) - return -1; - for (i = 0; i < npoints; i++) { - int f, x, y, count; - if ((f = getd()) < 0 || (x = getd()) < 0 || (y = getd()) < 0 - || (count = getd()) < 0) - return -1; - if (f) - apoint(i, files[f-1], x, y, count); - } - return 1; -} - -/* process - read prof.out data from file */ -int process(char *file) { - int more; - - if ((fp = fopen(file, "r")) != NULL) { - struct file *p; - while ((more = gather()) > 0) - ; - fclose(fp); - if (more < 0) - return more; - for (p = filelist; p; p = p->link) - qsort(p->counts, p->count, sizeof *p->counts, - (int (*)(const void *, const void *)) - compare); - - return 1; - } - return 0; -} diff --git a/lcc/src/rcc.asdl b/lcc/src/rcc.asdl deleted file mode 100644 index 398e0d0..0000000 --- a/lcc/src/rcc.asdl +++ /dev/null @@ -1,70 +0,0 @@ --- lcc IR --- $Id: rcc.asdl 145 2001-10-17 21:53:10Z timo $ -module rcc { - --- Pickles start with an int version number, followed by rcc.program - -program = (int nuids,int nlabels,item* items,interface* interfaces,int argc,string *argv) - -real = (int msb,int lsb) - -item = Symbol(symbol symbol) - | Type(type type) - attributes(int uid) - -symbol = (identifier id,int type,int scope,int sclass,int ref,int flags) - -field = (identifier id,int type,int offset,int bitsize,int lsb) - -enum = (identifier id,int value) - -type = INT - | UNSIGNED - | FLOAT - | VOID - | POINTER(int type) - | ENUM(identifier tag,enum* ids) - | STRUCT(identifier tag,field* fields) - | UNION(identifier tag,field* fields) - | ARRAY(int type) - | FUNCTION(int type,int* formals) - | CONST(int type) - | VOLATILE(int type) - attributes(int size,int align) - -interface = Export(int p) - | Import(int p) - | Global(int p,int seg) - | Local(int uid,symbol p) -- includes formals - | Address(int uid,symbol q,int p,int n) - | Segment(int seg) - | Defaddress(int p) - | Deflabel(int label) - | Defconst(int suffix,int size,int value) - | Defconstf(int size,real value) - | Defstring(string s) - | Space(int n) - | Function(int f,int* caller,int* callee,int ncalls,interface* codelist) - | Blockbeg - | Blockend - | Forest(node* nodes) - -node = CNST(int value) - | CNSTF(real value) - | ARG(node left,int len,int align) - | ASGN(node left,node right,int len,int align) - | CVT(int op,node left,int fromsize) - | CALL(node left,int type) - | CALLB(node left,node right,int type) - | RET - | ADDRG(int uid) - | ADDRL(int uid) - | ADDRF(int uid) - | Unary(int op,node left) -- INDIR RET JUMP NEG BCOM - | Binary(int op,node left,node right) -- ADD SUB DIV MUL MOD BOR BAND BXOR RSH LSH - | Compare(int op,node left,node right,int label) -- EQ NE GT GE LE LT - | LABEL(int label) - | BRANCH(int label) - | CSE(int uid,node node) - attributes(int suffix,int size) -} diff --git a/lcc/src/run.sh b/lcc/src/run.sh deleted file mode 100644 index 819e898..0000000 --- a/lcc/src/run.sh +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/sh -# run .../target/os/tst/foo.s [ remotehost ] - -# set -x -target=`echo $1 | awk -F/ '{ print $(NF-3) }'` -os=`echo $1 | awk -F/ '{ print $(NF-2) }'` -dir=$target/$os - -case "$1" in -*symbolic/irix*) idir=include/mips/irix; remotehost=noexecute ;; -*symbolic/osf*) idir=include/alpha/osf; remotehost=noexecute ;; -*) idir=include/$dir; remotehost=${2-$REMOTEHOST} ;; -esac - -if [ ! -d "$target/$os" -o ! -d "$idir" ]; then - echo 2>&1 $0: unknown combination '"'$target/$os'"' - exit 1 -fi - -C=`basename $1 .s` -BUILDDIR=${BUILDDIR-.} LCC="${LCC-${BUILDDIR}/lcc} -Wo-lccdir=$BUILDDIR" -TSTDIR=${TSTDIR-${BUILDDIR}/$dir/tst} -if [ ! -d $TSTDIR ]; then mkdir -p $TSTDIR; fi - -echo ${BUILDDIR}/rcc$EXE -target=$target/$os $1: 1>&2 -$LCC -S -I$idir -Ualpha -Usun -Uvax -Umips -Ux86 \ - -Wf-errout=$TSTDIR/$C.2 -D$target -Wf-g0 \ - -Wf-target=$target/$os -o $1 tst/$C.c -if [ $? != 0 ]; then remotehost=noexecute; fi -if [ -r $dir/tst/$C.2bk ]; then - diff $dir/tst/$C.2bk $TSTDIR/$C.2 -fi -if [ -r $dir/tst/$C.sbk ]; then - if diff $dir/tst/$C.sbk $TSTDIR/$C.s; then exit 0; fi -fi - -case "$remotehost" in -noexecute) exit 0 ;; -""|"-") $LCC -o $TSTDIR/$C$EXE $1; $TSTDIR/$C$EXE <tst/$C.0 >$TSTDIR/$C.1 ;; -*) rcp $1 $remotehost: - if expr "$remotehost" : '.*@' >/dev/null ; then - remotehost="`expr $remotehost : '.*@\(.*\)'` -l `expr $remotehost : '\(.*\)@'`" - fi - rsh $remotehost "cc -o $C$EXE $C.s -lm;./$C$EXE;rm -f $C$EXE $C.[so]" <tst/$C.0 >$TSTDIR/$C.1 - ;; -esac -if [ -r $dir/tst/$C.1bk ]; then - diff $dir/tst/$C.1bk $TSTDIR/$C.1 - exit $? -fi -exit 0 diff --git a/lcc/src/simp.c b/lcc/src/simp.c deleted file mode 100644 index 227dfbb..0000000 --- a/lcc/src/simp.c +++ /dev/null @@ -1,587 +0,0 @@ -#include "c.h" -#include <float.h> - - -#define foldcnst(TYPE,VAR,OP) \ - if (l->op == CNST+TYPE && r->op == CNST+TYPE) \ - return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR) -#define commute(L,R) \ - if (generic(R->op) == CNST && generic(L->op) != CNST) \ - do { Tree t = L; L = R; R = t; } while(0) -#define xfoldcnst(TYPE,VAR,OP,FUNC)\ - if (l->op == CNST+TYPE && r->op == CNST+TYPE\ - && FUNC(l->u.v.VAR,r->u.v.VAR,\ - ty->u.sym->u.limits.min.VAR,\ - ty->u.sym->u.limits.max.VAR, needconst)) \ - return cnsttree(ty, l->u.v.VAR OP r->u.v.VAR) -#define xcvtcnst(FTYPE,SRC,DST,VAR,EXPR) \ - if (l->op == CNST+FTYPE) do {\ - if (!explicitCast\ - && ((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\ - warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, DST);\ - if (needconst\ - || !((SRC) < DST->u.sym->u.limits.min.VAR || (SRC) > DST->u.sym->u.limits.max.VAR))\ - return cnsttree(ty, (EXPR)); } while(0) -#define identity(X,Y,TYPE,VAR,VAL) \ - if (X->op == CNST+TYPE && X->u.v.VAR == VAL) return Y -#define zerofield(OP,TYPE,VAR) \ - if (l->op == FIELD \ - && r->op == CNST+TYPE && r->u.v.VAR == 0)\ - return eqtree(OP, bittree(BAND, l->kids[0],\ - cnsttree(unsignedtype, \ - (unsigned long)fieldmask(l->u.field)<<fieldright(l->u.field))), r) -#define cfoldcnst(TYPE,VAR,OP) \ - if (l->op == CNST+TYPE && r->op == CNST+TYPE) \ - return cnsttree(inttype, (long)(l->u.v.VAR OP r->u.v.VAR)) -#define foldaddp(L,R,RTYPE,VAR) \ - if (L->op == CNST+P && R->op == CNST+RTYPE) { \ - Tree e = tree(CNST+P, ty, NULL, NULL);\ - e->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\ - return e; } -#define ufoldcnst(TYPE,EXP) if (l->op == CNST+TYPE) return EXP -#define sfoldcnst(OP) \ - if (l->op == CNST+U && r->op == CNST+I \ - && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) \ - return cnsttree(ty, (unsigned long)(l->u.v.u OP r->u.v.i)) -#define geu(L,R,V) \ - if (R->op == CNST+U && R->u.v.u == 0) do { \ - warning("result of unsigned comparison is constant\n"); \ - return tree(RIGHT, inttype, root(L), cnsttree(inttype, (long)(V))); } while(0) -#define idempotent(OP) if (l->op == OP) return l->kids[0] - -int needconst; -int explicitCast; -static int addi(long x, long y, long min, long max, int needconst) { - int cond = x == 0 || y == 0 - || (x < 0 && y < 0 && x >= min - y) - || (x < 0 && y > 0) - || (x > 0 && y < 0) - || (x > 0 && y > 0 && x <= max - y); - if (!cond && needconst) { - warning("overflow in constant expression\n"); - cond = 1; - } - return cond; - - -} - -static int addd(double x, double y, double min, double max, int needconst) { - int cond = x == 0 || y == 0 - || (x < 0 && y < 0 && x >= min - y) - || (x < 0 && y > 0) - || (x > 0 && y < 0) - || (x > 0 && y > 0 && x <= max - y); - if (!cond && needconst) { - warning("overflow in constant expression\n"); - cond = 1; - } - return cond; - - -} - -static Tree addrtree(Tree e, long n, Type ty) { - Symbol p = e->u.sym, q; - - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - NEW0(q, PERM); - else - NEW0(q, FUNC); - q->name = stringd(genlabel(1)); - q->sclass = p->sclass; - q->scope = p->scope; - assert(isptr(ty) || isarray(ty)); - q->type = isptr(ty) ? ty->type : ty; - q->temporary = p->temporary; - q->generated = p->generated; - q->addressed = p->addressed; - q->computed = 1; - q->defined = 1; - q->ref = 1; - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) { - if (p->sclass == AUTO) - q->sclass = STATIC; - (*IR->address)(q, p, n); - } else { - Code cp; - addlocal(p); - cp = code(Address); - cp->u.addr.sym = q; - cp->u.addr.base = p; - cp->u.addr.offset = n; - } - e = tree(e->op, ty, NULL, NULL); - e->u.sym = q; - return e; -} - -/* div[id] - return 1 if min <= x/y <= max, 0 otherwise */ -static int divi(long x, long y, long min, long max, int needconst) { - int cond = y != 0 && !(x == min && y == -1); - if (!cond && needconst) { - warning("overflow in constant expression\n"); - cond = 1; - } - return cond; - - -} - -static int divd(double x, double y, double min, double max, int needconst) { - int cond; - - if (x < 0) x = -x; - if (y < 0) y = -y; - cond = y != 0 && !(y < 1 && x > max*y); - if (!cond && needconst) { - warning("overflow in constant expression\n"); - cond = 1; - } - return cond; - -} - -/* mul[id] - return 1 if min <= x*y <= max, 0 otherwise */ -static int muli(long x, long y, long min, long max, int needconst) { - int cond = (x > -1 && x <= 1) || (y > -1 && y <= 1) - || (x < 0 && y < 0 && -x <= max/-y) - || (x < 0 && y > 0 && x >= min/y) - || (x > 0 && y < 0 && y >= min/x) - || (x > 0 && y > 0 && x <= max/y); - if (!cond && needconst) { - warning("overflow in constant expression\n"); - cond = 1; - } - return cond; - - -} - -static int muld(double x, double y, double min, double max, int needconst) { - int cond = (x >= -1 && x <= 1) || (y >= -1 && y <= 1) - || (x < 0 && y < 0 && -x <= max/-y) - || (x < 0 && y > 0 && x >= min/y) - || (x > 0 && y < 0 && y >= min/x) - || (x > 0 && y > 0 && x <= max/y); - if (!cond && needconst) { - warning("overflow in constant expression\n"); - cond = 1; - } - return cond; - - -} -/* sub[id] - return 1 if min <= x-y <= max, 0 otherwise */ -static int subi(long x, long y, long min, long max, int needconst) { - return addi(x, -y, min, max, needconst); -} - -static int subd(double x, double y, double min, double max, int needconst) { - return addd(x, -y, min, max, needconst); -} -Tree constexpr(int tok) { - Tree p; - - needconst++; - p = expr1(tok); - needconst--; - return p; -} - -int intexpr(int tok, int n) { - Tree p = constexpr(tok); - - needconst++; - if (p->op == CNST+I || p->op == CNST+U) - n = cast(p, inttype)->u.v.i; - else - error("integer expression must be constant\n"); - needconst--; - return n; -} -Tree simplify(int op, Type ty, Tree l, Tree r) { - int n; - - if (optype(op) == 0) - op = mkop(op, ty); - switch (op) { - case ADD+U: - foldcnst(U,u,+); - commute(r,l); - identity(r,l,U,u,0); - break; - case ADD+I: - xfoldcnst(I,i,+,addi); - commute(r,l); - identity(r,l,I,i,0); - break; - case CVI+I: - xcvtcnst(I,l->u.v.i,ty,i,(long)extend(l->u.v.i,ty)); - break; - case CVU+I: - if (l->op == CNST+U) { - if (!explicitCast && l->u.v.u > ty->u.sym->u.limits.max.i) - warning("overflow in converting constant expression from `%t' to `%t'\n", l->type, ty); - if (needconst || !(l->u.v.u > ty->u.sym->u.limits.max.i)) - return cnsttree(ty, (long)extend(l->u.v.u,ty)); - } - break; - case CVP+U: - xcvtcnst(P,(unsigned long)l->u.v.p,ty,u,(unsigned long)l->u.v.p); - break; - case CVU+P: - xcvtcnst(U,(void*)l->u.v.u,ty,p,(void*)l->u.v.u); - break; - case CVP+P: - xcvtcnst(P,l->u.v.p,ty,p,l->u.v.p); - break; - case CVI+U: - xcvtcnst(I,l->u.v.i,ty,u,((unsigned long)l->u.v.i)&ones(8*ty->size)); - break; - case CVU+U: - xcvtcnst(U,l->u.v.u,ty,u,l->u.v.u&ones(8*ty->size)); - break; - - case CVI+F: - xcvtcnst(I,l->u.v.i,ty,d,(long double)l->u.v.i); - case CVU+F: - xcvtcnst(U,l->u.v.u,ty,d,(long double)l->u.v.u); - break; - case CVF+I: - xcvtcnst(F,l->u.v.d,ty,i,(long)l->u.v.d); - break; - case CVF+F: { - float d; - if (l->op == CNST+F) { - if (l->u.v.d < ty->u.sym->u.limits.min.d) - d = ty->u.sym->u.limits.min.d; - else if (l->u.v.d > ty->u.sym->u.limits.max.d) - d = ty->u.sym->u.limits.max.d; - else - d = l->u.v.d; - } - xcvtcnst(F,l->u.v.d,ty,d,(long double)d); - break; - } - case BAND+U: - foldcnst(U,u,&); - commute(r,l); - identity(r,l,U,u,ones(8*ty->size)); - if (r->op == CNST+U && r->u.v.u == 0) - return tree(RIGHT, ty, root(l), cnsttree(ty, 0UL)); - break; - case BAND+I: - foldcnst(I,i,&); - commute(r,l); - identity(r,l,I,i,ones(8*ty->size)); - if (r->op == CNST+I && r->u.v.u == 0) - return tree(RIGHT, ty, root(l), cnsttree(ty, 0L)); - break; - - case MUL+U: - commute(l,r); - if (l->op == CNST+U && (n = ispow2(l->u.v.u)) != 0) - return simplify(LSH, ty, r, cnsttree(inttype, (long)n)); - foldcnst(U,u,*); - identity(r,l,U,u,1); - break; - case NE+I: - cfoldcnst(I,i,!=); - commute(r,l); - zerofield(NE,I,i); - break; - - case EQ+I: - cfoldcnst(I,i,==); - commute(r,l); - zerofield(EQ,I,i); - break; - case ADD+P: - foldaddp(l,r,I,i); - foldaddp(l,r,U,u); - foldaddp(r,l,I,i); - foldaddp(r,l,U,u); - commute(r,l); - identity(r,retype(l,ty),I,i,0); - identity(r,retype(l,ty),U,u,0); - if (isaddrop(l->op) - && ((r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i - && r->u.v.i >= longtype->u.sym->u.limits.min.i) - || (r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))) - return addrtree(l, cast(r, longtype)->u.v.i, ty); - if (l->op == ADD+P && isaddrop(l->kids[1]->op) - && ((r->op == CNST+I && r->u.v.i <= longtype->u.sym->u.limits.max.i - && r->u.v.i >= longtype->u.sym->u.limits.min.i) - || (r->op == CNST+U && r->u.v.u <= longtype->u.sym->u.limits.max.i))) - return simplify(ADD+P, ty, l->kids[0], - addrtree(l->kids[1], cast(r, longtype)->u.v.i, ty)); - if ((l->op == ADD+I || l->op == SUB+I) - && l->kids[1]->op == CNST+I && isaddrop(r->op)) - return simplify(ADD+P, ty, l->kids[0], - simplify(generic(l->op)+P, ty, r, l->kids[1])); - if (l->op == ADD+P && generic(l->kids[1]->op) == CNST - && generic(r->op) == CNST) - return simplify(ADD+P, ty, l->kids[0], - simplify(ADD, l->kids[1]->type, l->kids[1], r)); - if (l->op == ADD+I && generic(l->kids[1]->op) == CNST - && r->op == ADD+P && generic(r->kids[1]->op) == CNST) - return simplify(ADD+P, ty, l->kids[0], - simplify(ADD+P, ty, r->kids[0], - simplify(ADD, r->kids[1]->type, l->kids[1], r->kids[1]))); - if (l->op == RIGHT && l->kids[1]) - return tree(RIGHT, ty, l->kids[0], - simplify(ADD+P, ty, l->kids[1], r)); - else if (l->op == RIGHT && l->kids[0]) - return tree(RIGHT, ty, - simplify(ADD+P, ty, l->kids[0], r), NULL); - break; - - case ADD+F: - xfoldcnst(F,d,+,addd); - commute(r,l); - break; - case AND+I: - op = AND; - ufoldcnst(I,l->u.v.i ? cond(r) : l); /* 0&&r => 0, 1&&r => r */ - break; - case OR+I: - op = OR; - /* 0||r => r, 1||r => 1 */ - ufoldcnst(I,l->u.v.i ? cnsttree(ty, 1L) : cond(r)); - break; - case BCOM+I: - ufoldcnst(I,cnsttree(ty, (long)extend((~l->u.v.i)&ones(8*ty->size), ty))); - idempotent(BCOM+U); - break; - case BCOM+U: - ufoldcnst(U,cnsttree(ty, (unsigned long)((~l->u.v.u)&ones(8*ty->size)))); - idempotent(BCOM+U); - break; - case BOR+U: - foldcnst(U,u,|); - commute(r,l); - identity(r,l,U,u,0); - break; - case BOR+I: - foldcnst(I,i,|); - commute(r,l); - identity(r,l,I,i,0); - break; - case BXOR+U: - foldcnst(U,u,^); - commute(r,l); - identity(r,l,U,u,0); - break; - case BXOR+I: - foldcnst(I,i,^); - commute(r,l); - identity(r,l,I,i,0); - break; - case DIV+F: - xfoldcnst(F,d,/,divd); - break; - case DIV+I: - identity(r,l,I,i,1); - if ((r->op == CNST+I && r->u.v.i == 0) - || (l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i - && r->op == CNST+I && r->u.v.i == -1)) - break; - xfoldcnst(I,i,/,divi); - break; - case DIV+U: - identity(r,l,U,u,1); - if (r->op == CNST+U && r->u.v.u == 0) - break; - if (r->op == CNST+U && (n = ispow2(r->u.v.u)) != 0) - return simplify(RSH, ty, l, cnsttree(inttype, (long)n)); - foldcnst(U,u,/); - break; - case EQ+F: - cfoldcnst(F,d,==); - commute(r,l); - break; - case EQ+U: - cfoldcnst(U,u,==); - commute(r,l); - zerofield(EQ,U,u); - break; - case GE+F: cfoldcnst(F,d,>=); break; - case GE+I: cfoldcnst(I,i,>=); break; - case GE+U: - geu(l,r,1); /* l >= 0 => (l,1) */ - cfoldcnst(U,u,>=); - if (l->op == CNST+U && l->u.v.u == 0) /* 0 >= r => r == 0 */ - return eqtree(EQ, r, l); - break; - case GT+F: cfoldcnst(F,d, >); break; - case GT+I: cfoldcnst(I,i, >); break; - case GT+U: - geu(r,l,0); /* 0 > r => (r,0) */ - cfoldcnst(U,u, >); - if (r->op == CNST+U && r->u.v.u == 0) /* l > 0 => l != 0 */ - return eqtree(NE, l, r); - break; - case LE+F: cfoldcnst(F,d,<=); break; - case LE+I: cfoldcnst(I,i,<=); break; - case LE+U: - geu(r,l,1); /* 0 <= r => (r,1) */ - cfoldcnst(U,u,<=); - if (r->op == CNST+U && r->u.v.u == 0) /* l <= 0 => l == 0 */ - return eqtree(EQ, l, r); - break; - case LSH+I: - identity(r,l,I,i,0); - if (l->op == CNST+I && r->op == CNST+I - && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size - && muli(l->u.v.i, 1<<r->u.v.i, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i, needconst)) - return cnsttree(ty, (long)(l->u.v.i<<r->u.v.i)); - if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) { - warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i); - break; - } - - break; - case LSH+U: - identity(r,l,I,i,0); - sfoldcnst(<<); - if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) { - warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i); - break; - } - - break; - - case LT+F: cfoldcnst(F,d, <); break; - case LT+I: cfoldcnst(I,i, <); break; - case LT+U: - geu(l,r,0); /* l < 0 => (l,0) */ - cfoldcnst(U,u, <); - if (l->op == CNST+U && l->u.v.u == 0) /* 0 < r => r != 0 */ - return eqtree(NE, r, l); - break; - case MOD+I: - if (r->op == CNST+I && r->u.v.i == 1) /* l%1 => (l,0) */ - return tree(RIGHT, ty, root(l), cnsttree(ty, 0L)); - if ((r->op == CNST+I && r->u.v.i == 0) - || (l->op == CNST+I && l->u.v.i == ty->u.sym->u.limits.min.i - && r->op == CNST+I && r->u.v.i == -1)) - break; - xfoldcnst(I,i,%,divi); - break; - case MOD+U: - if (r->op == CNST+U && ispow2(r->u.v.u)) /* l%2^n => l&(2^n-1) */ - return bittree(BAND, l, cnsttree(ty, r->u.v.u - 1)); - if (r->op == CNST+U && r->u.v.u == 0) - break; - foldcnst(U,u,%); - break; - case MUL+F: - xfoldcnst(F,d,*,muld); - commute(l,r); - break; - case MUL+I: - commute(l,r); - xfoldcnst(I,i,*,muli); - if (l->op == CNST+I && r->op == ADD+I && r->kids[1]->op == CNST+I) - /* c1*(x + c2) => c1*x + c1*c2 */ - return simplify(ADD, ty, simplify(MUL, ty, l, r->kids[0]), - simplify(MUL, ty, l, r->kids[1])); - if (l->op == CNST+I && r->op == SUB+I && r->kids[1]->op == CNST+I) - /* c1*(x - c2) => c1*x - c1*c2 */ - return simplify(SUB, ty, simplify(MUL, ty, l, r->kids[0]), - simplify(MUL, ty, l, r->kids[1])); - if (l->op == CNST+I && l->u.v.i > 0 && (n = ispow2(l->u.v.i)) != 0) - /* 2^n * r => r<<n */ - return simplify(LSH, ty, r, cnsttree(inttype, (long)n)); - identity(r,l,I,i,1); - break; - case NE+F: - cfoldcnst(F,d,!=); - commute(r,l); - break; - case NE+U: - cfoldcnst(U,u,!=); - commute(r,l); - zerofield(NE,U,u); - break; - case NEG+F: - ufoldcnst(F,cnsttree(ty, -l->u.v.d)); - idempotent(NEG+F); - break; - case NEG+I: - if (l->op == CNST+I) { - if (needconst && l->u.v.i == ty->u.sym->u.limits.min.i) - warning("overflow in constant expression\n"); - if (needconst || l->u.v.i != ty->u.sym->u.limits.min.i) - return cnsttree(ty, -l->u.v.i); - } - idempotent(NEG+I); - break; - case NOT+I: - op = NOT; - ufoldcnst(I,cnsttree(ty, !l->u.v.i)); - break; - case RSH+I: - identity(r,l,I,i,0); - if (l->op == CNST+I && r->op == CNST+I - && r->u.v.i >= 0 && r->u.v.i < 8*l->type->size) { - long n = l->u.v.i>>r->u.v.i; - if (l->u.v.i < 0) - n |= ~0UL<<(8*l->type->size - r->u.v.i); - return cnsttree(ty, n); - } - if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) { - warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i); - break; - } - - break; - case RSH+U: - identity(r,l,I,i,0); - sfoldcnst(>>); - if (r->op == CNST+I && (r->u.v.i >= 8*ty->size || r->u.v.i < 0)) { - warning("shifting an `%t' by %d bits is undefined\n", ty, r->u.v.i); - break; - } - - break; - case SUB+F: - xfoldcnst(F,d,-,subd); - break; - case SUB+I: - xfoldcnst(I,i,-,subi); - identity(r,l,I,i,0); - break; - case SUB+U: - foldcnst(U,u,-); - identity(r,l,U,u,0); - break; - case SUB+P: - if (l->op == CNST+P && r->op == CNST+P) - return cnsttree(ty, (long)((char *)l->u.v.p - (char *)r->u.v.p)); - if (r->op == CNST+I || r->op == CNST+U) - return simplify(ADD, ty, l, - cnsttree(inttype, r->op == CNST+I ? -r->u.v.i : -(long)r->u.v.u)); - if (isaddrop(l->op) && r->op == ADD+I && r->kids[1]->op == CNST+I) - /* l - (x + c) => l-c - x */ - return simplify(SUB, ty, - simplify(SUB, ty, l, r->kids[1]), r->kids[0]); - break; - default:assert(0); - } - return tree(op, ty, l, r); -} -/* ispow2 - if u > 1 && u == 2^n, return n, otherwise return 0 */ -int ispow2(unsigned long u) { - int n; - - if (u > 1 && (u&(u-1)) == 0) - for (n = 0; u; u >>= 1, n++) - if (u&1) - return n; - return 0; -} - diff --git a/lcc/src/sparc.md b/lcc/src/sparc.md deleted file mode 100644 index f956d46..0000000 --- a/lcc/src/sparc.md +++ /dev/null @@ -1,1163 +0,0 @@ -%{ -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -static int imm(Node); -static void renameregs(void); -extern Interface sparcIR, solarisIR; -static void defsymbol2(Symbol); -static void export2(Symbol); -static void globalend(void); -static void global2(Symbol); -static void segment2(int); -static void progend2(void); - -extern char *stabprefix; -extern void stabblock(int, int, Symbol*); -extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -extern void stabfend(Symbol, int); -extern void stabinit(char *, int, char *[]); -extern void stabline(Coordinate *); -extern void stabsym(Symbol); -extern void stabtype(Symbol); -static Symbol greg[32], gregw; -static Symbol *oreg = &greg[8], *ireg = &greg[24]; -static Symbol freg[32], freg2[32]; -static Symbol fregw, freg2w; - -static int regvars; -static int retstruct; - -static int pflag = 0; - -static int cseg; - -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -reg: ADDRGP4 "set %a,%%%c\n" 1 -stk13: ADDRFP4 "%a" imm(a) -stk13: ADDRLP4 "%a" imm(a) -reg: stk13 "add %0,%%fp,%%%c\n" 1 -stk: ADDRFP4 "set %a,%%%c\n" 2 -stk: ADDRLP4 "set %a,%%%c\n" 2 -reg: ADDRFP4 "set %a,%%%c\nadd %%%c,%%fp,%%%c\n" 3 -reg: ADDRLP4 "set %a,%%%c\nadd %%%c,%%fp,%%%c\n" 3 -con13: CNSTI1 "%a" imm(a) -con13: CNSTI2 "%a" imm(a) -con13: CNSTI4 "%a" imm(a) -con13: CNSTU1 "%a" imm(a) -con13: CNSTU2 "%a" imm(a) -con13: CNSTU4 "%a" imm(a) -con13: CNSTP4 "%a" imm(a) -base: ADDI4(reg,con13) "%%%0+%1" -base: ADDP4(reg,con13) "%%%0+%1" -base: ADDU4(reg,con13) "%%%0+%1" -base: reg "%%%0" -base: con13 "%0" -base: stk13 "%%fp+%0" -addr: base "%0" -addr: ADDI4(reg,reg) "%%%0+%%%1" -addr: ADDP4(reg,reg) "%%%0+%%%1" -addr: ADDU4(reg,reg) "%%%0+%%%1" -addr: stk "%%fp+%%%0" -reg: INDIRI1(addr) "ldsb [%0],%%%c\n" 1 -reg: INDIRI2(addr) "ldsh [%0],%%%c\n" 1 -reg: INDIRI4(addr) "ld [%0],%%%c\n" 1 -reg: INDIRU1(addr) "ldub [%0],%%%c\n" 1 -reg: INDIRU2(addr) "lduh [%0],%%%c\n" 1 -reg: INDIRU4(addr) "ld [%0],%%%c\n" 1 -reg: INDIRP4(addr) "ld [%0],%%%c\n" 1 -reg: INDIRF4(addr) "ld [%0],%%f%c\n" 1 -stmt: ASGNI1(addr,reg) "stb %%%1,[%0]\n" 1 -stmt: ASGNI2(addr,reg) "sth %%%1,[%0]\n" 1 -stmt: ASGNI4(addr,reg) "st %%%1,[%0]\n" 1 -stmt: ASGNU1(addr,reg) "stb %%%1,[%0]\n" 1 -stmt: ASGNU2(addr,reg) "sth %%%1,[%0]\n" 1 -stmt: ASGNU4(addr,reg) "st %%%1,[%0]\n" 1 -stmt: ASGNP4(addr,reg) "st %%%1,[%0]\n" 1 -stmt: ASGNF4(addr,reg) "st %%f%1,[%0]\n" 1 -addrl: ADDRLP4 "%%%fp+%a" imm(a) - -reg: INDIRF8(addrl) "ldd [%0],%%f%c\n" 1 -stmt: ASGNF8(addrl,reg) "std %%f%1,[%0]\n" 1 -reg: INDIRF8(base) "ld2 [%0],%%f%c\n" 2 -stmt: ASGNF8(base,reg) "st2 %%f%1,[%0]\n" 2 -spill: ADDRLP4 "%a" !imm(a) - -stmt: ASGNI1(spill,reg) "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n" -stmt: ASGNI2(spill,reg) "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n" -stmt: ASGNI4(spill,reg) "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n" -stmt: ASGNU1(spill,reg) "set %0,%%g1\nstb %%%1,[%%fp+%%g1]\n" -stmt: ASGNU2(spill,reg) "set %0,%%g1\nsth %%%1,[%%fp+%%g1]\n" -stmt: ASGNU4(spill,reg) "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n" -stmt: ASGNP4(spill,reg) "set %0,%%g1\nst %%%1,[%%fp+%%g1]\n" -stmt: ASGNF4(spill,reg) "set %0,%%g1\nst %%f%1,[%%fp+%%g1]\n" -stmt: ASGNF8(spill,reg) "set %0,%%g1\nstd %%f%1,[%%fp+%%g1]\n" -reg: CVII4(INDIRI1(addr)) "ldsb [%0],%%%c\n" 1 -reg: CVII4(INDIRI2(addr)) "ldsh [%0],%%%c\n" 1 -reg: CVUU4(INDIRU1(addr)) "ldub [%0],%%%c\n" 1 -reg: CVUU4(INDIRU2(addr)) "lduh [%0],%%%c\n" 1 -reg: CVUI4(INDIRU1(addr)) "ldub [%0],%%%c\n" 1 -reg: CVUI4(INDIRU2(addr)) "lduh [%0],%%%c\n" 1 -reg: LOADI1(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADI2(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADI4(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADP4(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADU1(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADU2(reg) "mov %%%0,%%%c\n" move(a) -reg: LOADU4(reg) "mov %%%0,%%%c\n" move(a) -reg: CNSTI1 "# reg\n" range(a, 0, 0) -reg: CNSTI2 "# reg\n" range(a, 0, 0) -reg: CNSTI4 "# reg\n" range(a, 0, 0) -reg: CNSTP4 "# reg\n" range(a, 0, 0) -reg: CNSTU1 "# reg\n" range(a, 0, 0) -reg: CNSTU2 "# reg\n" range(a, 0, 0) -reg: CNSTU4 "# reg\n" range(a, 0, 0) -reg: con "set %0,%%%c\n" 1 -rc: con13 "%0" -rc: reg "%%%0" -reg: ADDI4(reg,rc) "add %%%0,%1,%%%c\n" 1 -reg: ADDP4(reg,rc) "add %%%0,%1,%%%c\n" 1 -reg: ADDU4(reg,rc) "add %%%0,%1,%%%c\n" 1 -reg: BANDI4(reg,rc) "and %%%0,%1,%%%c\n" 1 -reg: BORI4(reg,rc) "or %%%0,%1,%%%c\n" 1 -reg: BXORI4(reg,rc) "xor %%%0,%1,%%%c\n" 1 -reg: BANDU4(reg,rc) "and %%%0,%1,%%%c\n" 1 -reg: BORU4(reg,rc) "or %%%0,%1,%%%c\n" 1 -reg: BXORU4(reg,rc) "xor %%%0,%1,%%%c\n" 1 -reg: SUBI4(reg,rc) "sub %%%0,%1,%%%c\n" 1 -reg: SUBP4(reg,rc) "sub %%%0,%1,%%%c\n" 1 -reg: SUBU4(reg,rc) "sub %%%0,%1,%%%c\n" 1 -rc5: CNSTI4 "%a" range(a, 0, 31) -rc5: reg "%%%0" -reg: LSHI4(reg,rc5) "sll %%%0,%1,%%%c\n" 1 -reg: LSHU4(reg,rc5) "sll %%%0,%1,%%%c\n" 1 -reg: RSHI4(reg,rc5) "sra %%%0,%1,%%%c\n" 1 -reg: RSHU4(reg,rc5) "srl %%%0,%1,%%%c\n" 1 -reg: BANDI4(reg,BCOMI4(rc)) "andn %%%0,%1,%%%c\n" 1 -reg: BORI4(reg,BCOMI4(rc)) "orn %%%0,%1,%%%c\n" 1 -reg: BXORI4(reg,BCOMI4(rc)) "xnor %%%0,%1,%%%c\n" 1 -reg: BANDU4(reg,BCOMU4(rc)) "andn %%%0,%1,%%%c\n" 1 -reg: BORU4(reg,BCOMU4(rc)) "orn %%%0,%1,%%%c\n" 1 -reg: BXORU4(reg,BCOMU4(rc)) "xnor %%%0,%1,%%%c\n" 1 -reg: NEGI4(reg) "neg %%%0,%%%c\n" 1 -reg: BCOMI4(reg) "not %%%0,%%%c\n" 1 -reg: BCOMU4(reg) "not %%%0,%%%c\n" 1 -reg: CVII4(reg) "sll %%%0,8*(4-%a),%%%c; sra %%%c,8*(4-%a),%%%c\n" 2 -reg: CVUU4(reg) "sll %%%0,8*(4-%a),%%%c; srl %%%c,8*(4-%a),%%%c\n" 2 -reg: CVUU4(reg) "and %%%0,0xff,%%%c\n" (a->syms[0]->u.c.v.i == 1 ? 1 : LBURG_MAX) -reg: CVUU4(reg) "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n" 2 -reg: CVUI4(reg) "and %%%0,0xff,%%%c\n" (a->syms[0]->u.c.v.i == 1 ? 1 : LBURG_MAX) -reg: CVUI4(reg) "set 0xffff,%%g1; and %%%0,%%g1,%%%c\n" 2 -addrg: ADDRGP4 "%a" -stmt: JUMPV(addrg) "ba %0; nop\n" 2 -stmt: JUMPV(addr) "jmp %0; nop\n" 2 -stmt: LABELV "%a:\n" -stmt: EQI4(reg,rc) "cmp %%%0,%1; be %a; nop\n" 3 -stmt: EQU4(reg,rc) "cmp %%%0,%1; be %a; nop\n" 3 -stmt: GEI4(reg,rc) "cmp %%%0,%1; bge %a; nop\n" 3 -stmt: GEU4(reg,rc) "cmp %%%0,%1; bgeu %a; nop\n" 3 -stmt: GTI4(reg,rc) "cmp %%%0,%1; bg %a; nop\n" 3 -stmt: GTU4(reg,rc) "cmp %%%0,%1; bgu %a; nop\n" 3 -stmt: LEI4(reg,rc) "cmp %%%0,%1; ble %a; nop\n" 3 -stmt: LEU4(reg,rc) "cmp %%%0,%1; bleu %a; nop\n" 3 -stmt: LTI4(reg,rc) "cmp %%%0,%1; bl %a; nop\n" 3 -stmt: LTU4(reg,rc) "cmp %%%0,%1; blu %a; nop\n" 3 -stmt: NEI4(reg,rc) "cmp %%%0,%1; bne %a; nop\n" 3 -stmt: NEU4(reg,rc) "cmp %%%0,%1; bne %a; nop\n" 3 -call: ADDRGP4 "%a" -call: addr "%0" -reg: CALLF8(call) "call %0; nop\n" 2 -reg: CALLF4(call) "call %0; nop\n" 2 -reg: CALLI4(call) "call %0; nop\n" 2 -reg: CALLP4(call) "call %0; nop\n" 2 -reg: CALLU4(call) "call %0; nop\n" 2 -stmt: CALLV(call) "call %0; nop\n" 2 -stmt: CALLB(call,reg) "call %0; st %%%1,[%%sp+64]; unimp %b&0xfff\n" 3 - -stmt: RETF8(reg) "# ret\n" 1 -stmt: RETF4(reg) "# ret\n" 1 -stmt: RETI4(reg) "# ret\n" 1 -stmt: RETU4(reg) "# ret\n" 1 -stmt: RETP4(reg) "# ret\n" 1 -stmt: ARGI4(reg) "st %%%0,[%%sp+4*%c+68]\n" 1 -stmt: ARGU4(reg) "st %%%0,[%%sp+4*%c+68]\n" 1 -stmt: ARGP4(reg) "st %%%0,[%%sp+4*%c+68]\n" 1 -stmt: ARGF4(reg) "# ARGF4\n" 1 -stmt: ARGF8(reg) "# ARGF8\n" 1 - -reg: DIVI4(reg,rc) "sra %%%0,31,%%g1; wr %%g0,%%g1,%%y; nop; nop; nop; sdiv %%%0,%1,%%%c\n" 6 - -reg: DIVU4(reg,rc) "wr %%g0,%%g0,%%y; nop; nop; nop; udiv %%%0,%1,%%%c\n" 5 - -reg: MODI4(reg,rc) "sra %%%0,31,%%g1; wr %%g0,%%g1,%%y; nop; nop; nop; sdiv %%%0,%1,%%g1\n; smul %%g1,%1,%%g1; sub %%%0,%%g1,%%%c\n" 8 - - -reg: MODU4(reg,rc) "wr %%g0,%%g0,%%y; nop; nop; nop; udiv %%%0,%1,%%g1\n; umul %%g1,%1,%%g1; sub %%%0,%%g1,%%%c\n" 7 - - -reg: MULI4(rc,reg) "smul %%%1,%0,%%%c\n" 1 -reg: MULU4(rc,reg) "umul %%%1,%0,%%%c\n" 1 -reg: ADDF8(reg,reg) "faddd %%f%0,%%f%1,%%f%c\n" 1 -reg: ADDF4(reg,reg) "fadds %%f%0,%%f%1,%%f%c\n" 1 -reg: DIVF8(reg,reg) "fdivd %%f%0,%%f%1,%%f%c\n" 1 -reg: DIVF4(reg,reg) "fdivs %%f%0,%%f%1,%%f%c\n" 1 -reg: MULF8(reg,reg) "fmuld %%f%0,%%f%1,%%f%c\n" 1 -reg: MULF4(reg,reg) "fmuls %%f%0,%%f%1,%%f%c\n" 1 -reg: SUBF8(reg,reg) "fsubd %%f%0,%%f%1,%%f%c\n" 1 -reg: SUBF4(reg,reg) "fsubs %%f%0,%%f%1,%%f%c\n" 1 -reg: NEGF4(reg) "fnegs %%f%0,%%f%c\n" 1 -reg: LOADF4(reg) "fmovs %%f%0,%%f%c\n" 1 -reg: CVFF4(reg) "fdtos %%f%0,%%f%c\n" 1 -reg: CVFF8(reg) "fstod %%f%0,%%f%c\n" 1 -reg: CVFI4(reg) "fstoi %%f%0,%%f0; st %%f0,[%%sp+64]; ld [%%sp+64],%%%c\n" (a->syms[0]->u.c.v.i==4?3:LBURG_MAX) - -reg: CVFI4(reg) "fdtoi %%f%0,%%f0; st %%f0,[%%sp+64]; ld [%%sp+64],%%%c\n" (a->syms[0]->u.c.v.i==8?3:LBURG_MAX) - -reg: CVIF4(reg) "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitos %%f%c,%%f%c\n" 3 - -reg: CVIF8(reg) "st %%%0,[%%sp+64]; ld [%%sp+64],%%f%c; fitod %%f%c,%%f%c\n" 3 - -rel: EQF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbue" -rel: EQF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbue" -rel: GEF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbuge" -rel: GEF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbuge" -rel: GTF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbug" -rel: GTF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbug" -rel: LEF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbule" -rel: LEF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbule" -rel: LTF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbul" -rel: LTF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbul" -rel: NEF8(reg,reg) "fcmped %%f%0,%%f%1; nop; fbne" -rel: NEF4(reg,reg) "fcmpes %%f%0,%%f%1; nop; fbne" - -stmt: rel "%0 %a; nop\n" 4 -reg: LOADF8(reg) "# LOADD\n" 2 - -reg: NEGF8(reg) "# NEGD\n" 2 - -stmt: ASGNB(reg,INDIRB(reg)) "# ASGNB\n" - -%% -static void progend(void){} -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - for (i = 0; i < argc; i++) - if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0) - pflag = 1; - if (IR == &solarisIR) - stabprefix = ".LL"; - else - stabprefix = "L"; - for (i = 0; i < 8; i++) { - greg[i + 0] = mkreg(stringf("g%d", i), i + 0, 1, IREG); - greg[i + 8] = mkreg(stringf("o%d", i), i + 8, 1, IREG); - greg[i + 16] = mkreg(stringf("l%d", i), i + 16, 1, IREG); - greg[i + 24] = mkreg(stringf("i%d", i), i + 24, 1, IREG); - } - gregw = mkwildcard(greg); - for (i = 0; i < 32; i++) - freg[i] = mkreg("%d", i, 1, FREG); - for (i = 0; i < 31; i += 2) - freg2[i] = mkreg("%d", i, 3, FREG); - fregw = mkwildcard(freg); - freg2w = mkwildcard(freg2); - tmask[IREG] = 0x3fff3e00; - vmask[IREG] = 0x3ff00000; - tmask[FREG] = ~(unsigned)0; - vmask[FREG] = 0; -} -static Symbol rmap(int opk) { - switch (optype(opk)) { - case I: case U: case P: case B: - return gregw; - case F: - return opsize(opk) == 4 ? fregw : freg2w; - default: - return 0; - } -} -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case CNST+I: case CNST+U: case CNST+P: - if (range(p, 0, 0) == 0) { - setreg(p, greg[0]); - p->x.registered = 1; - } - break; - case CALL+B: - assert(p->syms[1] && p->syms[1]->type && isfunc(p->syms[1]->type)); - p->syms[1] = intconst(freturn(p->syms[1]->type)->size); - break; - case CALL+F: setreg(p, opsize(p->op)==4?freg[0]:freg2[0]); break; - case CALL+I: case CALL+P: case CALL+U: - case CALL+V: setreg(p, oreg[0]); break; - case RET+F: rtarget(p, 0, opsize(p->op)==4?freg[0]:freg2[0]); break; - case RET+I: case RET+P: case RET+U: - rtarget(p, 0, ireg[0]); - p->kids[0]->x.registered = 1; - break; - case ARG+I: case ARG+P: case ARG+U: - if (p->syms[RX]->u.c.v.i < 6) { - rtarget(p, 0, oreg[p->syms[RX]->u.c.v.i]); - p->op = LOAD+opkind(p->op); - setreg(p, oreg[p->syms[RX]->u.c.v.i]); - } - break; - } -} -static void clobber(Node p) { - assert(p); - switch (specific(p->op)) { - case CALL+B: case CALL+F: case CALL+I: - spill(~(unsigned)3, FREG, p); - break; - case CALL+V: - spill(oreg[0]->x.regnode->mask, IREG, p); - spill(~(unsigned)3, FREG, p); - break; - case ARG+F: - if (opsize(p->op) == 4 && p->syms[2]->u.c.v.i <= 6) - spill((1<<(p->syms[2]->u.c.v.i + 8)), IREG, p); - else if (opsize(p->op) == 8 && p->syms[2]->u.c.v.i <= 5) - spill((3<<(p->syms[2]->u.c.v.i + 8))&0xff00, IREG, p); - break; - } -} -static int imm(Node p) { - return range(p, -4096, 4091); -} -static void doarg(Node p) { - assert(p && p->syms[0] && p->op != ARG+B); - p->syms[RX] = intconst(mkactual(4, - p->syms[0]->u.c.v.i)/4); -} -static void emit2(Node p) { - switch (p->op) { - case ARG+F+sizeop(4): { - int n = p->syms[RX]->u.c.v.i; - print("st %%f%d,[%%sp+4*%d+68]\n", - getregnum(p->x.kids[0]), n); - if (n <= 5) - print("ld [%%sp+4*%d+68],%%o%d\n", n, n); - break; - } - case ARG+F+sizeop(8): { - int n = p->syms[RX]->u.c.v.i; - int src = getregnum(p->x.kids[0]); - print("st %%f%d,[%%sp+4*%d+68]\n", src, n); - print("st %%f%d,[%%sp+4*%d+68]\n", src+1, n+1); - if (n <= 5) - print("ld [%%sp+4*%d+68],%%o%d\n", n, n); - if (n <= 4) - print("ld [%%sp+4*%d+68],%%o%d\n", n+1, n+1); - break; - } - case LOAD+F+sizeop(8): { - int dst = getregnum(p); - int src = getregnum(p->x.kids[0]); - print("fmovs %%f%d,%%f%d; ", src, dst); - print("fmovs %%f%d,%%f%d\n", src+1, dst+1); - break; - } - case NEG+F+sizeop(8): { - int dst = getregnum(p); - int src = getregnum(p->x.kids[0]); - print("fnegs %%f%d,%%f%d; ", src, dst); - print("fmovs %%f%d,%%f%d\n", src+1, dst+1); - break; - } - case ASGN+B: { - static int tmpregs[] = { 1, 2, 3 }; - dalign = salign = p->syms[1]->u.c.v.i; - blkcopy(getregnum(p->x.kids[0]), 0, - getregnum(p->x.kids[1]), 0, - p->syms[0]->u.c.v.i, tmpregs); - break; - } - } -} -static void local(Symbol p) { - if (retstruct) { - assert(p == retv); - p->x.name = stringd(4*16); - p->x.offset = 4*16; - p->sclass = AUTO; - retstruct = 0; - return; - } - if (isscalar(p->type) && !p->addressed && !isfloat(p->type)) - p->sclass = REGISTER; - if (askregvar(p, rmap(ttob(p->type))) == 0) - mkauto(p); - else if (p->scope > LOCAL) - regvars++; -} -static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int autos = 0, i, leaf, reg, varargs; - - if (IR == &solarisIR) - globalend(); - regvars = 0; - for (i = 0; callee[i]; i++) - ; - varargs = variadic(f->type) - || i > 0 && strcmp(callee[i-1]->name, - "__builtin_va_alist") == 0; - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - for (i = 0; i < 8; i++) - ireg[i]->x.regnode->vbl = NULL; - offset = 68; - maxargoffset = 24; - reg = 0; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i], q = caller[i]; - int size = roundup(q->type->size, 4); - assert(q); - if (isfloat(p->type) || reg >= 6) { - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringd(offset); - p->sclass = q->sclass = AUTO; - autos++; - } - else if (p->addressed || varargs) { - p->x.offset = offset; - p->x.name = stringd(p->x.offset); - p->sclass = AUTO; - q->sclass = REGISTER; - askregvar(q, ireg[reg]); - assert(q->x.regnode); - autos++; - } - else { - p->sclass = q->sclass = REGISTER; - askregvar(p, ireg[reg]); - assert(p->x.regnode); - q->x.name = p->x.name; - } - offset += size; - reg += isstruct(p->type) ? 1 : size/4; - } - assert(caller[i] == 0); - offset = maxoffset = 0; - retstruct = isstruct(freturn(f->type)); - gencode(caller, callee); - maxargoffset = roundup(maxargoffset, 4); - framesize = roundup(maxoffset + maxargoffset + 4*(16+1), 8); - assert(!varargs || autos); - leaf = (!ncalls - && !maxoffset && !autos && !regvars - && !isstruct(freturn(f->type)) - && !(usedmask[IREG]&0x00ffff01) - && !(usedmask[FREG]&~(unsigned)3) - && !pflag && !glevel); - print(".align 4\n%s:\n", f->x.name); - if (leaf) { - for (i = 0; caller[i] && callee[i]; i++) { - Symbol p = caller[i], q = callee[i]; - if (p->sclass == REGISTER && q->sclass == REGISTER) { - assert(q->x.regnode); - assert(q->x.regnode->set == IREG); - assert(q->x.regnode->number >= 24); - assert(q->x.regnode->number <= 31); - p->x.name = greg[q->x.regnode->number - 16]->x.name; - } - } - renameregs(); - } else if (framesize <= 4095) - print("save %%sp,%d,%%sp\n", -framesize); - else - print("set %d,%%g1; save %%sp,%%g1,%%sp\n", -framesize); - if (varargs) - for (; reg < 6; reg++) - print("st %%i%d,[%%fp+%d]\n", reg, 4*reg + 68); - else { - offset = 4*(16 + 1); - reg = 0; - for (i = 0; caller[i]; i++) { - Symbol p = caller[i]; - if (isfloat(p->type) && p->type->size == 8 && reg <= 4) { - print("st %%r%d,[%%fp+%d]\n", - ireg[reg++]->x.regnode->number, offset); - print("st %%r%d,[%%fp+%d]\n", - ireg[reg++]->x.regnode->number, offset + 4); - } else if (isfloat(p->type) && p->type->size == 4 && reg <= 5) - print("st %%r%d,[%%fp+%d]\n", - ireg[reg++]->x.regnode->number, offset); - else - reg++; - offset += roundup(p->type->size, 4); - } - } - if (pflag) { - int lab = genlabel(1); - print("set L%d,%%o0; call mcount; nop\n", lab); - print(".seg \"data\"\n.align 4; L%d:.word 0\n.seg \"text\"\n", lab); - } - emitcode(); - if (isstruct(freturn(f->type))) - print("jmp %%i7+12; restore\n"); - else if (!leaf) - print("ret; restore\n"); - else { - renameregs(); - print("retl; nop\n"); - } - if (IR == &solarisIR) { - print(".type %s,#function\n", f->x.name); - print(".size %s,.-%s\n", f->x.name, f->x.name); - } -} -#define exch(x, y, t) (((t) = x), ((x) = (y)), ((y) = (t))) - -static void renameregs(void) { - int i; - - for (i = 0; i < 8; i++) { - char *ptmp; - int itmp; - if (ireg[i]->x.regnode->vbl) - ireg[i]->x.regnode->vbl->x.name = oreg[i]->x.name; - exch(ireg[i]->x.name, oreg[i]->x.name, ptmp); - exch(ireg[i]->x.regnode->number, - oreg[i]->x.regnode->number, itmp); - } -} -static void defconst(int suffix, int size, Value v) { - if (suffix == F && size == 4) { - float f = v.d; - print(".word 0x%x\n", *(unsigned *)&f); - } else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".word 0x%x\n.word 0x%x\n", p[swap], p[!swap]); - } else if (suffix == P) - print(".word 0x%x\n", v.p); - else if (size == 1) - print(".byte 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 2) - print(".half 0x%x\n", suffix == I ? v.i : v.u); - else if (size == 4) - print(".word 0x%x\n", suffix == I ? v.i : v.u); - else assert(0); -} - -static void defaddress(Symbol p) { - print(".word %s\n", p->x.name); -} - -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} - -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", p->x.name, n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} -static void export(Symbol p) { - print(".global %s\n", p->x.name); -} -static void import(Symbol p) {} -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("%d", genlabel(1)); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; - if (p->scope >= LABELS) - p->x.name = stringf(p->generated ? "L%s" : "_%s", - p->x.name); -} -static void segment(int n) { - cseg = n; - switch (n) { - case CODE: print(".seg \"text\"\n"); break; - case BSS: print(".seg \"bss\"\n"); break; - case DATA: print(".seg \"data\"\n"); break; - case LIT: print(".seg \"text\"\n"); break; - } -} -static void space(int n) { - if (cseg != BSS) - print(".skip %d\n", n); -} -static void global(Symbol p) { - print(".align %d\n", p->type->align); - assert(p->u.seg); - if (p->u.seg == BSS - && (p->sclass == STATIC || Aflag >= 2)) - print(".reserve %s,%d\n", p->x.name, p->type->size); - else if (p->u.seg == BSS) - print(".common %s,%d\n", p->x.name, p->type->size); - else - print("%s:\n", p->x.name); -} -static void blkfetch(int k, int off, int reg, int tmp) { - assert(k == 1 || k == 2 || k == 4); - assert(salign >= k); - if (k == 1) - print("ldub [%%r%d+%d],%%r%d\n", reg, off, tmp); - else if (k == 2) - print("lduh [%%r%d+%d],%%r%d\n", reg, off, tmp); - else - print("ld [%%r%d+%d],%%r%d\n", reg, off, tmp); -} -static void blkstore(int k, int off, int reg, int tmp) { - assert(k == 1 || k == 2 || k == 4); - assert(dalign >= k); - if (k == 1) - print("stb %%r%d,[%%r%d+%d]\n", tmp, reg, off); - else if (k == 2) - print("sth %%r%d,[%%r%d+%d]\n", tmp, reg, off); - else - print("st %%r%d,[%%r%d+%d]\n", tmp, reg, off); -} -static void blkloop(int dreg, int doff, int sreg, int soff, int size, int tmps[]) { - if ((size&~7) < 4096) { - print("add %%r%d,%d,%%r%d\n", sreg, size&~7, sreg); - print("add %%r%d,%d,%%r%d\n", dreg, size&~7, tmps[2]); - } else { - print("set %d,%%r%d\n", size&~7, tmps[2]); - print("add %%r%d,%%r%d,%%r%d\n", sreg, tmps[2], sreg); - print("add %%r%d,%%r%d,%%r%d\n", dreg, tmps[2], tmps[2]); - } - blkcopy(tmps[2], doff, sreg, soff, size&7, tmps); - print("1: dec 8,%%r%d\n", tmps[2]); - blkcopy(tmps[2], doff, sreg, soff - 8, 8, tmps); - print("cmp %%r%d,%%r%d; ", tmps[2], dreg); - print("bgt 1b; "); - print("dec 8,%%r%d\n", sreg); -} -static void defsymbol2(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf(".%d", genlabel(1)); - else - assert(p->scope != CONSTANTS || isint(p->type) || isptr(p->type)), - p->x.name = p->name; - if (p->scope >= LABELS) - p->x.name = stringf(p->generated ? ".L%s" : "%s", - p->x.name); -} - -static Symbol prevg; - -static void globalend(void) { - if (prevg && prevg->type->size > 0) - print(".size %s,%d\n", prevg->x.name, prevg->type->size); - prevg = NULL; -} - -static void export2(Symbol p) { - globalend(); - print(".global %s\n", p->x.name); -} - -static void progend2(void) { - globalend(); -} - -static void global2(Symbol p) { - globalend(); - assert(p->u.seg); - if (!p->generated) { - print(".type %s,#%s\n", p->x.name, - isfunc(p->type) ? "function" : "object"); - if (p->type->size > 0) - print(".size %s,%d\n", p->x.name, p->type->size); - else - prevg = p; - } - if (p->u.seg == BSS && p->sclass == STATIC) - print(".local %s\n.common %s,%d,%d\n", p->x.name, p->x.name, - p->type->size, p->type->align); - else if (p->u.seg == BSS && Aflag >= 2) - print(".align %d\n%s:.skip %d\n", p->type->align, p->x.name, - p->type->size); - else if (p->u.seg == BSS) - print(".common %s,%d,%d\n", p->x.name, p->type->size, p->type->align); - else - print(".align %d\n%s:\n", p->type->align, p->x.name); -} - -static void segment2(int n) { - cseg = n; - switch (n) { - case CODE: print(".section \".text\"\n"); break; - case BSS: print(".section \".bss\"\n"); break; - case DATA: print(".section \".data\"\n"); break; - case LIT: print(".section \".rodata\"\n"); break; - } -} -Interface sparcIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 1, /* wants_callb */ - 0, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - stabblock, 0, 0, stabinit, stabline, stabsym, stabtype, - { - 1, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}; - -Interface solarisIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 8, 1, /* double */ - 8, 8, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 1, 0, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 1, /* wants_callb */ - 0, /* wants_argb */ - 1, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol2, - emit, - export2, - function, - gen, - global2, - import, - local, - progbeg, - progend2, - segment2, - space, - stabblock, 0, 0, stabinit, stabline, stabsym, stabtype, - { - 1, /* max_unaligned_load */ - rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, - - } -}; -static char rcsid[] = "$Id: sparc.md 145 2001-10-17 21:53:10Z timo $"; diff --git a/lcc/src/stab.c b/lcc/src/stab.c deleted file mode 100644 index e53604d..0000000 --- a/lcc/src/stab.c +++ /dev/null @@ -1,326 +0,0 @@ -#include <string.h> -#include <stdlib.h> -#include "c.h" -#include "stab.h" - - -static char *currentfile; /* current file name */ -static int ntypes; - -extern Interface sparcIR; - -char *stabprefix = "L"; - -extern char *stabprefix; -extern void stabblock(int, int, Symbol*); -extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -extern void stabfend(Symbol, int); -extern void stabinit(char *, int, char *[]); -extern void stabline(Coordinate *); -extern void stabsym(Symbol); -extern void stabtype(Symbol); - -static void asgncode(Type, int); -static void dbxout(Type); -static int dbxtype(Type); -static int emittype(Type, int, int); - -/* asgncode - assign type code to ty */ -static void asgncode(Type ty, int lev) { - if (ty->x.marked || ty->x.typeno) - return; - ty->x.marked = 1; - switch (ty->op) { - case VOLATILE: case CONST: case VOLATILE+CONST: - asgncode(ty->type, lev); - ty->x.typeno = ty->type->x.typeno; - break; - case POINTER: case FUNCTION: case ARRAY: - asgncode(ty->type, lev + 1); - /* fall thru */ - case VOID: case INT: case UNSIGNED: case FLOAT: - break; - case STRUCT: case UNION: { - Field p; - for (p = fieldlist(ty); p; p = p->link) - asgncode(p->type, lev + 1); - /* fall thru */ - case ENUM: - if (ty->x.typeno == 0) - ty->x.typeno = ++ntypes; - if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) - dbxout(ty); - break; - } - default: - assert(0); - } -} - -/* dbxout - output .stabs entry for type ty */ -static void dbxout(Type ty) { - ty = unqual(ty); - if (!ty->x.printed) { - int col = 0; - print(".stabs \""), col += 8; - if (ty->u.sym && !(isfunc(ty) || isarray(ty) || isptr(ty))) - print("%s", ty->u.sym->name), col += strlen(ty->u.sym->name); - print(":%c", isstruct(ty) || isenum(ty) ? 'T' : 't'), col += 2; - emittype(ty, 0, col); - print("\",%d,0,0,0\n", N_LSYM); - } -} - -/* dbxtype - emit a stabs entry for type ty, return type code */ -static int dbxtype(Type ty) { - asgncode(ty, 0); - dbxout(ty); - return ty->x.typeno; -} - -/* - * emittype - emit ty's type number, emitting its definition if necessary. - * Returns the output column number after emission; col is the approximate - * output column before emission and is used to emit continuation lines for long - * struct, union, and enum types. Continuations are not emitted for other types, - * even if the definition is long. lev is the depth of calls to emittype. - */ -static int emittype(Type ty, int lev, int col) { - int tc = ty->x.typeno; - - if (isconst(ty) || isvolatile(ty)) { - col = emittype(ty->type, lev, col); - ty->x.typeno = ty->type->x.typeno; - ty->x.printed = 1; - return col; - } - if (tc == 0) { - ty->x.typeno = tc = ++ntypes; -/* fprint(2,"`%t'=%d\n", ty, tc); */ - } - print("%d", tc), col += 3; - if (ty->x.printed) - return col; - ty->x.printed = 1; - switch (ty->op) { - case VOID: /* void is defined as itself */ - print("=%d", tc), col += 1+3; - break; - case INT: - if (ty == chartype) /* plain char is a subrange of itself */ - print("=r%d;%d;%d;", tc, ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i), - col += 2+3+2*2.408*ty->size+2; - else /* other signed ints are subranges of int */ - print("=r1;%D;%D;", ty->u.sym->u.limits.min.i, ty->u.sym->u.limits.max.i), - col += 4+2*2.408*ty->size+2; - break; - case UNSIGNED: - if (ty == chartype) /* plain char is a subrange of itself */ - print("=r%d;0;%u;", tc, ty->u.sym->u.limits.max.i), - col += 2+3+2+2.408*ty->size+1; - else /* other signed ints are subranges of int */ - print("=r1;0;%U;", ty->u.sym->u.limits.max.i), - col += 4+2.408*ty->size+1; - break; - case FLOAT: /* float, double, long double get sizes, not ranges */ - print("=r1;%d;0;", ty->size), col += 4+1+3; - break; - case POINTER: - print("=*"), col += 2; - col = emittype(ty->type, lev + 1, col); - break; - case FUNCTION: - print("=f"), col += 2; - col = emittype(ty->type, lev + 1, col); - break; - case ARRAY: /* array includes subscript as an int range */ - if (ty->size && ty->type->size) - print("=ar1;0;%d;", ty->size/ty->type->size - 1), col += 7+3+1; - else - print("=ar1;0;-1;"), col += 10; - col = emittype(ty->type, lev + 1, col); - break; - case STRUCT: case UNION: { - Field p; - if (!ty->u.sym->defined) { - print("=x%c%s:", ty->op == STRUCT ? 's' : 'u', ty->u.sym->name); - col += 2+1+strlen(ty->u.sym->name)+1; - break; - } - if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { - ty->x.printed = 0; - break; - } - print("=%c%d", ty->op == STRUCT ? 's' : 'u', ty->size), col += 1+1+3; - for (p = fieldlist(ty); p; p = p->link) { - if (p->name) - print("%s:", p->name), col += strlen(p->name)+1; - else - print(":"), col += 1; - col = emittype(p->type, lev + 1, col); - if (p->lsb) - print(",%d,%d;", 8*p->offset + - (IR->little_endian ? fieldright(p) : fieldleft(p)), - fieldsize(p)); - else - print(",%d,%d;", 8*p->offset, 8*p->type->size); - col += 1+3+1+3+1; /* accounts for ,%d,%d; */ - if (col >= 80 && p->link) { - print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); - col = 8; - } - } - print(";"), col += 1; - break; - } - case ENUM: { - Symbol *p; - if (lev > 0 && (*ty->u.sym->name < '0' || *ty->u.sym->name > '9')) { - ty->x.printed = 0; - break; - } - print("=e"), col += 2; - for (p = ty->u.sym->u.idlist; *p; p++) { - print("%s:%d,", (*p)->name, (*p)->u.value), col += strlen((*p)->name)+3; - if (col >= 80 && p[1]) { - print("\\\\\",%d,0,0,0\n.stabs \"", N_LSYM); - col = 8; - } - } - print(";"), col += 1; - break; - } - default: - assert(0); - } - return col; -} - -/* stabblock - output a stab entry for '{' or '}' at level lev */ -void stabblock(int brace, int lev, Symbol *p) { - if (brace == '{') - while (*p) - stabsym(*p++); - { - int lab = genlabel(1); - print(".stabn 0x%x,0,%d,%s%d-%s\n", brace == '{' ? N_LBRAC : N_RBRAC, lev, - stabprefix, lab, cfunc->x.name); - print("%s%d:\n", stabprefix, lab); - } -} - -/* stabinit - initialize stab output */ -void stabinit(char *file, int argc, char *argv[]) { - typedef void (*Closure)(Symbol, void *); - extern char *getcwd(char *, size_t); - - print(".stabs \"lcc4_compiled.\",0x%x,0,0,0\n", N_OPT); - if (file && *file) { - char buf[1024], *cwd = getcwd(buf, sizeof buf); - if (cwd) - print(".stabs \"%s/\",0x%x,0,3,%stext0\n", cwd, N_SO, stabprefix); - print(".stabs \"%s\",0x%x,0,3,%stext0\n", file, N_SO, stabprefix); - (*IR->segment)(CODE); - print("%stext0:\n", stabprefix, N_SO); - currentfile = file; - } - dbxtype(inttype); - dbxtype(chartype); - dbxtype(doubletype); - dbxtype(floattype); - dbxtype(longdouble); - dbxtype(longtype); - dbxtype(longlong); - dbxtype(shorttype); - dbxtype(signedchar); - dbxtype(unsignedchar); - dbxtype(unsignedlong); - dbxtype(unsignedlonglong); - dbxtype(unsignedshort); - dbxtype(unsignedtype); - dbxtype(voidtype); - foreach(types, GLOBAL, (Closure)stabtype, NULL); -} - -/* stabline - emit stab entry for source coordinate *cp */ -void stabline(Coordinate *cp) { - if (cp->file && cp->file != currentfile) { - int lab = genlabel(1); - print(".stabs \"%s\",0x%x,0,0,%s%d\n", cp->file, N_SOL, stabprefix, lab); - print("%s%d:\n", stabprefix, lab); - currentfile = cp->file; - } - { - int lab = genlabel(1); - print(".stabn 0x%x,0,%d,%s%d-%s\n", N_SLINE, cp->y, - stabprefix, lab, cfunc->x.name); - print("%s%d:\n", stabprefix, lab); - } -} - -/* stabsym - output a stab entry for symbol p */ -void stabsym(Symbol p) { - int code, tc, sz = p->type->size; - - if (p->generated || p->computed) - return; - if (isfunc(p->type)) { - print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, - p->sclass == STATIC ? 'f' : 'F', dbxtype(freturn(p->type)), - N_FUN, p->x.name); - return; - } - if (!IR->wants_argb && p->scope == PARAM && p->structarg) { - assert(isptr(p->type) && isstruct(p->type->type)); - tc = dbxtype(p->type->type); - sz = p->type->type->size; - } else - tc = dbxtype(p->type); - if ((p->sclass == AUTO && p->scope == GLOBAL) || p->sclass == EXTERN) { - print(".stabs \"%s:G", p->name); - code = N_GSYM; - } else if (p->sclass == STATIC) { - print(".stabs \"%s:%c%d\",%d,0,0,%s\n", p->name, p->scope == GLOBAL ? 'S' : 'V', - tc, p->u.seg == BSS ? N_LCSYM : N_STSYM, p->x.name); - return; - } else if (p->sclass == REGISTER) { - if (p->x.regnode) { - int r = p->x.regnode->number; - if (p->x.regnode->set == FREG) - r += 32; /* floating point */ - print(".stabs \"%s:%c%d\",%d,0,", p->name, - p->scope == PARAM ? 'P' : 'r', tc, N_RSYM); - print("%d,%d\n", sz, r); - } - return; - } else if (p->scope == PARAM) { - print(".stabs \"%s:p", p->name); - code = N_PSYM; - } else if (p->scope >= LOCAL) { - print(".stabs \"%s:", p->name); - code = N_LSYM; - } else - assert(0); - print("%d\",%d,0,0,%s\n", tc, code, - p->scope >= PARAM && p->sclass != EXTERN ? p->x.name : "0"); -} - -/* stabtype - output a stab entry for type *p */ -void stabtype(Symbol p) { - if (p->type) { - if (p->sclass == 0) - dbxtype(p->type); - else if (p->sclass == TYPEDEF) - print(".stabs \"%s:t%d\",%d,0,0,0\n", p->name, dbxtype(p->type), N_LSYM); - } -} - -/* stabend - finalize a function */ -void stabfend(Symbol p, int lineno) {} - -/* stabend - finalize stab output */ -void stabend(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) { - (*IR->segment)(CODE); - print(".stabs \"\", %d, 0, 0,%setext\n", N_SO, stabprefix); - print("%setext:\n", stabprefix); -} diff --git a/lcc/src/stab.h b/lcc/src/stab.h deleted file mode 100644 index 198b1fe..0000000 --- a/lcc/src/stab.h +++ /dev/null @@ -1,113 +0,0 @@ -/* @(#)stab.h 1.11 92/05/11 SMI */ -/* - * Copyright (c) 1990 by Sun Microsystems, Inc. - */ - -/* - * This file gives definitions supplementing <a.out.h> - * for permanent symbol table entries. - * These must have one of the N_STAB bits on, - * and are subject to relocation according to the masks in <a.out.h>. - */ - -#ifndef _STAB_H -#define _STAB_H - - -#if !defined(_a_out_h) && !defined(_A_OUT_H) -/* this file contains fragments of a.out.h and stab.h relevant to - * support of stabX processing within ELF files - see the - * Format of a symbol table entry - */ -struct nlist { - union { - char *n_name; /* for use when in-core */ - long n_strx; /* index into file string table */ - } n_un; - unsigned char n_type; /* type flag (N_TEXT,..) */ - char n_other; /* unused */ - short n_desc; /* see <stab.h> */ - unsigned long n_value; /* value of symbol (or sdb offset) */ -}; - -/* - * Simple values for n_type. - */ -#define N_UNDF 0x0 /* undefined */ -#define N_ABS 0x2 /* absolute */ -#define N_TEXT 0x4 /* text */ -#define N_DATA 0x6 /* data */ -#define N_BSS 0x8 /* bss */ -#define N_COMM 0x12 /* common (internal to ld) */ -#define N_FN 0x1f /* file name symbol */ - -#define N_EXT 01 /* external bit, or'ed in */ -#define N_TYPE 0x1e /* mask for all the type bits */ - -#endif - -/* - * for symbolic debugger, sdb(1): - */ -#define N_GSYM 0x20 /* global symbol: name,,0,type,0 */ -#define N_FNAME 0x22 /* procedure name (f77 kludge): name,,0 */ -#define N_FUN 0x24 /* procedure: name,,0,linenumber,address */ -#define N_STSYM 0x26 /* static symbol: name,,0,type,address */ -#define N_LCSYM 0x28 /* .lcomm symbol: name,,0,type,address */ -#define N_MAIN 0x2a /* name of main routine : name,,0,0,0 */ -#define N_ROSYM 0x2c /* ro_data objects */ -#define N_OBJ 0x38 /* object file path or name */ -#define N_OPT 0x3c /* compiler options */ -#define N_RSYM 0x40 /* register sym: name,,0,type,register */ -#define N_SLINE 0x44 /* src line: 0,,0,linenumber,address */ -#define N_FLINE 0x4c /* function start.end */ -#define N_SSYM 0x60 /* structure elt: name,,0,type,struct_offset */ -#define N_ENDM 0x62 /* last stab emitted for module */ -#define N_SO 0x64 /* source file name: name,,0,0,address */ -#define N_LSYM 0x80 /* local sym: name,,0,type,offset */ -#define N_BINCL 0x82 /* header file: name,,0,0,0 */ -#define N_SOL 0x84 /* #included file name: name,,0,0,address */ -#define N_PSYM 0xa0 /* parameter: name,,0,type,offset */ -#define N_EINCL 0xa2 /* end of include file */ -#define N_ENTRY 0xa4 /* alternate entry: name,linenumber,address */ -#define N_LBRAC 0xc0 /* left bracket: 0,,0,nesting level,address */ -#define N_EXCL 0xc2 /* excluded include file */ -#define N_RBRAC 0xe0 /* right bracket: 0,,0,nesting level,address */ -#define N_BCOMM 0xe2 /* begin common: name,, */ -#define N_ECOMM 0xe4 /* end common: name,, */ -#define N_ECOML 0xe8 /* end common (local name): ,,address */ -#define N_LENG 0xfe /* second stab entry with length information */ - -/* - * for the berkeley pascal compiler, pc(1): - */ -#define N_PC 0x30 /* global pascal symbol: name,,0,subtype,line */ -#define N_WITH 0xea /* pascal with statement: type,,0,0,offset */ - -/* - * for code browser only - */ -#define N_BROWS 0x48 /* path to associated .cb file */ - -/* - * Optional langauge designations for N_SO - */ -#define N_SO_AS 1 /* Assembler */ -#define N_SO_C 2 /* C */ -#define N_SO_ANSI_C 3 /* ANSI C */ -#define N_SO_CC 4 /* C++ */ -#define N_SO_FORTRAN 5 /* Fortran 77 */ -#define N_SO_PASCAL 6 /* Pascal */ - -/* - * Floating point type values - */ -#define NF_NONE 0 /* Undefined type */ -#define NF_SINGLE 1 /* IEEE 32 bit float */ -#define NF_DOUBLE 2 /* IEEE 64 bit float */ -#define NF_COMPLEX 3 /* Fortran complex */ -#define NF_COMPLEX16 4 /* Fortran double complex */ -#define NF_COMPLEX32 5 /* Fortran complex*16 */ -#define NF_LDOUBLE 6 /* Long double */ - -#endif diff --git a/lcc/src/stmt.c b/lcc/src/stmt.c deleted file mode 100644 index 9c3bdbe..0000000 --- a/lcc/src/stmt.c +++ /dev/null @@ -1,696 +0,0 @@ -#include "c.h" - - -#define SWSIZE 512 - -#define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1)) - -struct code codehead = { Start }; -Code codelist = &codehead; -float density = 0.5; -Table stmtlabs; - -static int foldcond(Tree e1, Tree e2); -static void caselabel(Swtch, long, int); -static void cmp(int, Symbol, long, int); -static Tree conditional(int); -static void dostmt(int, Swtch, int); -static int equal(Symbol, Symbol); -static void forstmt(int, Swtch, int); -static void ifstmt(int, int, Swtch, int); -static Symbol localaddr(Tree); -static void stmtlabel(void); -static void swstmt(int, int, int); -static void whilestmt(int, Swtch, int); -Code code(int kind) { - Code cp; - - if (!reachable(kind)) - warning("unreachable code\n"); - - NEW(cp, FUNC); - cp->kind = kind; - cp->prev = codelist; - cp->next = NULL; - codelist->next = cp; - codelist = cp; - return cp; -} -int reachable(int kind) { - - if (kind > Start) { - Code cp; - for (cp = codelist; cp->kind < Label; ) - cp = cp->prev; - if (cp->kind == Jump || cp->kind == Switch) - return 0; - } - return 1; -} -void addlocal(Symbol p) { - if (!p->defined) { - code(Local)->u.var = p; - p->defined = 1; - p->scope = level; - } -} -void definept(Coordinate *p) { - Code cp = code(Defpoint); - - cp->u.point.src = p ? *p : src; - cp->u.point.point = npoints; - if (ncalled > 0) { - int n = findcount(cp->u.point.src.file, - cp->u.point.src.x, cp->u.point.src.y); - if (n > 0) - refinc = (float)n/ncalled; - } - if (glevel > 2) locus(identifiers, &cp->u.point.src); - if (events.points && reachable(Gen)) - { - Tree e = NULL; - apply(events.points, &cp->u.point.src, &e); - if (e) - listnodes(e, 0, 0); - } -} -void statement(int loop, Swtch swp, int lev) { - float ref = refinc; - - if (Aflag >= 2 && lev == 15) - warning("more than 15 levels of nested statements\n"); - switch (t) { - case IF: ifstmt(genlabel(2), loop, swp, lev + 1); - break; - case WHILE: whilestmt(genlabel(3), swp, lev + 1); break; - case DO: dostmt(genlabel(3), swp, lev + 1); expect(';'); - break; - - case FOR: forstmt(genlabel(4), swp, lev + 1); - break; - case BREAK: walk(NULL, 0, 0); - definept(NULL); - if (swp && swp->lab > loop) - branch(swp->lab + 1); - else if (loop) - branch(loop + 2); - else - error("illegal break statement\n"); - t = gettok(); expect(';'); - break; - - case CONTINUE: walk(NULL, 0, 0); - definept(NULL); - if (loop) - branch(loop + 1); - else - error("illegal continue statement\n"); - t = gettok(); expect(';'); - break; - - case SWITCH: swstmt(loop, genlabel(2), lev + 1); - break; - case CASE: { - int lab = genlabel(1); - if (swp == NULL) - error("illegal case label\n"); - definelab(lab); - while (t == CASE) { - static char stop[] = { IF, ID, 0 }; - Tree p; - t = gettok(); - p = constexpr(0); - if (generic(p->op) == CNST && isint(p->type)) { - if (swp) { - needconst++; - p = cast(p, swp->sym->type); - if (p->type->op == UNSIGNED) - p->u.v.i = extend(p->u.v.u, p->type); - needconst--; - caselabel(swp, p->u.v.i, lab); - } - } else - error("case label must be a constant integer expression\n"); - - test(':', stop); - } - statement(loop, swp, lev); - } break; - case DEFAULT: if (swp == NULL) - error("illegal default label\n"); - else if (swp->deflab) - error("extra default label\n"); - else { - swp->deflab = findlabel(swp->lab); - definelab(swp->deflab->u.l.label); - } - t = gettok(); - expect(':'); - statement(loop, swp, lev); break; - case RETURN: { - Type rty = freturn(cfunc->type); - t = gettok(); - definept(NULL); - if (t != ';') - if (rty == voidtype) { - error("extraneous return value\n"); - expr(0); - retcode(NULL); - } else - retcode(expr(0)); - else { - if (rty != voidtype) - warning("missing return value\n"); - retcode(NULL); - } - branch(cfunc->u.f.label); - } expect(';'); - break; - - case '{': compound(loop, swp, lev + 1); break; - case ';': definept(NULL); t = gettok(); break; - case GOTO: walk(NULL, 0, 0); - definept(NULL); - t = gettok(); - if (t == ID) { - Symbol p = lookup(token, stmtlabs); - if (p == NULL) { - p = install(token, &stmtlabs, 0, FUNC); - p->scope = LABELS; - p->u.l.label = genlabel(1); - p->src = src; - } - use(p, src); - branch(p->u.l.label); - t = gettok(); - } else - error("missing label in goto\n"); expect(';'); - break; - - case ID: if (getchr() == ':') { - stmtlabel(); - statement(loop, swp, lev); - break; - } - default: definept(NULL); - if (kind[t] != ID) { - error("unrecognized statement\n"); - t = gettok(); - } else { - Tree e = expr0(0); - listnodes(e, 0, 0); - if (nodecount == 0 || nodecount > 200) - walk(NULL, 0, 0); - else if (glevel) walk(NULL, 0, 0); - deallocate(STMT); - } expect(';'); - break; - - } - if (kind[t] != IF && kind[t] != ID - && t != '}' && t != EOI) { - static char stop[] = { IF, ID, '}', 0 }; - error("illegal statement termination\n"); - skipto(0, stop); - } - refinc = ref; -} - -static void ifstmt(int lab, int loop, Swtch swp, int lev) { - t = gettok(); - expect('('); - definept(NULL); - walk(conditional(')'), 0, lab); - refinc /= 2.0; - statement(loop, swp, lev); - if (t == ELSE) { - branch(lab + 1); - t = gettok(); - definelab(lab); - statement(loop, swp, lev); - if (findlabel(lab + 1)->ref) - definelab(lab + 1); - } else - definelab(lab); -} -static Tree conditional(int tok) { - Tree p = expr(tok); - - if (Aflag > 1 && isfunc(p->type)) - warning("%s used in a conditional expression\n", - funcname(p)); - return cond(p); -} -static void stmtlabel(void) { - Symbol p = lookup(token, stmtlabs); - - if (p == NULL) { - p = install(token, &stmtlabs, 0, FUNC); - p->scope = LABELS; - p->u.l.label = genlabel(1); - p->src = src; - } - if (p->defined) - error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src); - - p->defined = 1; - definelab(p->u.l.label); - t = gettok(); - expect(':'); -} -static void forstmt(int lab, Swtch swp, int lev) { - int once = 0; - Tree e1 = NULL, e2 = NULL, e3 = NULL; - Coordinate pt2, pt3; - - t = gettok(); - expect('('); - definept(NULL); - if (kind[t] == ID) - e1 = texpr(expr0, ';', FUNC); - else - expect(';'); - walk(e1, 0, 0); - pt2 = src; - refinc *= 10.0; - if (kind[t] == ID) - e2 = texpr(conditional, ';', FUNC); - else - expect(';'); - pt3 = src; - if (kind[t] == ID) - e3 = texpr(expr0, ')', FUNC); - else { - static char stop[] = { IF, ID, '}', 0 }; - test(')', stop); - } - if (e2) { - once = foldcond(e1, e2); - if (!once) - branch(lab + 3); - } - definelab(lab); - statement(lab, swp, lev); - definelab(lab + 1); - definept(&pt3); - if (e3) - walk(e3, 0, 0); - if (e2) { - if (!once) - definelab(lab + 3); - definept(&pt2); - walk(e2, lab, 0); - } else { - definept(&pt2); - branch(lab); - } - if (findlabel(lab + 2)->ref) - definelab(lab + 2); -} -static void swstmt(int loop, int lab, int lev) { - Tree e; - struct swtch sw; - Code head, tail; - - t = gettok(); - expect('('); - definept(NULL); - e = expr(')'); - if (!isint(e->type)) { - error("illegal type `%t' in switch expression\n", - e->type); - e = retype(e, inttype); - } - e = cast(e, promote(e->type)); - if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op) - && e->kids[0]->u.sym->type == e->type - && !isvolatile(e->kids[0]->u.sym->type)) { - sw.sym = e->kids[0]->u.sym; - walk(NULL, 0, 0); - } else { - sw.sym = genident(REGISTER, e->type, level); - addlocal(sw.sym); - walk(asgn(sw.sym, e), 0, 0); - } - head = code(Switch); - sw.lab = lab; - sw.deflab = NULL; - sw.ncases = 0; - sw.size = SWSIZE; - sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC); - sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC); - refinc /= 10.0; - statement(loop, &sw, lev); - if (sw.deflab == NULL) { - sw.deflab = findlabel(lab); - definelab(lab); - if (sw.ncases == 0) - warning("switch statement with no cases\n"); - } - if (findlabel(lab + 1)->ref) - definelab(lab + 1); - tail = codelist; - codelist = head->prev; - codelist->next = head->prev = NULL; - if (sw.ncases > 0) - swgen(&sw); - branch(lab); - head->next->prev = codelist; - codelist->next = head->next; - codelist = tail; -} -static void caselabel(Swtch swp, long val, int lab) { - int k; - - if (swp->ncases >= swp->size) - { - long *vals = swp->values; - Symbol *labs = swp->labels; - swp->size *= 2; - swp->values = newarray(swp->size, sizeof *swp->values, FUNC); - swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC); - for (k = 0; k < swp->ncases; k++) { - swp->values[k] = vals[k]; - swp->labels[k] = labs[k]; - } - } - k = swp->ncases; - for ( ; k > 0 && swp->values[k-1] >= val; k--) { - swp->values[k] = swp->values[k-1]; - swp->labels[k] = swp->labels[k-1]; - } - if (k < swp->ncases && swp->values[k] == val) - error("duplicate case label `%d'\n", val); - swp->values[k] = val; - swp->labels[k] = findlabel(lab); - ++swp->ncases; - if (Aflag >= 2 && swp->ncases == 258) - warning("more than 257 cases in a switch\n"); -} -void swgen(Swtch swp) { - int *buckets, k, n; - long *v = swp->values; - - buckets = newarray(swp->ncases + 1, - sizeof *buckets, FUNC); - for (n = k = 0; k < swp->ncases; k++, n++) { - buckets[n] = k; - while (n > 0 && den(n-1, k) >= density) - n--; - } - buckets[n] = swp->ncases; - swcode(swp, buckets, 0, n - 1); -} -void swcode(Swtch swp, int b[], int lb, int ub) { - int hilab, lolab, l, u, k = (lb + ub)/2; - long *v = swp->values; - - if (k > lb && k < ub) { - lolab = genlabel(1); - hilab = genlabel(1); - } else if (k > lb) { - lolab = genlabel(1); - hilab = swp->deflab->u.l.label; - } else if (k < ub) { - lolab = swp->deflab->u.l.label; - hilab = genlabel(1); - } else - lolab = hilab = swp->deflab->u.l.label; - l = b[k]; - u = b[k+1] - 1; - if (u - l + 1 <= 3) - { - int i; - for (i = l; i <= u; i++) - cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label); - if (k > lb && k < ub) - cmp(GT, swp->sym, v[u], hilab); - else if (k > lb) - cmp(GT, swp->sym, v[u], hilab); - else if (k < ub) - cmp(LT, swp->sym, v[l], lolab); - else - assert(lolab == hilab), - branch(lolab); - walk(NULL, 0, 0); - } - else { - Tree e; - Type ty = signedint(swp->sym->type); - Symbol table = genident(STATIC, - array(voidptype, u - l + 1, 0), GLOBAL); - (*IR->defsymbol)(table); - if (!isunsigned(swp->sym->type) || v[l] != 0) - cmp(LT, swp->sym, v[l], lolab); - cmp(GT, swp->sym, v[u], hilab); - e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l])); - if (e->type->size < unsignedptr->size) - e = cast(e, unsignedlong); - walk(tree(JUMP, voidtype, - rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL), - 0, 0); - code(Switch); - codelist->u.swtch.table = table; - codelist->u.swtch.sym = swp->sym; - codelist->u.swtch.deflab = swp->deflab; - codelist->u.swtch.size = u - l + 1; - codelist->u.swtch.values = &v[l]; - codelist->u.swtch.labels = &swp->labels[l]; - if (v[u] - v[l] + 1 >= 10000) - warning("switch generates a huge table\n"); - } - if (k > lb) { - assert(lolab != swp->deflab->u.l.label); - definelab(lolab); - swcode(swp, b, lb, k - 1); - } - if (k < ub) { - assert(hilab != swp->deflab->u.l.label); - definelab(hilab); - swcode(swp, b, k + 1, ub); - } -} -static void cmp(int op, Symbol p, long n, int lab) { - Type ty = signedint(p->type); - - listnodes(eqtree(op, - cast(idtree(p), ty), - cnsttree(ty, n)), - lab, 0); -} -void retcode(Tree p) { - Type ty; - - if (p == NULL) { - if (events.returns) - apply(events.returns, cfunc, NULL); - return; - } - p = pointer(p); - ty = assign(freturn(cfunc->type), p); - if (ty == NULL) { - error("illegal return type; found `%t' expected `%t'\n", - p->type, freturn(cfunc->type)); - return; - } - p = cast(p, ty); - if (retv) - { - if (iscallb(p)) - p = tree(RIGHT, p->type, - tree(CALL+B, p->type, - p->kids[0]->kids[0], idtree(retv)), - rvalue(idtree(retv))); - else - p = asgntree(ASGN, rvalue(idtree(retv)), p); - walk(p, 0, 0); - if (events.returns) - apply(events.returns, cfunc, rvalue(idtree(retv))); - return; - } - if (events.returns) - { - Symbol t1 = genident(AUTO, p->type, level); - addlocal(t1); - walk(asgn(t1, p), 0, 0); - apply(events.returns, cfunc, idtree(t1)); - p = idtree(t1); - } - if (!isfloat(p->type)) - p = cast(p, promote(p->type)); - if (isptr(p->type)) - { - Symbol q = localaddr(p); - if (q && (q->computed || q->generated)) - warning("pointer to a %s is an illegal return value\n", - q->scope == PARAM ? "parameter" : "local"); - else if (q) - warning("pointer to %s `%s' is an illegal return value\n", - q->scope == PARAM ? "parameter" : "local", q->name); - } - walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0); -} -void definelab(int lab) { - Code cp; - Symbol p = findlabel(lab); - - assert(lab); - walk(NULL, 0, 0); - code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p); - for (cp = codelist->prev; cp->kind <= Label; ) - cp = cp->prev; - while ( cp->kind == Jump - && cp->u.forest->kids[0] - && specific(cp->u.forest->kids[0]->op) == ADDRG+P - && cp->u.forest->kids[0]->syms[0] == p) { - assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab); - p->ref--; - assert(cp->next); - assert(cp->prev); - cp->prev->next = cp->next; - cp->next->prev = cp->prev; - cp = cp->prev; - while (cp->kind <= Label) - cp = cp->prev; - } -} -Node jump(int lab) { - Symbol p = findlabel(lab); - - p->ref++; - return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p), - NULL, NULL); -} -void branch(int lab) { - Code cp; - Symbol p = findlabel(lab); - - assert(lab); - walk(NULL, 0, 0); - code(Label)->u.forest = jump(lab); - for (cp = codelist->prev; cp->kind < Label; ) - cp = cp->prev; - while ( cp->kind == Label - && cp->u.forest->op == LABEL+V - && !equal(cp->u.forest->syms[0], p)) { - equatelab(cp->u.forest->syms[0], p); - assert(cp->next); - assert(cp->prev); - cp->prev->next = cp->next; - cp->next->prev = cp->prev; - cp = cp->prev; - while (cp->kind < Label) - cp = cp->prev; - } - if (cp->kind == Jump || cp->kind == Switch) { - p->ref--; - codelist->prev->next = NULL; - codelist = codelist->prev; - } else { - codelist->kind = Jump; - if (cp->kind == Label - && cp->u.forest->op == LABEL+V - && equal(cp->u.forest->syms[0], p)) - warning("source code specifies an infinite loop"); - } -} -void equatelab(Symbol old, Symbol new) { - assert(old->u.l.equatedto == NULL); - old->u.l.equatedto = new; - new->ref++; -} -static int equal(Symbol lprime, Symbol dst) { - assert(dst && lprime); - for ( ; dst; dst = dst->u.l.equatedto) - if (lprime == dst) - return 1; - return 0; -} -/* dostmt - do statement while ( expression ) */ -static void dostmt(int lab, Swtch swp, int lev) { - refinc *= 10.0; - t = gettok(); - definelab(lab); - statement(lab, swp, lev); - definelab(lab + 1); - expect(WHILE); - expect('('); - definept(NULL); - walk(conditional(')'), lab, 0); - if (findlabel(lab + 2)->ref) - definelab(lab + 2); -} - -/* foldcond - check if initial test in for(e1;e2;e3) S is necessary */ -static int foldcond(Tree e1, Tree e2) { - int op = generic(e2->op); - Symbol v; - - if (e1 == 0 || e2 == 0) - return 0; - if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op) - && generic(e1->kids[1]->op) == CNST) { - v = e1->kids[0]->u.sym; - e1 = e1->kids[1]; - } else - return 0; - if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE) - && generic(e2->kids[0]->op) == INDIR - && e2->kids[0]->kids[0]->u.sym == v - && e2->kids[1]->op == e1->op) { - e1 = simplify(op, e2->type, e1, e2->kids[1]); - if (e1->op == CNST+I) - return e1->u.v.i; - } - return 0; -} - -/* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */ -static Symbol localaddr(Tree p) { - if (p == NULL) - return NULL; - switch (generic(p->op)) { - case INDIR: case CALL: case ARG: - return NULL; - case ADDRL: case ADDRF: - return p->u.sym; - case RIGHT: case ASGN: - if (p->kids[1]) - return localaddr(p->kids[1]); - return localaddr(p->kids[0]); - case COND: { - Symbol q; - assert(p->kids[1] && p->kids[1]->op == RIGHT); - if ((q = localaddr(p->kids[1]->kids[0])) != NULL) - return q; - return localaddr(p->kids[1]->kids[1]); - } - default: { - Symbol q; - if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL) - return q; - return localaddr(p->kids[1]); - } - } -} - -/* whilestmt - while ( expression ) statement */ -static void whilestmt(int lab, Swtch swp, int lev) { - Coordinate pt; - Tree e; - - refinc *= 10.0; - t = gettok(); - expect('('); - walk(NULL, 0, 0); - pt = src; - e = texpr(conditional, ')', FUNC); - branch(lab + 1); - definelab(lab); - statement(lab, swp, lev); - definelab(lab + 1); - definept(&pt); - walk(e, lab, 0); - if (findlabel(lab + 2)->ref) - definelab(lab + 2); -} diff --git a/lcc/src/string.c b/lcc/src/string.c deleted file mode 100644 index 73cfc85..0000000 --- a/lcc/src/string.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "c.h" - - -static struct string { - char *str; - int len; - struct string *link; -} *buckets[1024]; -static int scatter[] = { /* map characters to random values */ - 2078917053, 143302914, 1027100827, 1953210302, 755253631, - 2002600785, 1405390230, 45248011, 1099951567, 433832350, - 2018585307, 438263339, 813528929, 1703199216, 618906479, - 573714703, 766270699, 275680090, 1510320440, 1583583926, - 1723401032, 1965443329, 1098183682, 1636505764, 980071615, - 1011597961, 643279273, 1315461275, 157584038, 1069844923, - 471560540, 89017443, 1213147837, 1498661368, 2042227746, - 1968401469, 1353778505, 1300134328, 2013649480, 306246424, - 1733966678, 1884751139, 744509763, 400011959, 1440466707, - 1363416242, 973726663, 59253759, 1639096332, 336563455, - 1642837685, 1215013716, 154523136, 593537720, 704035832, - 1134594751, 1605135681, 1347315106, 302572379, 1762719719, - 269676381, 774132919, 1851737163, 1482824219, 125310639, - 1746481261, 1303742040, 1479089144, 899131941, 1169907872, - 1785335569, 485614972, 907175364, 382361684, 885626931, - 200158423, 1745777927, 1859353594, 259412182, 1237390611, - 48433401, 1902249868, 304920680, 202956538, 348303940, - 1008956512, 1337551289, 1953439621, 208787970, 1640123668, - 1568675693, 478464352, 266772940, 1272929208, 1961288571, - 392083579, 871926821, 1117546963, 1871172724, 1771058762, - 139971187, 1509024645, 109190086, 1047146551, 1891386329, - 994817018, 1247304975, 1489680608, 706686964, 1506717157, - 579587572, 755120366, 1261483377, 884508252, 958076904, - 1609787317, 1893464764, 148144545, 1415743291, 2102252735, - 1788268214, 836935336, 433233439, 2055041154, 2109864544, - 247038362, 299641085, 834307717, 1364585325, 23330161, - 457882831, 1504556512, 1532354806, 567072918, 404219416, - 1276257488, 1561889936, 1651524391, 618454448, 121093252, - 1010757900, 1198042020, 876213618, 124757630, 2082550272, - 1834290522, 1734544947, 1828531389, 1982435068, 1002804590, - 1783300476, 1623219634, 1839739926, 69050267, 1530777140, - 1802120822, 316088629, 1830418225, 488944891, 1680673954, - 1853748387, 946827723, 1037746818, 1238619545, 1513900641, - 1441966234, 367393385, 928306929, 946006977, 985847834, - 1049400181, 1956764878, 36406206, 1925613800, 2081522508, - 2118956479, 1612420674, 1668583807, 1800004220, 1447372094, - 523904750, 1435821048, 923108080, 216161028, 1504871315, - 306401572, 2018281851, 1820959944, 2136819798, 359743094, - 1354150250, 1843084537, 1306570817, 244413420, 934220434, - 672987810, 1686379655, 1301613820, 1601294739, 484902984, - 139978006, 503211273, 294184214, 176384212, 281341425, - 228223074, 147857043, 1893762099, 1896806882, 1947861263, - 1193650546, 273227984, 1236198663, 2116758626, 489389012, - 593586330, 275676551, 360187215, 267062626, 265012701, - 719930310, 1621212876, 2108097238, 2026501127, 1865626297, - 894834024, 552005290, 1404522304, 48964196, 5816381, - 1889425288, 188942202, 509027654, 36125855, 365326415, - 790369079, 264348929, 513183458, 536647531, 13672163, - 313561074, 1730298077, 286900147, 1549759737, 1699573055, - 776289160, 2143346068, 1975249606, 1136476375, 262925046, - 92778659, 1856406685, 1884137923, 53392249, 1735424165, - 1602280572 -}; -char *string(const char *str) { - const char *s; - - for (s = str; *s; s++) - ; - return stringn(str, s - str); -} -char *stringd(long n) { - char str[25], *s = str + sizeof (str); - unsigned long m; - - if (n == LONG_MIN) - m = (unsigned long)LONG_MAX + 1; - else if (n < 0) - m = -n; - else - m = n; - do - *--s = m%10 + '0'; - while ((m /= 10) != 0); - if (n < 0) - *--s = '-'; - return stringn(s, str + sizeof (str) - s); -} -char *stringn(const char *str, int len) { - int i; - unsigned int h; - const char *end; - struct string *p; - - assert(str); - for (h = 0, i = len, end = str; i > 0; i--) - h = (h<<1) + scatter[*(unsigned char *)end++]; - h &= NELEMS(buckets)-1; - for (p = buckets[h]; p; p = p->link) - if (len == p->len) { - const char *s1 = str; - char *s2 = p->str; - do { - if (s1 == end) - return p->str; - } while (*s1++ == *s2++); - } - { - static char *next, *strlimit; - if (len + 1 >= strlimit - next) { - int n = len + 4*1024; - next = allocate(n, PERM); - strlimit = next + n; - } - NEW(p, PERM); - p->len = len; - for (p->str = next; str < end; ) - *next++ = *str++; - *next++ = 0; - p->link = buckets[h]; - buckets[h] = p; - return p->str; - } -} diff --git a/lcc/src/sym.c b/lcc/src/sym.c deleted file mode 100644 index 2a1cfeb..0000000 --- a/lcc/src/sym.c +++ /dev/null @@ -1,314 +0,0 @@ -#include "c.h" -#include <stdio.h> - - -#define equalp(x) v.x == p->sym.u.c.v.x - -struct table { - int level; - Table previous; - struct entry { - struct symbol sym; - struct entry *link; - } *buckets[256]; - Symbol all; -}; -#define HASHSIZE NELEMS(((Table)0)->buckets) -static struct table - cns = { CONSTANTS }, - ext = { GLOBAL }, - ids = { GLOBAL }, - tys = { GLOBAL }; -Table constants = &cns; -Table externals = &ext; -Table identifiers = &ids; -Table globals = &ids; -Table types = &tys; -Table labels; -int level = GLOBAL; -static int tempid; -List loci, symbols; - -Table table(Table tp, int level) { - Table new; - - NEW0(new, FUNC); - new->previous = tp; - new->level = level; - if (tp) - new->all = tp->all; - return new; -} -void foreach(Table tp, int lev, void (*apply)(Symbol, void *), void *cl) { - assert(tp); - while (tp && tp->level > lev) - tp = tp->previous; - if (tp && tp->level == lev) { - Symbol p; - Coordinate sav; - sav = src; - for (p = tp->all; p && p->scope == lev; p = p->up) { - src = p->src; - (*apply)(p, cl); - } - src = sav; - } -} -void enterscope(void) { - if (++level == LOCAL) - tempid = 0; -} -void exitscope(void) { - rmtypes(level); - if (types->level == level) - types = types->previous; - if (identifiers->level == level) { - if (Aflag >= 2) { - int n = 0; - Symbol p; - for (p = identifiers->all; p && p->scope == level; p = p->up) - if (++n > 127) { - warning("more than 127 identifiers declared in a block\n"); - break; - } - } - identifiers = identifiers->previous; - } - assert(level >= GLOBAL); - --level; -} -Symbol install(const char *name, Table *tpp, int level, int arena) { - Table tp = *tpp; - struct entry *p; - unsigned h = (unsigned long)name&(HASHSIZE-1); - - assert(level == 0 || level >= tp->level); - if (level > 0 && tp->level < level) - tp = *tpp = table(tp, level); - NEW0(p, arena); - p->sym.name = (char *)name; - p->sym.scope = level; - p->sym.up = tp->all; - tp->all = &p->sym; - p->link = tp->buckets[h]; - tp->buckets[h] = p; - return &p->sym; -} -Symbol relocate(const char *name, Table src, Table dst) { - struct entry *p, **q; - Symbol *r; - unsigned h = (unsigned long)name&(HASHSIZE-1); - - for (q = &src->buckets[h]; *q; q = &(*q)->link) - if (name == (*q)->sym.name) - break; - assert(*q); - /* - Remove the entry from src's hash chain - and from its list of all symbols. - */ - p = *q; - *q = (*q)->link; - for (r = &src->all; *r && *r != &p->sym; r = &(*r)->up) - ; - assert(*r == &p->sym); - *r = p->sym.up; - /* - Insert the entry into dst's hash chain - and into its list of all symbols. - Return the symbol-table entry. - */ - p->link = dst->buckets[h]; - dst->buckets[h] = p; - p->sym.up = dst->all; - dst->all = &p->sym; - return &p->sym; -} -Symbol lookup(const char *name, Table tp) { - struct entry *p; - unsigned h = (unsigned long)name&(HASHSIZE-1); - - assert(tp); - do - for (p = tp->buckets[h]; p; p = p->link) - if (name == p->sym.name) - return &p->sym; - while ((tp = tp->previous) != NULL); - return NULL; -} -int genlabel(int n) { - static int label = 1; - - label += n; - return label - n; -} -Symbol findlabel(int lab) { - struct entry *p; - unsigned h = lab&(HASHSIZE-1); - - for (p = labels->buckets[h]; p; p = p->link) - if (lab == p->sym.u.l.label) - return &p->sym; - NEW0(p, FUNC); - p->sym.name = stringd(lab); - p->sym.scope = LABELS; - p->sym.up = labels->all; - labels->all = &p->sym; - p->link = labels->buckets[h]; - labels->buckets[h] = p; - p->sym.generated = 1; - p->sym.u.l.label = lab; - (*IR->defsymbol)(&p->sym); - return &p->sym; -} -Symbol constant(Type ty, Value v) { - struct entry *p; - unsigned h = v.u&(HASHSIZE-1); - - ty = unqual(ty); - for (p = constants->buckets[h]; p; p = p->link) - if (eqtype(ty, p->sym.type, 1)) - switch (ty->op) { - case INT: if (equalp(i)) return &p->sym; break; - case UNSIGNED: if (equalp(u)) return &p->sym; break; - case FLOAT: if (equalp(d)) return &p->sym; break; - case FUNCTION: if (equalp(g)) return &p->sym; break; - case ARRAY: - case POINTER: if (equalp(p)) return &p->sym; break; - default: assert(0); - } - NEW0(p, PERM); - p->sym.name = vtoa(ty, v); - p->sym.scope = CONSTANTS; - p->sym.type = ty; - p->sym.sclass = STATIC; - p->sym.u.c.v = v; - p->link = constants->buckets[h]; - p->sym.up = constants->all; - constants->all = &p->sym; - constants->buckets[h] = p; - if (ty->u.sym && !ty->u.sym->addressed) - (*IR->defsymbol)(&p->sym); - p->sym.defined = 1; - return &p->sym; -} -Symbol intconst(int n) { - Value v; - - v.i = n; - return constant(inttype, v); -} -Symbol genident(int scls, Type ty, int lev) { - Symbol p; - - NEW0(p, lev >= LOCAL ? FUNC : PERM); - p->name = stringd(genlabel(1)); - p->scope = lev; - p->sclass = scls; - p->type = ty; - p->generated = 1; - if (lev == GLOBAL) - (*IR->defsymbol)(p); - return p; -} - -Symbol temporary(int scls, Type ty) { - Symbol p; - - NEW0(p, FUNC); - p->name = stringd(++tempid); - p->scope = level < LOCAL ? LOCAL : level; - p->sclass = scls; - p->type = ty; - p->temporary = 1; - p->generated = 1; - return p; -} -Symbol newtemp(int sclass, int tc, int size) { - Symbol p = temporary(sclass, btot(tc, size)); - - (*IR->local)(p); - p->defined = 1; - return p; -} - -Symbol allsymbols(Table tp) { - return tp->all; -} - -void locus(Table tp, Coordinate *cp) { - loci = append(cp, loci); - symbols = append(allsymbols(tp), symbols); -} - -void use(Symbol p, Coordinate src) { - Coordinate *cp; - - NEW(cp, PERM); - *cp = src; - p->uses = append(cp, p->uses); -} -/* findtype - find type ty in identifiers */ -Symbol findtype(Type ty) { - Table tp = identifiers; - int i; - struct entry *p; - - assert(tp); - do - for (i = 0; i < HASHSIZE; i++) - for (p = tp->buckets[i]; p; p = p->link) - if (p->sym.type == ty && p->sym.sclass == TYPEDEF) - return &p->sym; - while ((tp = tp->previous) != NULL); - return NULL; -} - -/* mkstr - make a string constant */ -Symbol mkstr(char *str) { - Value v; - Symbol p; - - v.p = str; - p = constant(array(chartype, strlen(v.p) + 1, 0), v); - if (p->u.c.loc == NULL) - p->u.c.loc = genident(STATIC, p->type, GLOBAL); - return p; -} - -/* mksymbol - make a symbol for name, install in &globals if sclass==EXTERN */ -Symbol mksymbol(int sclass, const char *name, Type ty) { - Symbol p; - - if (sclass == EXTERN) - p = install(string(name), &globals, GLOBAL, PERM); - else { - NEW0(p, PERM); - p->name = string(name); - p->scope = GLOBAL; - } - p->sclass = sclass; - p->type = ty; - (*IR->defsymbol)(p); - p->defined = 1; - return p; -} - -/* vtoa - return string for the constant v of type ty */ -char *vtoa(Type ty, Value v) { - - ty = unqual(ty); - switch (ty->op) { - case INT: return stringd(v.i); - case UNSIGNED: return stringf((v.u&~0x7FFF) ? "0x%X" : "%U", v.u); - case FLOAT: return stringf("%g", (double)v.d); - case ARRAY: - if (ty->type == chartype || ty->type == signedchar - || ty->type == unsignedchar) - return v.p; - return stringf("%p", v.p); - case POINTER: return stringf("%p", v.p); - case FUNCTION: return stringf("%p", v.g); - } - assert(0); return NULL; -} diff --git a/lcc/src/symbolic.c b/lcc/src/symbolic.c deleted file mode 100644 index affa67a..0000000 --- a/lcc/src/symbolic.c +++ /dev/null @@ -1,494 +0,0 @@ -#include <time.h> -#include <ctype.h> -#include "c.h" - -#define I(f) s_##f - -static Node *tail; -static int off, maxoff, uid = 0, verbose = 0, html = 0; - -static const char *yyBEGIN(const char *tag) { - if (html) - print("<%s>", tag); - return tag; -} - -static void yyEND(const char *tag) { - if (html) - print("</%s>", tag); - if (isupper(*tag)) - print("\n"); -} - -#define BEGIN(tag) do { const char *yytag=yyBEGIN(#tag); -#define END yyEND(yytag); } while (0) -#define ITEM BEGIN(li) -#define START BEGIN(LI) -#define ANCHOR(attr,code) do { const char *yytag="a"; if (html) { printf("<a " #attr "=\""); code; print("\">"); } -#define NEWLINE print(html ? "<br>\n" : "\n") - -static void emitCoord(Coordinate src) { - if (src.file && *src.file) { - ANCHOR(href,print("%s", src.file)); print("%s", src.file); END; - print(":"); - } - print("%d.%d", src.y, src.x); -} - -static void emitString(int len, const char *s) { - for ( ; len-- > 0; s++) - if (*s == '&' && html) - print("&"); - else if (*s == '<' && html) - print("<"); - else if (*s == '>' && html) - print("<"); - else if (*s == '"' || *s == '\\') - print("\\%c", *s); - else if (*s >= ' ' && *s < 0177) - print("%c", *s); - else - print("\\%d%d%d", (*s>>6)&3, (*s>>3)&7, *s&7); -} - -static void emitSymRef(Symbol p) { - (*IR->defsymbol)(p); - ANCHOR(href,print("#%s", p->x.name)); BEGIN(code); print("%s", p->name); END; END; -} - -static void emitSymbol(Symbol p) { - (*IR->defsymbol)(p); - ANCHOR(name,print("%s", p->x.name)); BEGIN(code); print("%s", p->name); END; END; - BEGIN(ul); -#define xx(field,code) ITEM; if (!html) print(" "); print(#field "="); code; END - if (verbose && (src.y || src.x)) - xx(src,emitCoord(p->src)); - xx(type,print("%t", p->type)); - xx(sclass,print("%k", p->sclass)); - switch (p->scope) { - case CONSTANTS: xx(scope,print("CONSTANTS")); break; - case LABELS: xx(scope,print("LABELS")); break; - case GLOBAL: xx(scope,print("GLOBAL")); break; - case PARAM: xx(scope,print("PARAM")); break; - case LOCAL: xx(scope,print("LOCAL")); break; - default: - if (p->scope > LOCAL) - xx(scope,print("LOCAL+%d", p->scope-LOCAL)); - else - xx(scope,print("%d", p->scope)); - } - if (p->scope >= PARAM && p->sclass != STATIC) - xx(offset,print("%d", p->x.offset)); - xx(ref,print("%f", p->ref)); - if (p->temporary && p->u.t.cse) - xx(u.t.cse,print("%p", p->u.t.cse)); - END; -#undef xx -} - -/* address - initialize q for addressing expression p+n */ -static void I(address)(Symbol q, Symbol p, long n) { - q->name = stringf("%s%s%D", p->name, n > 0 ? "+" : "", n); - (*IR->defsymbol)(q); - START; print("address "); emitSymbol(q); END; -} - -/* blockbeg - start a block */ -static void I(blockbeg)(Env *e) { - e->offset = off; - START; print("blockbeg off=%d", off); END; -} - -/* blockend - start a block */ -static void I(blockend)(Env *e) { - if (off > maxoff) - maxoff = off; - START; print("blockend off=%d", off); END; - off = e->offset; -} - -/* defaddress - initialize an address */ -static void I(defaddress)(Symbol p){ - START; print("defaddress "); emitSymRef(p); END; -} - -/* defconst - define a constant */ -static void I(defconst)(int suffix, int size, Value v) { - START; - print("defconst "); - switch (suffix) { - case I: - print("int.%d ", size); - BEGIN(code); - if (size > sizeof (int)) - print("%D", v.i); - else - print("%d", (int)v.i); - END; - break; - case U: - print("unsigned.%d ", size); - BEGIN(code); - if (size > sizeof (unsigned)) - print("%U", v.u); - else - print("%u", (unsigned)v.u); - END; - break; - case P: print("void*.%d ", size); BEGIN(code); print("%p", v.p); END; break; - case F: print("float.%d ", size); BEGIN(code); print("%g", (double)v.d); END; break; - default: assert(0); - } - END; -} - -/* defstring - emit a string constant */ -static void I(defstring)(int len, char *s) { - START; print("defstring "); - BEGIN(code); print("\""); emitString(len, s); print("\""); END; - END; -} - -/* defsymbol - define a symbol: initialize p->x */ -static void I(defsymbol)(Symbol p) { - if (p->x.name == NULL) - p->x.name = stringd(++uid); -} - -/* emit - emit the dags on list p */ -static void I(emit)(Node p){ - ITEM; - if (!html) - print(" "); - for (; p; p = p->x.next) { - if (p->op == LABEL+V) { - assert(p->syms[0]); - ANCHOR(name,print("%s", p->syms[0]->x.name)); - BEGIN(code); print("%s", p->syms[0]->name); END; - END; - print(":"); - } else { - int i; - if (p->x.listed) { - BEGIN(strong); print("%d", p->x.inst); END; print("'"); - print(" %s", opname(p->op)); - } else - print("%d. %s", p->x.inst, opname(p->op)); - if (p->count > 1) - print(" count=%d", p->count); - for (i = 0; i < NELEMS(p->kids) && p->kids[i]; i++) - print(" #%d", p->kids[i]->x.inst); - if (generic(p->op) == CALL && p->syms[0] && p->syms[0]->type) - print(" {%t}", p->syms[0]->type); - else - for (i = 0; i < NELEMS(p->syms) && p->syms[i]; i++) { - print(" "); - if (p->syms[i]->scope == CONSTANTS) - print(p->syms[i]->name); - else - emitSymRef(p->syms[i]); - } - } - NEWLINE; - } - END; -} - -/* export - announce p as exported */ -static void I(export)(Symbol p) { - START; print("export "); emitSymRef(p); END; -} - -/* function - generate code for a function */ -static void I(function)(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { - int i; - - (*IR->defsymbol)(f); - off = 0; - for (i = 0; caller[i] && callee[i]; i++) { - off = roundup(off, caller[i]->type->align); - caller[i]->x.offset = callee[i]->x.offset = off; - off += caller[i]->type->size; - } - if (!html) { - print("function "); - emitSymbol(f); - print(" ncalls=%d\n", ncalls); - for (i = 0; caller[i]; i++) - START; print("caller "); emitSymbol(caller[i]); END; - for (i = 0; callee[i]; i++) - START; print("callee "); emitSymbol(callee[i]); END; - } else { - START; - print("function"); - BEGIN(UL); -#define xx(field,code) ITEM; print(#field "="); code; END - xx(f,emitSymbol(f)); - xx(ncalls,print("%d", ncalls)); - if (caller[0]) { - ITEM; print("caller"); BEGIN(OL); - for (i = 0; caller[i]; i++) - ITEM; emitSymbol(caller[i]); END; - END; END; - ITEM; print("callee"); BEGIN(OL); - for (i = 0; callee[i]; i++) - ITEM; emitSymbol(callee[i]); END; - END; END; - } else { - xx(caller,BEGIN(em); print("empty"); END); - xx(callee,BEGIN(em); print("empty"); END); - } - END; - END; - } - maxoff = off = 0; - gencode(caller, callee); - if (html) - START; print("emitcode"); BEGIN(ul); emitcode(); END; END; - else - emitcode(); - START; print("maxoff=%d", maxoff); END; -#undef xx -} - -/* visit - generate code for *p */ -static int visit(Node p, int n) { - if (p && p->x.inst == 0) { - p->x.inst = ++n; - n = visit(p->kids[0], n); - n = visit(p->kids[1], n); - *tail = p; - tail = &p->x.next; - } - return n; -} - -/* gen0 - generate code for the dags on list p */ -static Node I(gen)(Node p) { - int n; - Node nodelist; - - tail = &nodelist; - for (n = 0; p; p = p->link) { - switch (generic(p->op)) { /* check for valid forest */ - case CALL: - assert(IR->wants_dag || p->count == 0); - break; - case ARG: - case ASGN: case JUMP: case LABEL: case RET: - case EQ: case GE: case GT: case LE: case LT: case NE: - assert(p->count == 0); - break; - case INDIR: - assert(IR->wants_dag && p->count > 0); - break; - default: - assert(0); - } - check(p); - p->x.listed = 1; - n = visit(p, n); - } - *tail = 0; - return nodelist; -} - -/* global - announce a global */ -static void I(global)(Symbol p) { - START; print("global "); emitSymbol(p); END; -} - -/* import - import a symbol */ -static void I(import)(Symbol p) { - START; print("import "); emitSymRef(p); END; -} - -/* local - local variable */ -static void I(local)(Symbol p) { - if (p->temporary) - p->name = stringf("t%s", p->name); - (*IR->defsymbol)(p); - off = roundup(off, p->type->align); - p->x.offset = off; - off += p->type->size; - START; print(p->temporary ? "temporary " : "local "); emitSymbol(p); END; -} - -/* progbeg - beginning of program */ -static void I(progbeg)(int argc, char *argv[]) { - int i; - - for (i = 1; i < argc; i++) - if (strcmp(argv[i], "-v") == 0) - verbose++; - else if (strcmp(argv[i], "-html") == 0) - html++; - if (html) { - print("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n"); - print("<html>"); - BEGIN(head); - if (firstfile && *firstfile) - BEGIN(title); emitString(strlen(firstfile), firstfile); END; - print("<link rev=made href=\"mailto:drh@microsoft.com\">\n"); - END; - print("<body>\n"); - if (firstfile && *firstfile) - BEGIN(h1); emitString(strlen(firstfile), firstfile); END; - BEGIN(P); BEGIN(em); - print("Links lead from uses of identifiers and labels to their definitions."); - END; END; - print("<ul>\n"); - START; - print("progbeg"); - BEGIN(ol); - for (i = 1; i < argc; i++) { - ITEM; - BEGIN(code); print("\""); emitString(strlen(argv[i]), argv[i]); print("\""); END; - END; - } - END; - END; - } -} - -/* progend - end of program */ -static void I(progend)(void) { - START; print("progend"); END; - if (html) { - time_t t; - print("</ul>\n"); - time(&t); - print("<hr><address>%s</address>\n", ctime(&t)); - print("</body></html>\n"); - } -} - -/* segment - switch to segment s */ -static void I(segment)(int s) { - START; print("segment %s", &"text\0bss\0.data\0lit\0.sym\0."[5*s-5]); END; -} - -/* space - initialize n bytes of space */ -static void I(space)(int n) { - START; print("space %d", n); END; -} - -static void I(stabblock)(int brace, int lev, Symbol *p) {} - -/* stabend - finalize stab output */ -static void I(stabend)(Coordinate *cp, Symbol p, Coordinate **cpp, Symbol *sp, Symbol *stab) { - int i; - - if (p) - emitSymRef(p); - print("\n"); - if (cpp && sp) - for (i = 0; cpp[i] && sp[i]; i++) { - print("%w.%d: ", cpp[i], cpp[i]->x); - emitSymRef(sp[i]); - print("\n"); - } -} - -static void I(stabfend)(Symbol p, int lineno) {} -static void I(stabinit)(char *file, int argc, char *argv[]) {} - -/* stabline - emit line number information for source coordinate *cp */ -static void I(stabline)(Coordinate *cp) { - if (cp->file) - print("%s:", cp->file); - print("%d.%d:\n", cp->y, cp->x); -} - -static void I(stabsym)(Symbol p) {} -static void I(stabtype)(Symbol p) {} - -Interface symbolicIR = { - {1, 1, 0}, /* char */ - {2, 2, 0}, /* short */ - {4, 4, 0}, /* int */ - {4, 4, 0}, /* long */ - {4, 4, 0}, /* long long */ - {4, 4, 1}, /* float */ - {8, 8, 1}, /* double */ - {8, 8, 1}, /* long double */ - {4, 4, 0}, /* T* */ - {0, 4, 0}, /* struct */ - 0, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 1, /* wants_dag */ - 0, /* unsigned_char */ - I(address), - I(blockbeg), - I(blockend), - I(defaddress), - I(defconst), - I(defstring), - I(defsymbol), - I(emit), - I(export), - I(function), - I(gen), - I(global), - I(import), - I(local), - I(progbeg), - I(progend), - I(segment), - I(space), - I(stabblock), - I(stabend), - I(stabfend), - I(stabinit), - I(stabline), - I(stabsym), - I(stabtype) -}; - -Interface symbolic64IR = { - {1, 1, 0}, /* char */ - {2, 2, 0}, /* short */ - {4, 4, 0}, /* int */ - {8, 8, 0}, /* long */ - {8, 8, 0}, /* long long */ - {4, 4, 1}, /* float */ - {8, 8, 1}, /* double */ - {8, 8, 1}, /* long double */ - {8, 8, 0}, /* T* */ - {0, 1, 0}, /* struct */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 1, /* left_to_right */ - 1, /* wants_dag */ - 0, /* unsigned_char */ - I(address), - I(blockbeg), - I(blockend), - I(defaddress), - I(defconst), - I(defstring), - I(defsymbol), - I(emit), - I(export), - I(function), - I(gen), - I(global), - I(import), - I(local), - I(progbeg), - I(progend), - I(segment), - I(space), - I(stabblock), - I(stabend), - I(stabfend), - I(stabinit), - I(stabline), - I(stabsym), - I(stabtype) -}; diff --git a/lcc/src/token.h b/lcc/src/token.h deleted file mode 100644 index d309f9b..0000000 --- a/lcc/src/token.h +++ /dev/null @@ -1,133 +0,0 @@ -/* -xx(symbol, value, prec, op, optree, kind, string) -*/ -yy(0, 0, 0, 0, 0, 0, 0) -xx(FLOAT, 1, 0, 0, 0, CHAR, "float") -xx(DOUBLE, 2, 0, 0, 0, CHAR, "double") -xx(CHAR, 3, 0, 0, 0, CHAR, "char") -xx(SHORT, 4, 0, 0, 0, CHAR, "short") -xx(INT, 5, 0, 0, 0, CHAR, "int") -xx(UNSIGNED, 6, 0, 0, 0, CHAR, "unsigned") -xx(POINTER, 7, 0, 0, 0, 0, "pointer") -xx(VOID, 8, 0, 0, 0, CHAR, "void") -xx(STRUCT, 9, 0, 0, 0, CHAR, "struct") -xx(UNION, 10, 0, 0, 0, CHAR, "union") -xx(FUNCTION, 11, 0, 0, 0, 0, "function") -xx(ARRAY, 12, 0, 0, 0, 0, "array") -xx(ENUM, 13, 0, 0, 0, CHAR, "enum") -xx(LONG, 14, 0, 0, 0, CHAR, "long") -xx(CONST, 15, 0, 0, 0, CHAR, "const") -xx(VOLATILE, 16, 0, 0, 0, CHAR, "volatile") -yy(0, 17, 0, 0, 0, 0, 0) -yy(0, 18, 0, 0, 0, 0, 0) -yy(0, 19, 0, 0, 0, 0, 0) -yy(0, 20, 0, 0, 0, 0, 0) -yy(0, 21, 0, 0, 0, 0, 0) -yy(0, 22, 0, 0, 0, 0, 0) -yy(0, 23, 0, 0, 0, 0, 0) -yy(0, 24, 0, 0, 0, 0, 0) -yy(0, 25, 0, 0, 0, 0, 0) -yy(0, 26, 0, 0, 0, 0, 0) -yy(0, 27, 0, 0, 0, 0, 0) -yy(0, 28, 0, 0, 0, 0, "long long") -yy(0, 29, 0, 0, 0, 0, 0) -yy(0, 30, 0, 0, 0, 0, 0) -yy(0, 31, 0, 0, 0, 0, "const volatile") -xx(ID, 32, 0, 0, 0, ID, "identifier") -yy(0, 33, 0, 0, 0, ID, "!") -xx(FCON, 34, 0, 0, 0, ID, "floating constant") -xx(ICON, 35, 0, 0, 0, ID, "integer constant") -xx(SCON, 36, 0, 0, 0, ID, "string constant") -yy(0, 37, 13, MOD, bittree,'%', "%") -yy(0, 38, 8, BAND, bittree,ID, "&") -xx(INCR, 39, 0, ADD, addtree,ID, "++") -yy(0, 40, 0, 0, 0, ID, "(") -yy(0, 41, 0, 0, 0, ')', ")") -yy(0, 42, 13, MUL, multree,ID, "*") -yy(0, 43, 12, ADD, addtree,ID, "+") -yy(0, 44, 1, 0, 0, ',', ",") -yy(0, 45, 12, SUB, subtree,ID, "-") -yy(0, 46, 0, 0, 0, '.', ".") -yy(0, 47, 13, DIV, multree,'/', "/") -xx(DECR, 48, 0, SUB, subtree,ID, "--") -xx(DEREF, 49, 0, 0, 0, DEREF, "->") -xx(ANDAND, 50, 5, AND, andtree,ANDAND, "&&") -xx(OROR, 51, 4, OR, andtree,OROR, "||") -xx(LEQ, 52, 10, LE, cmptree,LEQ, "<=") -xx(EQL, 53, 9, EQ, eqtree, EQL, "==") -xx(NEQ, 54, 9, NE, eqtree, NEQ, "!=") -xx(GEQ, 55, 10, GE, cmptree,GEQ, ">=") -xx(RSHIFT, 56, 11, RSH, shtree, RSHIFT, ">>") -xx(LSHIFT, 57, 11, LSH, shtree, LSHIFT, "<<") -yy(0, 58, 0, 0, 0, ':', ":") -yy(0, 59, 0, 0, 0, IF, ";") -yy(0, 60, 10, LT, cmptree,'<', "<") -yy(0, 61, 2, ASGN, asgntree,'=', "=") -yy(0, 62, 10, GT, cmptree,'>', ">") -yy(0, 63, 0, 0, 0, '?', "?") -xx(ELLIPSIS, 64, 0, 0, 0, ELLIPSIS,"...") -xx(SIZEOF, 65, 0, 0, 0, ID, "sizeof") -yy(0, 66, 0, 0, 0, 0, 0) -xx(AUTO, 67, 0, 0, 0, STATIC, "auto") -xx(BREAK, 68, 0, 0, 0, IF, "break") -xx(CASE, 69, 0, 0, 0, IF, "case") -xx(CONTINUE, 70, 0, 0, 0, IF, "continue") -xx(DEFAULT, 71, 0, 0, 0, IF, "default") -xx(DO, 72, 0, 0, 0, IF, "do") -xx(ELSE, 73, 0, 0, 0, IF, "else") -xx(EXTERN, 74, 0, 0, 0, STATIC, "extern") -xx(FOR, 75, 0, 0, 0, IF, "for") -xx(GOTO, 76, 0, 0, 0, IF, "goto") -xx(IF, 77, 0, 0, 0, IF, "if") -xx(REGISTER, 78, 0, 0, 0, STATIC, "register") -xx(RETURN, 79, 0, 0, 0, IF, "return") -xx(SIGNED, 80, 0, 0, 0, CHAR, "signed") -xx(STATIC, 81, 0, 0, 0, STATIC, "static") -xx(SWITCH, 82, 0, 0, 0, IF, "switch") -xx(TYPEDEF, 83, 0, 0, 0, STATIC, "typedef") -xx(WHILE, 84, 0, 0, 0, IF, "while") -xx(TYPECODE, 85, 0, 0, 0, ID, "__typecode") -xx(FIRSTARG, 86, 0, 0, 0, ID, "__firstarg") -yy(0, 87, 0, 0, 0, 0, 0) -yy(0, 88, 0, 0, 0, 0, 0) -yy(0, 89, 0, 0, 0, 0, 0) -yy(0, 90, 0, 0, 0, 0, 0) -yy(0, 91, 0, 0, 0, '[', "[") -yy(0, 92, 0, 0, 0, 0, 0) -yy(0, 93, 0, 0, 0, ']', "]") -yy(0, 94, 7, BXOR, bittree,'^', "^") -yy(0, 95, 0, 0, 0, 0, 0) -yy(0, 96, 0, 0, 0, 0, 0) -yy(0, 97, 0, 0, 0, 0, 0) -yy(0, 98, 0, 0, 0, 0, 0) -yy(0, 99, 0, 0, 0, 0, 0) -yy(0, 100, 0, 0, 0, 0, 0) -yy(0, 101, 0, 0, 0, 0, 0) -yy(0, 102, 0, 0, 0, 0, 0) -yy(0, 103, 0, 0, 0, 0, 0) -yy(0, 104, 0, 0, 0, 0, 0) -yy(0, 105, 0, 0, 0, 0, 0) -yy(0, 106, 0, 0, 0, 0, 0) -yy(0, 107, 0, 0, 0, 0, 0) -yy(0, 108, 0, 0, 0, 0, 0) -yy(0, 109, 0, 0, 0, 0, 0) -yy(0, 110, 0, 0, 0, 0, 0) -yy(0, 111, 0, 0, 0, 0, 0) -yy(0, 112, 0, 0, 0, 0, 0) -yy(0, 113, 0, 0, 0, 0, 0) -yy(0, 114, 0, 0, 0, 0, 0) -yy(0, 115, 0, 0, 0, 0, 0) -yy(0, 116, 0, 0, 0, 0, 0) -yy(0, 117, 0, 0, 0, 0, 0) -yy(0, 118, 0, 0, 0, 0, 0) -yy(0, 119, 0, 0, 0, 0, 0) -yy(0, 120, 0, 0, 0, 0, 0) -yy(0, 121, 0, 0, 0, 0, 0) -yy(0, 122, 0, 0, 0, 0, 0) -yy(0, 123, 0, 0, 0, IF, "{") -yy(0, 124, 6, BOR, bittree,'|', "|") -yy(0, 125, 0, 0, 0, '}', "}") -yy(0, 126, 0, BCOM, 0, ID, "~") -xx(EOI, 127, 0, 0, 0, EOI, "end of input") -#undef xx -#undef yy diff --git a/lcc/src/trace.c b/lcc/src/trace.c deleted file mode 100644 index 3b9ba78..0000000 --- a/lcc/src/trace.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "c.h" - - -static char *fmt, *fp, *fmtend; /* format string, current & limit pointer */ -static Tree args; /* printf arguments */ -static Symbol frameno; /* local holding frame number */ - -/* appendstr - append str to the evolving format string, expanding it if necessary */ -static void appendstr(char *str) { - do - if (fp == fmtend) { - if (fp) { - char *s = allocate(2*(fmtend - fmt), FUNC); - strncpy(s, fmt, fmtend - fmt); - fp = s + (fmtend - fmt); - fmtend = s + 2*(fmtend - fmt); - fmt = s; - } else { - fp = fmt = allocate(80, FUNC); - fmtend = fmt + 80; - } - } - while ((*fp++ = *str++) != 0); - fp--; -} - -/* tracevalue - append format and argument to print the value of e */ -static void tracevalue(Tree e, int lev) { - Type ty = unqual(e->type); - - switch (ty->op) { - case INT: - if (ty == chartype || ty == signedchar) - appendstr("'\\x%02x'"); - else if (ty == longtype) - appendstr("0x%ld"); - else - appendstr("0x%d"); - break; - case UNSIGNED: - if (ty == chartype || ty == unsignedchar) - appendstr("'\\x%02x'"); - else if (ty == unsignedlong) - appendstr("0x%lx"); - else - appendstr("0x%x"); - break; - case FLOAT: - if (ty == longdouble) - appendstr("%Lg"); - else - appendstr("%g"); - break; - case POINTER: - if (unqual(ty->type) == chartype - || unqual(ty->type) == signedchar - || unqual(ty->type) == unsignedchar) { - static Symbol null; - if (null == NULL) - null = mkstr("(null)"); - tracevalue(cast(e, unsignedtype), lev + 1); - appendstr(" \"%.30s\""); - e = condtree(e, e, pointer(idtree(null->u.c.loc))); - } else { - appendstr("("); appendstr(typestring(ty, "")); appendstr(")0x%x"); - } - break; - case STRUCT: { - Field q; - appendstr("("); appendstr(typestring(ty, "")); appendstr("){"); - for (q = ty->u.sym->u.s.flist; q; q = q->link) { - appendstr(q->name); appendstr("="); - tracevalue(field(addrof(e), q->name), lev + 1); - if (q->link) - appendstr(","); - } - appendstr("}"); - return; - } - case UNION: - appendstr("("); appendstr(typestring(ty, "")); appendstr("){...}"); - return; - case ARRAY: - if (lev && ty->type->size > 0) { - int i; - e = pointer(e); - appendstr("{"); - for (i = 0; i < ty->size/ty->type->size; i++) { - Tree p = (*optree['+'])(ADD, e, consttree(i, inttype)); - if (isptr(p->type) && isarray(p->type->type)) - p = retype(p, p->type->type); - else - p = rvalue(p); - if (i) - appendstr(","); - tracevalue(p, lev + 1); - } - appendstr("}"); - } else - appendstr(typestring(ty, "")); - return; - default: - assert(0); - } - e = cast(e, promote(ty)); - args = tree(mkop(ARG,e->type), e->type, e, args); -} - -/* tracefinis - complete & generate the trace call to print */ -static void tracefinis(Symbol printer) { - Tree *ap; - Symbol p; - - *fp = 0; - p = mkstr(string(fmt)); - for (ap = &args; *ap; ap = &(*ap)->kids[1]) - ; - *ap = tree(ARG+P, charptype, pointer(idtree(p->u.c.loc)), 0); - walk(calltree(pointer(idtree(printer)), freturn(printer->type), args, NULL), 0, 0); - args = 0; - fp = fmtend = 0; -} - -/* tracecall - generate code to trace entry to f */ -static void tracecall(Symbol printer, Symbol f) { - int i; - Symbol counter = genident(STATIC, inttype, GLOBAL); - - defglobal(counter, BSS); - (*IR->space)(counter->type->size); - frameno = genident(AUTO, inttype, level); - addlocal(frameno); - appendstr(f->name); appendstr("#"); - tracevalue(asgn(frameno, incr(INCR, idtree(counter), consttree(1, inttype))), 0); - appendstr("("); - for (i = 0; f->u.f.callee[i]; i++) { - if (i) - appendstr(","); - appendstr(f->u.f.callee[i]->name); appendstr("="); - tracevalue(idtree(f->u.f.callee[i]), 0); - } - if (variadic(f->type)) - appendstr(",..."); - appendstr(") called\n"); - tracefinis(printer); -} - -/* tracereturn - generate code to trace return e */ -static void tracereturn(Symbol printer, Symbol f, Tree e) { - appendstr(f->name); appendstr("#"); - tracevalue(idtree(frameno), 0); - appendstr(" returned"); - if (freturn(f->type) != voidtype && e) { - appendstr(" "); - tracevalue(e, 0); - } - appendstr("\n"); - tracefinis(printer); -} - -/* trace_init - initialize for tracing */ -void trace_init(int argc, char *argv[]) { - int i; - static int inited; - - if (inited) - return; - inited = 1; - type_init(argc, argv); - if (IR) - for (i = 1; i < argc; i++) - if (strncmp(argv[i], "-t", 2) == 0 && strchr(argv[i], '=') == NULL) { - Symbol printer = mksymbol(EXTERN, - argv[i][2] ? &argv[i][2] : "printf", - ftype(inttype, ptr(qual(CONST, chartype)))); - printer->defined = 0; - attach((Apply)tracecall, printer, &events.entry); - attach((Apply)tracereturn, printer, &events.returns); - break; - } -} diff --git a/lcc/src/tree.c b/lcc/src/tree.c deleted file mode 100644 index d2b6a91..0000000 --- a/lcc/src/tree.c +++ /dev/null @@ -1,223 +0,0 @@ -#include "c.h" - - -int where = STMT; -static int warn; -static int nid = 1; /* identifies trees & nodes in debugging output */ -static struct nodeid { - int printed; - Tree node; -} ids[500]; /* if ids[i].node == p, then p's id is i */ - -static void printtree1(Tree, int, int); - -Tree tree(int op, Type type, Tree left, Tree right) { - Tree p; - - NEW0(p, where); - p->op = op; - p->type = type; - p->kids[0] = left; - p->kids[1] = right; - return p; -} - -Tree texpr(Tree (*f)(int), int tok, int a) { - int save = where; - Tree p; - - where = a; - p = (*f)(tok); - where = save; - return p; -} -static Tree root1(Tree p) { - if (p == NULL) - return p; - if (p->type == voidtype) - warn++; - switch (generic(p->op)) { - case COND: { - Tree q = p->kids[1]; - assert(q && q->op == RIGHT); - if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN) - q->kids[0] = root1(q->kids[0]->kids[1]); - else - q->kids[0] = root1(q->kids[0]); - if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN) - q->kids[1] = root1(q->kids[1]->kids[1]); - else - q->kids[1] = root1(q->kids[1]); - p->u.sym = 0; - if (q->kids[0] == 0 && q->kids[1] == 0) - p = root1(p->kids[0]); - } - break; - case AND: case OR: - if ((p->kids[1] = root1(p->kids[1])) == 0) - p = root1(p->kids[0]); - break; - case NOT: - if (warn++ == 0) - warning("expression with no effect elided\n"); - return root1(p->kids[0]); - case RIGHT: - if (p->kids[1] == 0) - return root1(p->kids[0]); - if (p->kids[0] && p->kids[0]->op == CALL+B - && p->kids[1] && p->kids[1]->op == INDIR+B) - /* avoid premature release of the CALL+B temporary */ - return p->kids[0]; - if (p->kids[0] && p->kids[0]->op == RIGHT - && p->kids[1] == p->kids[0]->kids[0]) - /* de-construct e++ construction */ - return p->kids[0]->kids[1]; - p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1])); - return p->kids[0] || p->kids[1] ? p : (Tree)0; - case EQ: case NE: case GT: case GE: case LE: case LT: - case ADD: case SUB: case MUL: case DIV: case MOD: - case LSH: case RSH: case BAND: case BOR: case BXOR: - if (warn++ == 0) - warning("expression with no effect elided\n"); - p = tree(RIGHT, p->type, root1(p->kids[0]), root1(p->kids[1])); - return p->kids[0] || p->kids[1] ? p : (Tree)0; - case INDIR: - if (p->type->size == 0 && unqual(p->type) != voidtype) - warning("reference to `%t' elided\n", p->type); - if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type)) - warning("reference to `volatile %t' elided\n", p->type); - /* fall thru */ - case CVI: case CVF: case CVU: case CVP: - case NEG: case BCOM: case FIELD: - if (warn++ == 0) - warning("expression with no effect elided\n"); - return root1(p->kids[0]); - case ADDRL: case ADDRG: case ADDRF: case CNST: - if (needconst) - return p; - if (warn++ == 0) - warning("expression with no effect elided\n"); - return NULL; - case ARG: case ASGN: case CALL: case JUMP: case LABEL: - break; - default: assert(0); - } - return p; -} - -Tree root(Tree p) { - warn = 0; - return root1(p); -} - -char *opname(int op) { - static char *opnames[] = { - "", - "CNST", - "ARG", - "ASGN", - "INDIR", - "CVC", - "CVD", - "CVF", - "CVI", - "CVP", - "CVS", - "CVU", - "NEG", - "CALL", - "*LOAD*", - "RET", - "ADDRG", - "ADDRF", - "ADDRL", - "ADD", - "SUB", - "LSH", - "MOD", - "RSH", - "BAND", - "BCOM", - "BOR", - "BXOR", - "DIV", - "MUL", - "EQ", - "GE", - "GT", - "LE", - "LT", - "NE", - "JUMP", - "LABEL", - "AND", - "NOT", - "OR", - "COND", - "RIGHT", - "FIELD" - }, *suffixes[] = { - "0", "F", "D", "C", "S", "I", "U", "P", "V", "B", - "10","11","12","13","14","15" - }; - - if (generic(op) >= AND && generic(op) <= FIELD && opsize(op) == 0) - return opnames[opindex(op)]; - return stringf("%s%s%s", - opindex(op) > 0 && opindex(op) < NELEMS(opnames) ? - opnames[opindex(op)] : stringd(opindex(op)), - suffixes[optype(op)], opsize(op) > 0 ? stringd(opsize(op)) : ""); -} - -int nodeid(Tree p) { - int i = 1; - - ids[nid].node = p; - while (ids[i].node != p) - i++; - if (i == nid) - ids[nid++].printed = 0; - return i; -} - -/* printed - return pointer to ids[id].printed */ -int *printed(int id) { - if (id) - return &ids[id].printed; - nid = 1; - return 0; -} - -/* printtree - print tree p on fd */ -void printtree(Tree p, int fd) { - (void)printed(0); - printtree1(p, fd, 1); -} - -/* printtree1 - recursively print tree p */ -static void printtree1(Tree p, int fd, int lev) { - FILE *f = fd == 1 ? stdout : stderr; - int i; - static char blanks[] = " "; - - if (p == 0 || *printed(i = nodeid(p))) - return; - fprint(f, "#%d%S%S", i, blanks, i < 10 ? 2 : i < 100 ? 1 : 0, blanks, lev); - fprint(f, "%s %t", opname(p->op), p->type); - *printed(i) = 1; - for (i = 0; i < NELEMS(p->kids); i++) - if (p->kids[i]) - fprint(f, " #%d", nodeid(p->kids[i])); - if (p->op == FIELD && p->u.field) - fprint(f, " %s %d..%d", p->u.field->name, - fieldsize(p->u.field) + fieldright(p->u.field), fieldright(p->u.field)); - else if (generic(p->op) == CNST) - fprint(f, " %s", vtoa(p->type, p->u.v)); - else if (p->u.sym) - fprint(f, " %s", p->u.sym->name); - if (p->node) - fprint(f, " node=%p", p->node); - fprint(f, "\n"); - for (i = 0; i < NELEMS(p->kids); i++) - printtree1(p->kids[i], fd, lev + 1); -} diff --git a/lcc/src/types.c b/lcc/src/types.c deleted file mode 100644 index 4aa3d18..0000000 --- a/lcc/src/types.c +++ /dev/null @@ -1,748 +0,0 @@ -#include "c.h" -#include <float.h> - - -static Field isfield(const char *, Field); -static Type type(int, Type, int, int, void *); - -static struct entry { - struct type type; - struct entry *link; -} *typetable[128]; -static int maxlevel; - -static Symbol pointersym; - -Type chartype; /* char */ -Type doubletype; /* double */ -Type floattype; /* float */ -Type inttype; /* signed int */ -Type longdouble; /* long double */ -Type longtype; /* long */ -Type longlong; /* long long */ -Type shorttype; /* signed short int */ -Type signedchar; /* signed char */ -Type unsignedchar; /* unsigned char */ -Type unsignedlong; /* unsigned long int */ -Type unsignedlonglong; /* unsigned long long int */ -Type unsignedshort; /* unsigned short int */ -Type unsignedtype; /* unsigned int */ -Type funcptype; /* void (*)() */ -Type charptype; /* char* */ -Type voidptype; /* void* */ -Type voidtype; /* basic types: void */ -Type unsignedptr; /* unsigned type to hold void* */ -Type signedptr; /* signed type to hold void* */ -Type widechar; /* unsigned type that represents wchar_t */ - -static Type xxinit(int op, char *name, Metrics m) { - Symbol p = install(string(name), &types, GLOBAL, PERM); - Type ty = type(op, 0, m.size, m.align, p); - - assert(ty->align == 0 || ty->size%ty->align == 0); - p->type = ty; - p->addressed = m.outofline; - switch (ty->op) { - case INT: - p->u.limits.max.i = ones(8*ty->size)>>1; - p->u.limits.min.i = -p->u.limits.max.i - 1; - break; - case UNSIGNED: - p->u.limits.max.u = ones(8*ty->size); - p->u.limits.min.u = 0; - break; - case FLOAT: - if (ty->size == sizeof (float)) - p->u.limits.max.d = FLT_MAX; - else if (ty->size == sizeof (double)) - p->u.limits.max.d = DBL_MAX; - else - p->u.limits.max.d = LDBL_MAX; - p->u.limits.min.d = -p->u.limits.max.d; - break; - default: assert(0); - } - return ty; -} -static Type type(int op, Type ty, int size, int align, void *sym) { - unsigned h = (op^((unsigned long)ty>>3)) -&(NELEMS(typetable)-1); - struct entry *tn; - - if (op != FUNCTION && (op != ARRAY || size > 0)) - for (tn = typetable[h]; tn; tn = tn->link) - if (tn->type.op == op && tn->type.type == ty - && tn->type.size == size && tn->type.align == align - && tn->type.u.sym == sym) - return &tn->type; - NEW0(tn, PERM); - tn->type.op = op; - tn->type.type = ty; - tn->type.size = size; - tn->type.align = align; - tn->type.u.sym = sym; - tn->link = typetable[h]; - typetable[h] = tn; - return &tn->type; -} -void type_init(int argc, char *argv[]) { - static int inited; - int i; - - if (inited) - return; - inited = 1; - if (!IR) - return; - for (i = 1; i < argc; i++) { - int size, align, outofline; - if (strncmp(argv[i], "-unsigned_char=", 15) == 0) - IR->unsigned_char = argv[i][15] - '0'; -#define xx(name) \ - else if (sscanf(argv[i], "-" #name "=%d,%d,%d", &size, &align, &outofline) == 3) { \ - IR->name.size = size; IR->name.align = align; \ - IR->name.outofline = outofline; } - xx(charmetric) - xx(shortmetric) - xx(intmetric) - xx(longmetric) - xx(longlongmetric) - xx(floatmetric) - xx(doublemetric) - xx(longdoublemetric) - xx(ptrmetric) - xx(structmetric) -#undef xx - } -#define xx(v,name,op,metrics) v=xxinit(op,name,IR->metrics) - xx(chartype, "char", IR->unsigned_char ? UNSIGNED : INT,charmetric); - xx(doubletype, "double", FLOAT, doublemetric); - xx(floattype, "float", FLOAT, floatmetric); - xx(inttype, "int", INT, intmetric); - xx(longdouble, "long double", FLOAT, longdoublemetric); - xx(longtype, "long int", INT, longmetric); - xx(longlong, "long long int", INT, longlongmetric); - xx(shorttype, "short", INT, shortmetric); - xx(signedchar, "signed char", INT, charmetric); - xx(unsignedchar, "unsigned char", UNSIGNED,charmetric); - xx(unsignedlong, "unsigned long", UNSIGNED,longmetric); - xx(unsignedshort, "unsigned short", UNSIGNED,shortmetric); - xx(unsignedtype, "unsigned int", UNSIGNED,intmetric); - xx(unsignedlonglong,"unsigned long long",UNSIGNED,longlongmetric); -#undef xx - { - Symbol p; - p = install(string("void"), &types, GLOBAL, PERM); - voidtype = type(VOID, NULL, 0, 0, p); - p->type = voidtype; - } - pointersym = install(string("T*"), &types, GLOBAL, PERM); - pointersym->addressed = IR->ptrmetric.outofline; - pointersym->u.limits.max.p = (void*)ones(8*IR->ptrmetric.size); - pointersym->u.limits.min.p = 0; - voidptype = ptr(voidtype); - funcptype = ptr(func(voidtype, NULL, 1)); - charptype = ptr(chartype); -#define xx(v,t) if (v==NULL && t->size==voidptype->size && t->align==voidptype->align) v=t - xx(unsignedptr,unsignedshort); - xx(unsignedptr,unsignedtype); - xx(unsignedptr,unsignedlong); - xx(unsignedptr,unsignedlonglong); - if (unsignedptr == NULL) - unsignedptr = type(UNSIGNED, NULL, voidptype->size, voidptype->align, voidptype->u.sym); - xx(signedptr,shorttype); - xx(signedptr,inttype); - xx(signedptr,longtype); - xx(signedptr,longlong); - if (signedptr == NULL) - signedptr = type(INT, NULL, voidptype->size, voidptype->align, voidptype->u.sym); -#undef xx - widechar = unsignedshort; - for (i = 0; i < argc; i++) { -#define xx(name,type) \ - if (strcmp(argv[i], "-wchar_t=" #name) == 0) \ - widechar = type; - xx(unsigned_char,unsignedchar) - xx(unsigned_int,unsignedtype) - xx(unsigned_short,unsignedshort) - } -#undef xx -} -void rmtypes(int lev) { - if (maxlevel >= lev) { - int i; - maxlevel = 0; - for (i = 0; i < NELEMS(typetable); i++) { - struct entry *tn, **tq = &typetable[i]; - while ((tn = *tq) != NULL) - if (tn->type.op == FUNCTION) - tq = &tn->link; - else if (tn->type.u.sym && tn->type.u.sym->scope >= lev) - *tq = tn->link; - else { - if (tn->type.u.sym && tn->type.u.sym->scope > maxlevel) - maxlevel = tn->type.u.sym->scope; - tq = &tn->link; - } - - } - } -} -Type ptr(Type ty) { - return type(POINTER, ty, IR->ptrmetric.size, - IR->ptrmetric.align, pointersym); -} -Type deref(Type ty) { - if (isptr(ty)) - ty = ty->type; - else - error("type error: %s\n", "pointer expected"); - return isenum(ty) ? unqual(ty)->type : ty; -} -Type array(Type ty, int n, int a) { - assert(ty); - if (isfunc(ty)) { - error("illegal type `array of %t'\n", ty); - return array(inttype, n, 0); - } - if (isarray(ty) && ty->size == 0) - error("missing array size\n"); - if (ty->size == 0) { - if (unqual(ty) == voidtype) - error("illegal type `array of %t'\n", ty); - else if (Aflag >= 2) - warning("declaring type array of %t' is undefined\n", ty); - - } else if (n > INT_MAX/ty->size) { - error("size of `array of %t' exceeds %d bytes\n", - ty, INT_MAX); - n = 1; - } - return type(ARRAY, ty, n*ty->size, - a ? a : ty->align, NULL); -} -Type atop(Type ty) { - if (isarray(ty)) - return ptr(ty->type); - error("type error: %s\n", "array expected"); - return ptr(ty); -} -Type qual(int op, Type ty) { - if (isarray(ty)) - ty = type(ARRAY, qual(op, ty->type), ty->size, - ty->align, NULL); - else if (isfunc(ty)) - warning("qualified function type ignored\n"); - else if ((isconst(ty) && op == CONST) - || (isvolatile(ty) && op == VOLATILE)) - error("illegal type `%k %t'\n", op, ty); - else { - if (isqual(ty)) { - op += ty->op; - ty = ty->type; - } - ty = type(op, ty, ty->size, ty->align, NULL); - } - return ty; -} -Type func(Type ty, Type *proto, int style) { - if (ty && (isarray(ty) || isfunc(ty))) - error("illegal return type `%t'\n", ty); - ty = type(FUNCTION, ty, 0, 0, NULL); - ty->u.f.proto = proto; - ty->u.f.oldstyle = style; - return ty; -} -Type freturn(Type ty) { - if (isfunc(ty)) - return ty->type; - error("type error: %s\n", "function expected"); - return inttype; -} -int variadic(Type ty) { - if (isfunc(ty) && ty->u.f.proto) { - int i; - for (i = 0; ty->u.f.proto[i]; i++) - ; - return i > 1 && ty->u.f.proto[i-1] == voidtype; - } - return 0; -} -Type newstruct(int op, char *tag) { - Symbol p; - - assert(tag); - if (*tag == 0) - tag = stringd(genlabel(1)); - else - if ((p = lookup(tag, types)) != NULL && (p->scope == level - || (p->scope == PARAM && level == PARAM+1))) { - if (p->type->op == op && !p->defined) - return p->type; - error("redefinition of `%s' previously defined at %w\n", - p->name, &p->src); - } - p = install(tag, &types, level, PERM); - p->type = type(op, NULL, 0, 0, p); - if (p->scope > maxlevel) - maxlevel = p->scope; - p->src = src; - return p->type; -} -Field newfield(char *name, Type ty, Type fty) { - Field p, *q = &ty->u.sym->u.s.flist; - - if (name == NULL) - name = stringd(genlabel(1)); - for (p = *q; p; q = &p->link, p = *q) - if (p->name == name) - error("duplicate field name `%s' in `%t'\n", - name, ty); - NEW0(p, PERM); - *q = p; - p->name = name; - p->type = fty; - if (xref) { /* omit */ - if (ty->u.sym->u.s.ftab == NULL) /* omit */ - ty->u.sym->u.s.ftab = table(NULL, level); /* omit */ - install(name, &ty->u.sym->u.s.ftab, 0, PERM)->src = src;/* omit */ - } /* omit */ - return p; -} -int eqtype(Type ty1, Type ty2, int ret) { - if (ty1 == ty2) - return 1; - if (ty1->op != ty2->op) - return 0; - switch (ty1->op) { - case ENUM: case UNION: case STRUCT: - case UNSIGNED: case INT: case FLOAT: - return 0; - case POINTER: return eqtype(ty1->type, ty2->type, 1); - case VOLATILE: case CONST+VOLATILE: - case CONST: return eqtype(ty1->type, ty2->type, 1); - case ARRAY: if (eqtype(ty1->type, ty2->type, 1)) { - if (ty1->size == ty2->size) - return 1; - if (ty1->size == 0 || ty2->size == 0) - return ret; - } - return 0; - case FUNCTION: if (eqtype(ty1->type, ty2->type, 1)) { - Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto; - if (p1 == p2) - return 1; - if (p1 && p2) { - for ( ; *p1 && *p2; p1++, p2++) - if (eqtype(unqual(*p1), unqual(*p2), 1) == 0) - return 0; - if (*p1 == NULL && *p2 == NULL) - return 1; - } else { - if (variadic(p1 ? ty1 : ty2)) - return 0; - if (p1 == NULL) - p1 = p2; - for ( ; *p1; p1++) { - Type ty = unqual(*p1); - if (promote(ty) != (isenum(ty) ? ty->type : ty)) - return 0; - } - return 1; - } - } - return 0; - } - assert(0); return 0; -} -Type promote(Type ty) { - ty = unqual(ty); - switch (ty->op) { - case ENUM: - return inttype; - case INT: - if (ty->size < inttype->size) - return inttype; - break; - case UNSIGNED: - if (ty->size < inttype->size) - return inttype; - if (ty->size < unsignedtype->size) - return unsignedtype; - break; - case FLOAT: - if (ty->size < doubletype->size) - return doubletype; - } - return ty; -} -Type signedint(Type ty) { - if (ty->op == INT) - return ty; - assert(ty->op == UNSIGNED); -#define xx(t) if (ty->size == t->size) return t - xx(inttype); - xx(longtype); - xx(longlong); -#undef xx - assert(0); return NULL; -} -Type compose(Type ty1, Type ty2) { - if (ty1 == ty2) - return ty1; - assert(ty1->op == ty2->op); - switch (ty1->op) { - case POINTER: - return ptr(compose(ty1->type, ty2->type)); - case CONST+VOLATILE: - return qual(CONST, qual(VOLATILE, - compose(ty1->type, ty2->type))); - case CONST: case VOLATILE: - return qual(ty1->op, compose(ty1->type, ty2->type)); - case ARRAY: { Type ty = compose(ty1->type, ty2->type); - if (ty1->size && ((ty1->type->size && ty2->size == 0) || ty1->size == ty2->size)) - return array(ty, ty1->size/ty1->type->size, ty1->align); - if (ty2->size && ty2->type->size && ty1->size == 0) - return array(ty, ty2->size/ty2->type->size, ty2->align); - return array(ty, 0, 0); } - case FUNCTION: { Type *p1 = ty1->u.f.proto, *p2 = ty2->u.f.proto; - Type ty = compose(ty1->type, ty2->type); - List tlist = NULL; - if (p1 == NULL && p2 == NULL) - return func(ty, NULL, 1); - if (p1 && p2 == NULL) - return func(ty, p1, ty1->u.f.oldstyle); - if (p2 && p1 == NULL) - return func(ty, p2, ty2->u.f.oldstyle); - for ( ; *p1 && *p2; p1++, p2++) { - Type ty = compose(unqual(*p1), unqual(*p2)); - if (isconst(*p1) || isconst(*p2)) - ty = qual(CONST, ty); - if (isvolatile(*p1) || isvolatile(*p2)) - ty = qual(VOLATILE, ty); - tlist = append(ty, tlist); - } - assert(*p1 == NULL && *p2 == NULL); - return func(ty, ltov(&tlist, PERM), 0); } - } - assert(0); return NULL; -} -int ttob(Type ty) { - switch (ty->op) { - case CONST: case VOLATILE: case CONST+VOLATILE: - return ttob(ty->type); - case VOID: case INT: case UNSIGNED: case FLOAT: - return ty->op + sizeop(ty->size); - case POINTER: - return POINTER + sizeop(voidptype->size); - case FUNCTION: - return POINTER + sizeop(funcptype->size); - case ARRAY: case STRUCT: case UNION: - return STRUCT; - case ENUM: - return INT + sizeop(inttype->size); - } - assert(0); return INT; -} -Type btot(int op, int size) { -#define xx(ty) if (size == (ty)->size) return ty; - switch (optype(op)) { - case F: - xx(floattype); - xx(doubletype); - xx(longdouble); - assert(0); return 0; - case I: - if (chartype->op == INT) - xx(chartype); - xx(signedchar); - xx(shorttype); - xx(inttype); - xx(longtype); - xx(longlong); - assert(0); return 0; - case U: - if (chartype->op == UNSIGNED) - xx(chartype); - xx(unsignedchar); - xx(unsignedshort); - xx(unsignedtype); - xx(unsignedlong); - xx(unsignedlonglong); - assert(0); return 0; - case P: - xx(voidptype); - xx(funcptype); - assert(0); return 0; - } -#undef xx - assert(0); return 0; -} -int hasproto(Type ty) { - if (ty == 0) - return 1; - switch (ty->op) { - case CONST: case VOLATILE: case CONST+VOLATILE: case POINTER: - case ARRAY: - return hasproto(ty->type); - case FUNCTION: - return hasproto(ty->type) && ty->u.f.proto; - case STRUCT: case UNION: - case VOID: case FLOAT: case ENUM: case INT: case UNSIGNED: - return 1; - } - assert(0); return 0; -} -/* fieldlist - construct a flat list of fields in type ty */ -Field fieldlist(Type ty) { - return ty->u.sym->u.s.flist; -} - -/* fieldref - find field name of type ty, return entry */ -Field fieldref(const char *name, Type ty) { - Field p = isfield(name, unqual(ty)->u.sym->u.s.flist); - - if (p && xref) { - Symbol q; - assert(unqual(ty)->u.sym->u.s.ftab); - q = lookup(name, unqual(ty)->u.sym->u.s.ftab); - assert(q); - use(q, src); - } - return p; -} - -/* ftype - return a function type for rty function (ty,...)' */ -Type ftype(Type rty, Type ty) { - List list = append(ty, NULL); - - list = append(voidtype, list); - return func(rty, ltov(&list, PERM), 0); -} - -/* isfield - if name is a field in flist, return pointer to the field structure */ -static Field isfield(const char *name, Field flist) { - for ( ; flist; flist = flist->link) - if (flist->name == name) - break; - return flist; -} - -/* outtype - output type ty */ -void outtype(Type ty, FILE *f) { - switch (ty->op) { - case CONST+VOLATILE: case CONST: case VOLATILE: - fprint(f, "%k %t", ty->op, ty->type); - break; - case STRUCT: case UNION: case ENUM: - assert(ty->u.sym); - if (ty->size == 0) - fprint(f, "incomplete "); - assert(ty->u.sym->name); - if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') { - Symbol p = findtype(ty); - if (p == 0) - fprint(f, "%k defined at %w", ty->op, &ty->u.sym->src); - else - fprint(f, p->name); - } else { - fprint(f, "%k %s", ty->op, ty->u.sym->name); - if (ty->size == 0) - fprint(f, " defined at %w", &ty->u.sym->src); - } - break; - case VOID: case FLOAT: case INT: case UNSIGNED: - fprint(f, ty->u.sym->name); - break; - case POINTER: - fprint(f, "pointer to %t", ty->type); - break; - case FUNCTION: - fprint(f, "%t function", ty->type); - if (ty->u.f.proto && ty->u.f.proto[0]) { - int i; - fprint(f, "(%t", ty->u.f.proto[0]); - for (i = 1; ty->u.f.proto[i]; i++) - if (ty->u.f.proto[i] == voidtype) - fprint(f, ",..."); - else - fprint(f, ",%t", ty->u.f.proto[i]); - fprint(f, ")"); - } else if (ty->u.f.proto && ty->u.f.proto[0] == 0) - fprint(f, "(void)"); - - break; - case ARRAY: - if (ty->size > 0 && ty->type && ty->type->size > 0) { - fprint(f, "array %d", ty->size/ty->type->size); - while (ty->type && isarray(ty->type) && ty->type->type->size > 0) { - ty = ty->type; - fprint(f, ",%d", ty->size/ty->type->size); - } - } else - fprint(f, "incomplete array"); - if (ty->type) - fprint(f, " of %t", ty->type); - break; - default: assert(0); - } -} - -/* printdecl - output a C declaration for symbol p of type ty */ -void printdecl(Symbol p, Type ty) { - switch (p->sclass) { - case AUTO: - fprint(stderr, "%s;\n", typestring(ty, p->name)); - break; - case STATIC: case EXTERN: - fprint(stderr, "%k %s;\n", p->sclass, typestring(ty, p->name)); - break; - case TYPEDEF: case ENUM: - break; - default: assert(0); - } -} - -/* printproto - output a prototype declaration for function p */ -void printproto(Symbol p, Symbol callee[]) { - if (p->type->u.f.proto) - printdecl(p, p->type); - else { - int i; - List list = 0; - if (callee[0] == 0) - list = append(voidtype, list); - else - for (i = 0; callee[i]; i++) - list = append(callee[i]->type, list); - printdecl(p, func(freturn(p->type), ltov(&list, PERM), 0)); - } -} - -/* prtype - print details of type ty on f with given indent */ -static void prtype(Type ty, FILE *f, int indent, unsigned mark) { - switch (ty->op) { - default: - fprint(f, "(%d %d %d [%p])", ty->op, ty->size, ty->align, ty->u.sym); - break; - case FLOAT: case INT: case UNSIGNED: case VOID: - fprint(f, "(%k %d %d [\"%s\"])", ty->op, ty->size, ty->align, ty->u.sym->name); - break; - case CONST+VOLATILE: case CONST: case VOLATILE: case POINTER: case ARRAY: - fprint(f, "(%k %d %d ", ty->op, ty->size, ty->align); - prtype(ty->type, f, indent+1, mark); - fprint(f, ")"); - break; - case STRUCT: case UNION: - fprint(f, "(%k %d %d [\"%s\"]", ty->op, ty->size, ty->align, ty->u.sym->name); - if (ty->x.marked != mark) { - Field p; - ty->x.marked = mark; - for (p = ty->u.sym->u.s.flist; p; p = p->link) { - fprint(f, "\n%I", indent+1); - prtype(p->type, f, indent+1, mark); - fprint(f, " %s@%d", p->name, p->offset); - if (p->lsb) - fprint(f, ":%d..%d", - fieldsize(p) + fieldright(p), fieldright(p)); - } - fprint(f, "\n%I", indent); - } - fprint(f, ")"); - break; - case ENUM: - fprint(f, "(%k %d %d [\"%s\"]", ty->op, ty->size, ty->align, ty->u.sym->name); - if (ty->x.marked != mark) { - int i; - Symbol *p = ty->u.sym->u.idlist; - ty->x.marked = mark; - for (i = 0; p[i] != NULL; i++) - fprint(f, "%I%s=%d\n", indent+1, p[i]->name, p[i]->u.value); - } - fprint(f, ")"); - break; - case FUNCTION: - fprint(f, "(%k %d %d ", ty->op, ty->size, ty->align); - prtype(ty->type, f, indent+1, mark); - if (ty->u.f.proto) { - int i; - fprint(f, "\n%I{", indent+1); - for (i = 0; ty->u.f.proto[i]; i++) { - if (i > 0) - fprint(f, "%I", indent+2); - prtype(ty->u.f.proto[i], f, indent+2, mark); - fprint(f, "\n"); - } - fprint(f, "%I}", indent+1); - } - fprint(f, ")"); - break; - } -} - -/* printtype - print details of type ty on fd */ -void printtype(Type ty, int fd) { - static unsigned mark; - prtype(ty, fd == 1 ? stdout : stderr, 0, ++mark); - fprint(fd == 1 ? stdout : stderr, "\n"); -} - -/* typestring - return ty as C declaration for str, which may be "" */ -char *typestring(Type ty, char *str) { - for ( ; ty; ty = ty->type) { - Symbol p; - switch (ty->op) { - case CONST+VOLATILE: case CONST: case VOLATILE: - if (isptr(ty->type)) - str = stringf("%k %s", ty->op, str); - else - return stringf("%k %s", ty->op, typestring(ty->type, str)); - break; - case STRUCT: case UNION: case ENUM: - assert(ty->u.sym); - if ((p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - if (*ty->u.sym->name >= '1' && *ty->u.sym->name <= '9') - warning("unnamed %k in prototype\n", ty->op); - if (*str) - return stringf("%k %s %s", ty->op, ty->u.sym->name, str); - else - return stringf("%k %s", ty->op, ty->u.sym->name); - case VOID: case FLOAT: case INT: case UNSIGNED: - return *str ? stringf("%s %s", ty->u.sym->name, str) : ty->u.sym->name; - case POINTER: - if (!ischar(ty->type) && (p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - str = stringf(isarray(ty->type) || isfunc(ty->type) ? "(*%s)" : "*%s", str); - break; - case FUNCTION: - if ((p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - if (ty->u.f.proto == 0) - str = stringf("%s()", str); - else if (ty->u.f.proto[0]) { - int i; - str = stringf("%s(%s", str, typestring(ty->u.f.proto[0], "")); - for (i = 1; ty->u.f.proto[i]; i++) - if (ty->u.f.proto[i] == voidtype) - str = stringf("%s, ...", str); - else - str = stringf("%s, %s", str, typestring(ty->u.f.proto[i], "")); - str = stringf("%s)", str); - } else - str = stringf("%s(void)", str); - break; - case ARRAY: - if ((p = findtype(ty)) != NULL) - return *str ? stringf("%s %s", p->name, str) : p->name; - if (ty->type && ty->type->size > 0) - str = stringf("%s[%d]", str, ty->size/ty->type->size); - else - str = stringf("%s[]", str); - break; - default: assert(0); - } - } - assert(0); return 0; -} - diff --git a/lcc/src/x86.md b/lcc/src/x86.md deleted file mode 100644 index 6c4e1c4..0000000 --- a/lcc/src/x86.md +++ /dev/null @@ -1,998 +0,0 @@ -%{ -enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 }; -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -static void address(Symbol, Symbol, long); -static void blkfetch(int, int, int, int); -static void blkloop(int, int, int, int, int, int[]); -static void blkstore(int, int, int, int); -static void defaddress(Symbol); -static void defconst(int, int, Value); -static void defstring(int, char *); -static void defsymbol(Symbol); -static void doarg(Node); -static void emit2(Node); -static void export(Symbol); -static void clobber(Node); -static void function(Symbol, Symbol [], Symbol [], int); -static void global(Symbol); -static void import(Symbol); -static void local(Symbol); -static void progbeg(int, char **); -static void progend(void); -static void segment(int); -static void space(int); -static void target(Node); -extern int ckstack(Node, int); -extern int memop(Node); -extern int sametree(Node, Node); -static Symbol charreg[32], shortreg[32], intreg[32]; -static Symbol fltreg[32]; - -static Symbol charregw, shortregw, intregw, fltregw; - -static int cseg; - -static Symbol quo, rem; - -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRF4(VREGP) "# read register\n" -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRF8(VREGP) "# read register\n" -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" -con: CNSTI1 "%a" -con: CNSTU1 "%a" - -con: CNSTI2 "%a" -con: CNSTU2 "%a" - -con: CNSTI4 "%a" -con: CNSTU4 "%a" -con: CNSTP4 "%a" - -con: CNSTI8 "%a" -con: CNSTU8 "%a" -con: CNSTP8 "%a" -stmt: reg "" -acon: ADDRGP4 "(%a)" -acon: con "(%0)" -base: ADDRGP4 "(%a)" -base: reg "[%0]" -base: ADDI4(reg,acon) "%1[%0]" -base: ADDP4(reg,acon) "%1[%0]" -base: ADDU4(reg,acon) "%1[%0]" -base: ADDRFP4 "(%a)[ebp]" -base: ADDRLP4 "(%a)[ebp]" -index: reg "%0" -index: LSHI4(reg,con1) "%0*2" -index: LSHI4(reg,con2) "%0*4" -index: LSHI4(reg,con3) "%0*8" - -con1: CNSTI4 "1" range(a, 1, 1) -con1: CNSTU4 "1" range(a, 1, 1) -con2: CNSTI4 "2" range(a, 2, 2) -con2: CNSTU4 "2" range(a, 2, 2) -con3: CNSTI4 "3" range(a, 3, 3) -con3: CNSTU4 "3" range(a, 3, 3) -index: LSHU4(reg,con1) "%0*2" -index: LSHU4(reg,con2) "%0*4" -index: LSHU4(reg,con3) "%0*8" -addr: base "%0" -addr: ADDI4(index,base) "%1[%0]" -addr: ADDP4(index,base) "%1[%0]" -addr: ADDU4(index,base) "%1[%0]" -addr: index "[%0]" -mem: INDIRI1(addr) "byte ptr %0" -mem: INDIRI2(addr) "word ptr %0" -mem: INDIRI4(addr) "dword ptr %0" -mem: INDIRU1(addr) "byte ptr %0" -mem: INDIRU2(addr) "word ptr %0" -mem: INDIRU4(addr) "dword ptr %0" -mem: INDIRP4(addr) "dword ptr %0" -rc: reg "%0" -rc: con "%0" - -mr: reg "%0" -mr: mem "%0" - -mrc0: mem "%0" -mrc0: rc "%0" -mrc1: mem "%0" 1 -mrc1: rc "%0" - -mrc3: mem "%0" 3 -mrc3: rc "%0" -reg: addr "lea %c,%0\n" 1 -reg: mrc0 "mov %c,%0\n" 1 -reg: LOADI1(reg) "# move\n" 1 -reg: LOADI2(reg) "# move\n" 1 -reg: LOADI4(reg) "# move\n" move(a) -reg: LOADU1(reg) "# move\n" 1 -reg: LOADU2(reg) "# move\n" 1 -reg: LOADU4(reg) "# move\n" move(a) -reg: LOADP4(reg) "# move\n" move(a) -reg: ADDI4(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1 -reg: ADDP4(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1 -reg: ADDU4(reg,mrc1) "?mov %c,%0\nadd %c,%1\n" 1 -reg: SUBI4(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1 -reg: SUBP4(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1 -reg: SUBU4(reg,mrc1) "?mov %c,%0\nsub %c,%1\n" 1 -reg: BANDI4(reg,mrc1) "?mov %c,%0\nand %c,%1\n" 1 -reg: BORI4(reg,mrc1) "?mov %c,%0\nor %c,%1\n" 1 -reg: BXORI4(reg,mrc1) "?mov %c,%0\nxor %c,%1\n" 1 -reg: BANDU4(reg,mrc1) "?mov %c,%0\nand %c,%1\n" 1 -reg: BORU4(reg,mrc1) "?mov %c,%0\nor %c,%1\n" 1 -reg: BXORU4(reg,mrc1) "?mov %c,%0\nxor %c,%1\n" 1 -stmt: ASGNI4(addr,ADDI4(mem,con1)) "inc %1\n" memop(a) -stmt: ASGNI4(addr,ADDU4(mem,con1)) "inc %1\n" memop(a) -stmt: ASGNP4(addr,ADDP4(mem,con1)) "inc %1\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem,con1)) "dec %1\n" memop(a) -stmt: ASGNI4(addr,SUBU4(mem,con1)) "dec %1\n" memop(a) -stmt: ASGNP4(addr,SUBP4(mem,con1)) "dec %1\n" memop(a) -stmt: ASGNI4(addr,ADDI4(mem,rc)) "add %1,%2\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem,rc)) "sub %1,%2\n" memop(a) -stmt: ASGNU4(addr,ADDU4(mem,rc)) "add %1,%2\n" memop(a) -stmt: ASGNU4(addr,SUBU4(mem,rc)) "sub %1,%2\n" memop(a) - -stmt: ASGNI4(addr,BANDI4(mem,rc)) "and %1,%2\n" memop(a) -stmt: ASGNI4(addr,BORI4(mem,rc)) "or %1,%2\n" memop(a) -stmt: ASGNI4(addr,BXORI4(mem,rc)) "xor %1,%2\n" memop(a) -stmt: ASGNU4(addr,BANDU4(mem,rc)) "and %1,%2\n" memop(a) -stmt: ASGNU4(addr,BORU4(mem,rc)) "or %1,%2\n" memop(a) -stmt: ASGNU4(addr,BXORU4(mem,rc)) "xor %1,%2\n" memop(a) -reg: BCOMI4(reg) "?mov %c,%0\nnot %c\n" 2 -reg: BCOMU4(reg) "?mov %c,%0\nnot %c\n" 2 -reg: NEGI4(reg) "?mov %c,%0\nneg %c\n" 2 - -stmt: ASGNI4(addr,BCOMI4(mem)) "not %1\n" memop(a) -stmt: ASGNU4(addr,BCOMU4(mem)) "not %1\n" memop(a) -stmt: ASGNI4(addr,NEGI4(mem)) "neg %1\n" memop(a) -reg: LSHI4(reg,con5) "?mov %c,%0\nsal %c,%1\n" 2 -reg: LSHU4(reg,con5) "?mov %c,%0\nshl %c,%1\n" 2 -reg: RSHI4(reg,con5) "?mov %c,%0\nsar %c,%1\n" 2 -reg: RSHU4(reg,con5) "?mov %c,%0\nshr %c,%1\n" 2 - -stmt: ASGNI4(addr,LSHI4(mem,con5)) "sal %1,%2\n" memop(a) -stmt: ASGNI4(addr,LSHU4(mem,con5)) "shl %1,%2\n" memop(a) -stmt: ASGNI4(addr,RSHI4(mem,con5)) "sar %1,%2\n" memop(a) -stmt: ASGNI4(addr,RSHU4(mem,con5)) "shr %1,%2\n" memop(a) - -con5: CNSTI4 "%a" range(a, 0, 31) - -reg: LSHI4(reg,reg) "?mov %c,%0\nmov ecx,%1\nsal %c,cl\n" 3 -reg: LSHU4(reg,reg) "?mov %c,%0\nmov ecx,%1\nshl %c,cl\n" 2 -reg: RSHI4(reg,reg) "?mov %c,%0\nmov ecx,%1\nsar %c,cl\n" 2 -reg: RSHU4(reg,reg) "?mov %c,%0\nmov ecx,%1\nshr %c,cl\n" 2 -reg: MULI4(reg,mrc3) "?mov %c,%0\nimul %c,%1\n" 14 -reg: MULI4(con,mr) "imul %c,%1,%0\n" 13 -reg: MULU4(reg,mr) "mul %1\n" 13 -reg: DIVU4(reg,reg) "xor edx,edx\ndiv %1\n" -reg: MODU4(reg,reg) "xor edx,edx\ndiv %1\n" -reg: DIVI4(reg,reg) "cdq\nidiv %1\n" -reg: MODI4(reg,reg) "cdq\nidiv %1\n" -reg: CVPU4(reg) "mov %c,%0\n" move(a) -reg: CVUP4(reg) "mov %c,%0\n" move(a) -reg: CVII4(INDIRI1(addr)) "movsx %c,byte ptr %0\n" 3 -reg: CVII4(INDIRI2(addr)) "movsx %c,word ptr %0\n" 3 -reg: CVUU4(INDIRU1(addr)) "movzx %c,byte ptr %0\n" 3 -reg: CVUU4(INDIRU2(addr)) "movzx %c,word ptr %0\n" 3 -reg: CVII4(reg) "# extend\n" 3 -reg: CVIU4(reg) "# extend\n" 3 -reg: CVUI4(reg) "# extend\n" 3 -reg: CVUU4(reg) "# extend\n" 3 - -reg: CVII1(reg) "# truncate\n" 1 -reg: CVII2(reg) "# truncate\n" 1 -reg: CVUU1(reg) "# truncate\n" 1 -reg: CVUU2(reg) "# truncate\n" 1 -stmt: ASGNI1(addr,rc) "mov byte ptr %0,%1\n" 1 -stmt: ASGNI2(addr,rc) "mov word ptr %0,%1\n" 1 -stmt: ASGNI4(addr,rc) "mov dword ptr %0,%1\n" 1 -stmt: ASGNU1(addr,rc) "mov byte ptr %0,%1\n" 1 -stmt: ASGNU2(addr,rc) "mov word ptr %0,%1\n" 1 -stmt: ASGNU4(addr,rc) "mov dword ptr %0,%1\n" 1 -stmt: ASGNP4(addr,rc) "mov dword ptr %0,%1\n" 1 -stmt: ARGI4(mrc3) "push %0\n" 1 -stmt: ARGU4(mrc3) "push %0\n" 1 -stmt: ARGP4(mrc3) "push %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "mov ecx,%a\nrep movsb\n" -stmt: ARGB(INDIRB(reg)) "sub esp,%a\nmov edi,esp\nmov ecx,%a\nrep movsb\n" - -memf: INDIRF8(addr) "qword ptr %0" -memf: INDIRF4(addr) "dword ptr %0" -memf: CVFF8(INDIRF4(addr)) "dword ptr %0" -reg: memf "fld %0\n" 3 -stmt: ASGNF8(addr,reg) "fstp qword ptr %0\n" 7 -stmt: ASGNF4(addr,reg) "fstp dword ptr %0\n" 7 -stmt: ASGNF4(addr,CVFF4(reg)) "fstp dword ptr %0\n" 7 -stmt: ARGF8(reg) "sub esp,8\nfstp qword ptr [esp]\n" -stmt: ARGF4(reg) "sub esp,4\nfstp dword ptr [esp]\n" -reg: NEGF8(reg) "fchs\n" -reg: NEGF4(reg) "fchs\n" -flt: memf " %0" -flt: reg "p st(1),st" -reg: ADDF8(reg,flt) "fadd%1\n" -reg: ADDF4(reg,flt) "fadd%1\n" -reg: DIVF8(reg,flt) "fdiv%1\n" -reg: DIVF4(reg,flt) "fdiv%1\n" -reg: MULF8(reg,flt) "fmul%1\n" -reg: MULF4(reg,flt) "fmul%1\n" -reg: SUBF8(reg,flt) "fsub%1\n" -reg: SUBF4(reg,flt) "fsub%1\n" -reg: CVFF8(reg) "# CVFF8\n" -reg: CVFF4(reg) "sub esp,4\nfstp dword ptr 0[esp]\nfld dword ptr 0[esp]\nadd esp,4\n" 12 - -reg: CVFI4(reg) "call __ftol\n" 31 -reg: CVIF8(INDIRI4(addr)) "fild dword ptr %0\n" 10 -reg: CVIF4(reg) "push %0\nfild dword ptr 0[esp]\nadd esp,4\n" 12 - -reg: CVIF8(reg) "push %0\nfild dword ptr 0[esp]\nadd esp,4\n" 12 - -addrj: ADDRGP4 "%a" -addrj: reg "%0" 2 -addrj: mem "%0" 2 - -stmt: JUMPV(addrj) "jmp %0\n" 3 -stmt: LABELV "%a:\n" -stmt: EQI4(mem,rc) "cmp %0,%1\nje %a\n" 5 -stmt: GEI4(mem,rc) "cmp %0,%1\njge %a\n" 5 -stmt: GTI4(mem,rc) "cmp %0,%1\njg %a\n" 5 -stmt: LEI4(mem,rc) "cmp %0,%1\njle %a\n" 5 -stmt: LTI4(mem,rc) "cmp %0,%1\njl %a\n" 5 -stmt: NEI4(mem,rc) "cmp %0,%1\njne %a\n" 5 -stmt: GEU4(mem,rc) "cmp %0,%1\njae %a\n" 5 -stmt: GTU4(mem,rc) "cmp %0,%1\nja %a\n" 5 -stmt: LEU4(mem,rc) "cmp %0,%1\njbe %a\n" 5 -stmt: LTU4(mem,rc) "cmp %0,%1\njb %a\n" 5 -stmt: EQI4(reg,mrc1) "cmp %0,%1\nje %a\n" 4 -stmt: GEI4(reg,mrc1) "cmp %0,%1\njge %a\n" 4 -stmt: GTI4(reg,mrc1) "cmp %0,%1\njg %a\n" 4 -stmt: LEI4(reg,mrc1) "cmp %0,%1\njle %a\n" 4 -stmt: LTI4(reg,mrc1) "cmp %0,%1\njl %a\n" 4 -stmt: NEI4(reg,mrc1) "cmp %0,%1\njne %a\n" 4 - -stmt: EQU4(reg,mrc1) "cmp %0,%1\nje %a\n" 4 -stmt: GEU4(reg,mrc1) "cmp %0,%1\njae %a\n" 4 -stmt: GTU4(reg,mrc1) "cmp %0,%1\nja %a\n" 4 -stmt: LEU4(reg,mrc1) "cmp %0,%1\njbe %a\n" 4 -stmt: LTU4(reg,mrc1) "cmp %0,%1\njb %a\n" 4 -stmt: NEU4(reg,mrc1) "cmp %0,%1\njne %a\n" 4 -cmpf: memf " %0" -cmpf: reg "p" -stmt: EQF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nje %a\n" -stmt: GEF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njbe %a\n" -stmt: GTF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njb %a\n" -stmt: LEF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njae %a\n" -stmt: LTF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nja %a\n" -stmt: NEF8(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njne %a\n" - -stmt: EQF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nje %a\n" -stmt: GEF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njbe %a\n" -stmt: GTF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njb %a\n" -stmt: LEF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njae %a\n" -stmt: LTF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\nja %a\n" -stmt: NEF4(cmpf,reg) "fcomp%0\nfstsw ax\nsahf\njne %a\n" -reg: CALLI4(addrj) "call %0\nadd esp,%a\n" -reg: CALLU4(addrj) "call %0\nadd esp,%a\n" -reg: CALLP4(addrj) "call %0\nadd esp,%a\n" -stmt: CALLV(addrj) "call %0\nadd esp,%a\n" -reg: CALLF4(addrj) "call %0\nadd esp,%a\n" -reg: CALLF8(addrj) "call %0\nadd esp,%a\n" -stmt: CALLF4(addrj) "call %0\nadd esp,%a\nfstp\n" -stmt: CALLF8(addrj) "call %0\nadd esp,%a\nfstp\n" - -stmt: RETI4(reg) "# ret\n" -stmt: RETU4(reg) "# ret\n" -stmt: RETP4(reg) "# ret\n" -stmt: RETF4(reg) "# ret\n" -stmt: RETF8(reg) "# ret\n" -%% -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - intreg[EAX] = mkreg("eax", EAX, 1, IREG); - intreg[EDX] = mkreg("edx", EDX, 1, IREG); - intreg[ECX] = mkreg("ecx", ECX, 1, IREG); - intreg[EBX] = mkreg("ebx", EBX, 1, IREG); - intreg[ESI] = mkreg("esi", ESI, 1, IREG); - intreg[EDI] = mkreg("edi", EDI, 1, IREG); - - shortreg[EAX] = mkreg("ax", EAX, 1, IREG); - shortreg[ECX] = mkreg("cx", ECX, 1, IREG); - shortreg[EDX] = mkreg("dx", EDX, 1, IREG); - shortreg[EBX] = mkreg("bx", EBX, 1, IREG); - shortreg[ESI] = mkreg("si", ESI, 1, IREG); - shortreg[EDI] = mkreg("di", EDI, 1, IREG); - - charreg[EAX] = mkreg("al", EAX, 1, IREG); - charreg[ECX] = mkreg("cl", ECX, 1, IREG); - charreg[EDX] = mkreg("dl", EDX, 1, IREG); - charreg[EBX] = mkreg("bl", EBX, 1, IREG); - for (i = 0; i < 8; i++) - fltreg[i] = mkreg("%d", i, 0, FREG); - charregw = mkwildcard(charreg); - shortregw = mkwildcard(shortreg); - intregw = mkwildcard(intreg); - fltregw = mkwildcard(fltreg); - - tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX) - | (1<<EDX) | (1<<ECX) | (1<<EAX); - vmask[IREG] = 0; - tmask[FREG] = 0xff; - vmask[FREG] = 0; - print(".486\n"); - print(".model flat\n"); - print("extrn __fltused:near\n"); - print("extrn __ftol:near\n"); - cseg = 0; - quo = mkreg("eax", EAX, 1, IREG); - quo->x.regnode->mask |= 1<<EDX; - rem = mkreg("edx", EDX, 1, IREG); - rem->x.regnode->mask |= 1<<EAX; -} -static Symbol rmap(int opk) { - switch (optype(opk)) { - case B: case P: - return intregw; - case I: case U: - if (opsize(opk) == 1) - return charregw; - else if (opsize(opk) == 2) - return shortregw; - else - return intregw; - case F: - return fltregw; - default: - return 0; - } -} -static void segment(int n) { - if (n == cseg) - return; - if (cseg == CODE || cseg == LIT) - print("_TEXT ends\n"); - else if (cseg == DATA || cseg == BSS) - print("_DATA ends\n"); - cseg = n; - if (cseg == CODE || cseg == LIT) - print("_TEXT segment\n"); - else if (cseg == DATA || cseg == BSS) - print("_DATA segment\n"); -} -static void progend(void) { - segment(0); - print("end\n"); -} -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case MUL+U: - setreg(p, quo); - rtarget(p, 0, intreg[EAX]); - break; - case DIV+I: case DIV+U: - setreg(p, quo); - rtarget(p, 0, quo); - break; - case MOD+I: case MOD+U: - setreg(p, rem); - rtarget(p, 0, quo); - break; - case ASGN+B: - rtarget(p, 0, intreg[EDI]); - rtarget(p->kids[1], 0, intreg[ESI]); - break; - case ARG+B: - rtarget(p->kids[0], 0, intreg[ESI]); - break; - case CVF+I: - setreg(p, intreg[EAX]); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - setreg(p, intreg[EAX]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, intreg[EAX]); - break; - } -} - -static void clobber(Node p) { - static int nstack = 0; - - assert(p); - nstack = ckstack(p, nstack); - switch (specific(p->op)) { - case RSH+I: case RSH+U: case LSH+I: case LSH+U: - if (generic(p->kids[1]->op) != CNST - && !( generic(p->kids[1]->op) == INDIR - && specific(p->kids[1]->kids[0]->op) == VREG+P - && p->kids[1]->syms[RX]->u.t.cse - && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST -)) { - spill(1<<ECX, 1, p); - } - break; - case ASGN+B: case ARG+B: - spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p); - break; - case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F: - spill(1<<EAX, IREG, p); - break; - case CALL+F: - spill(1<<EDX | 1<<EAX | 1<<ECX, IREG, p); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - spill(1<<EDX | 1<<ECX, IREG, p); - break; - } -} -#define isfp(p) (optype((p)->op)==F) - -int ckstack(Node p, int n) { - int i; - - for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) - if (isfp(p->x.kids[i])) - n--; - if (isfp(p) && p->count > 0) - n++; - if (n > 8) - error("expression too complicated\n"); - debug(fprint(stderr, "(ckstack(%x)=%d)\n", p, n)); - assert(n >= 0); - return n; -} -int memop(Node p) { - assert(p); - assert(generic(p->op) == ASGN); - assert(p->kids[0]); - assert(p->kids[1]); - if (generic(p->kids[1]->kids[0]->op) == INDIR - && sametree(p->kids[0], p->kids[1]->kids[0]->kids[0])) - return 3; - else - return LBURG_MAX; -} -int sametree(Node p, Node q) { - return p == NULL && q == NULL - || p && q && p->op == q->op && p->syms[0] == q->syms[0] - && sametree(p->kids[0], q->kids[0]) - && sametree(p->kids[1], q->kids[1]); -} -static void emit2(Node p) { - int op = specific(p->op); -#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name) - - if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movsx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(charreg)); - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzx %s,%s\n", p->syms[RX]->x.name -, preg(shortreg)); - else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) { - char *dst = intreg[getregnum(p)]->x.name; - char *src = preg(intreg); - assert(opsize(p->op) <= opsize(p->x.kids[0]->op)); - if (dst != src) - print("mov %s,%s\n", dst, src); - } -} - -static void doarg(Node p) { - assert(p && p->syms[0]); - mkactual(4, p->syms[0]->u.c.v.i); -} -static void blkfetch(int k, int off, int reg, int tmp) {} -static void blkstore(int k, int off, int reg, int tmp) {} -static void blkloop(int dreg, int doff, int sreg, int soff, - int size, int tmps[]) {} -static void local(Symbol p) { - if (isfloat(p->type)) - p->sclass = AUTO; - if (askregvar(p, (*IR->x.rmap)(ttob(p->type))) == 0) - mkauto(p); -} -static void function(Symbol f, Symbol caller[], Symbol callee[], int n) { - int i; - - print("%s:\n", f->x.name); - print("push ebx\n"); - print("push esi\n"); - print("push edi\n"); - print("push ebp\n"); - print("mov ebp,esp\n"); - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~(unsigned)0; - offset = 16 + 4; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringf("%d", p->x.offset); - p->sclass = q->sclass = AUTO; - offset += roundup(q->type->size, 4); - } - assert(caller[i] == 0); - offset = maxoffset = 0; - gencode(caller, callee); - framesize = roundup(maxoffset, 4); - if (framesize > 0) - print("sub esp,%d\n", framesize); - emitcode(); - print("mov esp,ebp\n"); - print("pop ebp\n"); - print("pop edi\n"); - print("pop esi\n"); - print("pop ebx\n"); - print("ret\n"); -} -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("L%d", genlabel(1)); - else if (p->generated) - p->x.name = stringf("L%s", p->name); - else if (p->scope == GLOBAL || p->sclass == EXTERN) - p->x.name = stringf("_%s", p->name); - else if (p->scope == CONSTANTS - && (isint(p->type) || isptr(p->type)) - && p->name[0] == '0' && p->name[1] == 'x') - p->x.name = stringf("0%sH", &p->name[2]); - else - p->x.name = p->name; -} -static void address(Symbol q, Symbol p, long n) { - if (p->scope == GLOBAL - || p->sclass == STATIC || p->sclass == EXTERN) - q->x.name = stringf("%s%s%D", - p->x.name, n >= 0 ? "+" : "", n); - else { - assert(n <= INT_MAX && n >= INT_MIN); - q->x.offset = p->x.offset + n; - q->x.name = stringd(q->x.offset); - } -} -static void defconst(int suffix, int size, Value v) { - if (suffix == I && size == 1) - print("db %d\n", v.u); - else if (suffix == I && size == 2) - print("dw %d\n", v.i); - else if (suffix == I && size == 4) - print("dd %d\n", v.i); - else if (suffix == U && size == 1) - print("db 0%xH\n", v.u); - else if (suffix == U && size == 2) - print("dw 0%xH\n", v.u); - else if (suffix == U && size == 4) - print("dd 0%xH\n", v.u); - else if (suffix == P && size == 4) - print("dd 0%xH\n", v.p); - else if (suffix == F && size == 4) { - float f = v.d; - print("dd 0%xH\n", *(unsigned *)&f); - } - else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print("dd 0%xH\ndd 0%xH\n", p[swap], p[!swap]); - } - else assert(0); -} -static void defaddress(Symbol p) { - print("dd %s\n", p->x.name); -} -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print("db %d\n", (*s)&0377); -} -static void export(Symbol p) { - print("public %s\n", p->x.name); -} -static void import(Symbol p) { - int oldseg = cseg; - - if (p->ref > 0) { - segment(0); - print("extrn %s:near\n", p->x.name); - segment(oldseg); - } -} -static void global(Symbol p) { - print("align %d\n", - p->type->align > 4 ? 4 : p->type->align); - print("%s label byte\n", p->x.name); - if (p->u.seg == BSS) - print("db %d dup (0)\n", p->type->size); -} -static void space(int n) { - if (cseg != BSS) - print("db %d dup (0)\n", n); -} -Interface x86IR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 4, 1, /* double */ - 8, 4, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 4, 0, /* struct; so that ARGB keeps stack aligned */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 0, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - address, - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - local, - progbeg, - progend, - segment, - space, - 0, 0, 0, 0, 0, 0, 0, - {1, rmap, - blkfetch, blkstore, blkloop, - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - doarg, - target, - clobber, -} -}; -static char rcsid[] = "$Id: x86.md 145 2001-10-17 21:53:10Z timo $"; diff --git a/lcc/src/x86linux.md b/lcc/src/x86linux.md deleted file mode 100644 index d185f56..0000000 --- a/lcc/src/x86linux.md +++ /dev/null @@ -1,1081 +0,0 @@ -%{ -/* x86/linux lburg spec. Derived from x86.md by -Marcos Ramirez <marcos@inf.utfsm.cl> -Horst von Brand <vonbrand@sleipnir.valparaiso.cl> -Jacob Navia <jacob@jacob.remcomp.fr> -*/ -enum { EAX=0, ECX=1, EDX=2, EBX=3, ESI=6, EDI=7 }; -#include "c.h" -#define NODEPTR_TYPE Node -#define OP_LABEL(p) ((p)->op) -#define LEFT_CHILD(p) ((p)->kids[0]) -#define RIGHT_CHILD(p) ((p)->kids[1]) -#define STATE_LABEL(p) ((p)->x.state) -extern int ckstack(Node, int); -extern int memop(Node); -extern int sametree(Node, Node); -static Symbol charreg[32], shortreg[32], intreg[32]; -static Symbol fltreg[32]; - -static Symbol charregw, shortregw, intregw, fltregw; - -static int cseg; - -static Symbol quo, rem; - -extern char *stabprefix; -extern void stabblock(int, int, Symbol*); -extern void stabend(Coordinate *, Symbol, Coordinate **, Symbol *, Symbol *); -extern void stabfend(Symbol, int); -extern void stabinit(char *, int, char *[]); -extern void stabline(Coordinate *); -extern void stabsym(Symbol); -extern void stabtype(Symbol); - -static int pflag = 0; -static char rcsid[] = "$Id: x86linux.md 145 2001-10-17 21:53:10Z timo $"; - -#define hasargs(p) (p->syms[0] && p->syms[0]->u.c.v.i > 0 ? 0 : LBURG_MAX) -%} -%start stmt -%term CNSTF4=4113 -%term CNSTF8=8209 -%term CNSTF16=16401 -%term CNSTI1=1045 -%term CNSTI2=2069 -%term CNSTI4=4117 -%term CNSTI8=8213 -%term CNSTP4=4119 -%term CNSTP8=8215 -%term CNSTU1=1046 -%term CNSTU2=2070 -%term CNSTU4=4118 -%term CNSTU8=8214 - -%term ARGB=41 -%term ARGF4=4129 -%term ARGF8=8225 -%term ARGF16=16417 -%term ARGI4=4133 -%term ARGI8=8229 -%term ARGP4=4135 -%term ARGP8=8231 -%term ARGU4=4134 -%term ARGU8=8230 - -%term ASGNB=57 -%term ASGNF4=4145 -%term ASGNF8=8241 -%term ASGNF16=16433 -%term ASGNI1=1077 -%term ASGNI2=2101 -%term ASGNI4=4149 -%term ASGNI8=8245 -%term ASGNP4=4151 -%term ASGNP8=8247 -%term ASGNU1=1078 -%term ASGNU2=2102 -%term ASGNU4=4150 -%term ASGNU8=8246 - -%term INDIRB=73 -%term INDIRF4=4161 -%term INDIRF8=8257 -%term INDIRF16=16449 -%term INDIRI1=1093 -%term INDIRI2=2117 -%term INDIRI4=4165 -%term INDIRI8=8261 -%term INDIRP4=4167 -%term INDIRP8=8263 -%term INDIRU1=1094 -%term INDIRU2=2118 -%term INDIRU4=4166 -%term INDIRU8=8262 - -%term CVFF4=4209 -%term CVFF8=8305 -%term CVFF16=16497 -%term CVFI4=4213 -%term CVFI8=8309 - -%term CVIF4=4225 -%term CVIF8=8321 -%term CVIF16=16513 -%term CVII1=1157 -%term CVII2=2181 -%term CVII4=4229 -%term CVII8=8325 -%term CVIU1=1158 -%term CVIU2=2182 -%term CVIU4=4230 -%term CVIU8=8326 - -%term CVPP4=4247 -%term CVPP8=8343 -%term CVPP16=16535 -%term CVPU4=4246 -%term CVPU8=8342 - -%term CVUI1=1205 -%term CVUI2=2229 -%term CVUI4=4277 -%term CVUI8=8373 -%term CVUP4=4279 -%term CVUP8=8375 -%term CVUP16=16567 -%term CVUU1=1206 -%term CVUU2=2230 -%term CVUU4=4278 -%term CVUU8=8374 - -%term NEGF4=4289 -%term NEGF8=8385 -%term NEGF16=16577 -%term NEGI4=4293 -%term NEGI8=8389 - -%term CALLB=217 -%term CALLF4=4305 -%term CALLF8=8401 -%term CALLF16=16593 -%term CALLI4=4309 -%term CALLI8=8405 -%term CALLP4=4311 -%term CALLP8=8407 -%term CALLU4=4310 -%term CALLU8=8406 -%term CALLV=216 - -%term RETF4=4337 -%term RETF8=8433 -%term RETF16=16625 -%term RETI4=4341 -%term RETI8=8437 -%term RETP4=4343 -%term RETP8=8439 -%term RETU4=4342 -%term RETU8=8438 -%term RETV=248 - -%term ADDRGP4=4359 -%term ADDRGP8=8455 - -%term ADDRFP4=4375 -%term ADDRFP8=8471 - -%term ADDRLP4=4391 -%term ADDRLP8=8487 - -%term ADDF4=4401 -%term ADDF8=8497 -%term ADDF16=16689 -%term ADDI4=4405 -%term ADDI8=8501 -%term ADDP4=4407 -%term ADDP8=8503 -%term ADDU4=4406 -%term ADDU8=8502 - -%term SUBF4=4417 -%term SUBF8=8513 -%term SUBF16=16705 -%term SUBI4=4421 -%term SUBI8=8517 -%term SUBP4=4423 -%term SUBP8=8519 -%term SUBU4=4422 -%term SUBU8=8518 - -%term LSHI4=4437 -%term LSHI8=8533 -%term LSHU4=4438 -%term LSHU8=8534 - -%term MODI4=4453 -%term MODI8=8549 -%term MODU4=4454 -%term MODU8=8550 - -%term RSHI4=4469 -%term RSHI8=8565 -%term RSHU4=4470 -%term RSHU8=8566 - -%term BANDI4=4485 -%term BANDI8=8581 -%term BANDU4=4486 -%term BANDU8=8582 - -%term BCOMI4=4501 -%term BCOMI8=8597 -%term BCOMU4=4502 -%term BCOMU8=8598 - -%term BORI4=4517 -%term BORI8=8613 -%term BORU4=4518 -%term BORU8=8614 - -%term BXORI4=4533 -%term BXORI8=8629 -%term BXORU4=4534 -%term BXORU8=8630 - -%term DIVF4=4545 -%term DIVF8=8641 -%term DIVF16=16833 -%term DIVI4=4549 -%term DIVI8=8645 -%term DIVU4=4550 -%term DIVU8=8646 - -%term MULF4=4561 -%term MULF8=8657 -%term MULF16=16849 -%term MULI4=4565 -%term MULI8=8661 -%term MULU4=4566 -%term MULU8=8662 - -%term EQF4=4577 -%term EQF8=8673 -%term EQF16=16865 -%term EQI4=4581 -%term EQI8=8677 -%term EQU4=4582 -%term EQU8=8678 - -%term GEF4=4593 -%term GEF8=8689 -%term GEI4=4597 -%term GEI8=8693 -%term GEI16=16885 -%term GEU4=4598 -%term GEU8=8694 - -%term GTF4=4609 -%term GTF8=8705 -%term GTF16=16897 -%term GTI4=4613 -%term GTI8=8709 -%term GTU4=4614 -%term GTU8=8710 - -%term LEF4=4625 -%term LEF8=8721 -%term LEF16=16913 -%term LEI4=4629 -%term LEI8=8725 -%term LEU4=4630 -%term LEU8=8726 - -%term LTF4=4641 -%term LTF8=8737 -%term LTF16=16929 -%term LTI4=4645 -%term LTI8=8741 -%term LTU4=4646 -%term LTU8=8742 - -%term NEF4=4657 -%term NEF8=8753 -%term NEF16=16945 -%term NEI4=4661 -%term NEI8=8757 -%term NEU4=4662 -%term NEU8=8758 - -%term JUMPV=584 - -%term LABELV=600 - -%term LOADB=233 -%term LOADF4=4321 -%term LOADF8=8417 -%term LOADF16=16609 -%term LOADI1=1253 -%term LOADI2=2277 -%term LOADI4=4325 -%term LOADI8=8421 -%term LOADP4=4327 -%term LOADP8=8423 -%term LOADU1=1254 -%term LOADU2=2278 -%term LOADU4=4326 -%term LOADU8=8422 - -%term VREGP=711 -%% -reg: INDIRI1(VREGP) "# read register\n" -reg: INDIRU1(VREGP) "# read register\n" - -reg: INDIRI2(VREGP) "# read register\n" -reg: INDIRU2(VREGP) "# read register\n" - -reg: INDIRI4(VREGP) "# read register\n" -reg: INDIRP4(VREGP) "# read register\n" -reg: INDIRU4(VREGP) "# read register\n" - -reg: INDIRI8(VREGP) "# read register\n" -reg: INDIRP8(VREGP) "# read register\n" -reg: INDIRU8(VREGP) "# read register\n" - -freg: INDIRF4(VREGP) "# read register\n" -freg: INDIRF8(VREGP) "# read register\n" - -stmt: ASGNI1(VREGP,reg) "# write register\n" -stmt: ASGNU1(VREGP,reg) "# write register\n" - -stmt: ASGNI2(VREGP,reg) "# write register\n" -stmt: ASGNU2(VREGP,reg) "# write register\n" - -stmt: ASGNF4(VREGP,reg) "# write register\n" -stmt: ASGNI4(VREGP,reg) "# write register\n" -stmt: ASGNP4(VREGP,reg) "# write register\n" -stmt: ASGNU4(VREGP,reg) "# write register\n" - -stmt: ASGNF8(VREGP,reg) "# write register\n" -stmt: ASGNI8(VREGP,reg) "# write register\n" -stmt: ASGNP8(VREGP,reg) "# write register\n" -stmt: ASGNU8(VREGP,reg) "# write register\n" - -cnst: CNSTI1 "%a" -cnst: CNSTU1 "%a" - -cnst: CNSTI2 "%a" -cnst: CNSTU2 "%a" - -cnst: CNSTI4 "%a" -cnst: CNSTU4 "%a" -cnst: CNSTP4 "%a" - -cnst: CNSTI8 "%a" -cnst: CNSTU8 "%a" -cnst: CNSTP8 "%a" - -con: cnst "$%0" - -stmt: reg "" -stmt: freg "" - -acon: ADDRGP4 "%a" -acon: ADDRGP8 "%a" -acon: cnst "%0" - -baseaddr: ADDRGP4 "%a" -base: reg "(%0)" -base: ADDI4(reg,acon) "%1(%0)" -base: ADDP4(reg,acon) "%1(%0)" -base: ADDU4(reg,acon) "%1(%0)" -base: ADDRFP4 "%a(%%ebp)" -base: ADDRLP4 "%a(%%ebp)" - -index: reg "%0" -index: LSHI4(reg,con1) "%0,2" -index: LSHI4(reg,con2) "%0,4" -index: LSHI4(reg,con3) "%0,8" -index: LSHU4(reg,con1) "%0,2" -index: LSHU4(reg,con2) "%0,4" -index: LSHU4(reg,con3) "%0,8" - -con0: CNSTI4 "1" range(a, 0, 0) -con0: CNSTU4 "1" range(a, 0, 0) -con1: CNSTI4 "1" range(a, 1, 1) -con1: CNSTU4 "1" range(a, 1, 1) -con2: CNSTI4 "2" range(a, 2, 2) -con2: CNSTU4 "2" range(a, 2, 2) -con3: CNSTI4 "3" range(a, 3, 3) -con3: CNSTU4 "3" range(a, 3, 3) - -addr: base "%0" -addr: baseaddr "%0" -addr: ADDI4(index,baseaddr) "%1(,%0)" -addr: ADDP4(index,baseaddr) "%1(,%0)" -addr: ADDU4(index,baseaddr) "%1(,%0)" - -addr: ADDI4(reg,baseaddr) "%1(%0)" -addr: ADDP4(reg,baseaddr) "%1(%0)" -addr: ADDU4(reg,baseaddr) "%1(%0)" - -addr: ADDI4(index,reg) "(%1,%0)" -addr: ADDP4(index,reg) "(%1,%0)" -addr: ADDU4(index,reg) "(%1,%0)" - -addr: index "(,%0)" - -mem1: INDIRI1(addr) "%0" -mem1: INDIRU1(addr) "%0" -mem2: INDIRI2(addr) "%0" -mem2: INDIRU2(addr) "%0" -mem4: INDIRI4(addr) "%0" -mem4: INDIRU4(addr) "%0" -mem4: INDIRP4(addr) "%0" - -rc: reg "%0" -rc: con "%0" - -mr: reg "%0" -mr: mem4 "%0" - -mr1: reg "%0" -mr1: mem1 "%0" - -mr2: reg "%0" -mr2: mem2 "%0" - -mrc: mem4 "%0" 1 -mrc: mem1 "%0" 1 -mrc: mem2 "%0" 1 -mrc: rc "%0" - -reg: addr "leal %0,%c\n" 1 -reg: mr "movl %0,%c\n" 1 -reg: mr1 "movb %0,%c\n" 1 -reg: mr2 "movw %0,%c\n" 1 -reg: con "movl %0,%c\n" 1 - -reg: LOADI1(reg) "# move\n" 1 -reg: LOADI2(reg) "# move\n" 1 -reg: LOADI4(reg) "# move\n" move(a) -reg: LOADU1(reg) "# move\n" 1 -reg: LOADU2(reg) "# move\n" 1 -reg: LOADU4(reg) "# move\n" move(a) -reg: LOADP4(reg) "# move\n" move(a) -reg: ADDI4(reg,mrc) "?movl %0,%c\naddl %1,%c\n" 1 -reg: ADDP4(reg,mrc) "?movl %0,%c\naddl %1,%c\n" 1 -reg: ADDU4(reg,mrc) "?movl %0,%c\naddl %1,%c\n" 1 -reg: SUBI4(reg,mrc) "?movl %0,%c\nsubl %1,%c\n" 1 -reg: SUBP4(reg,mrc) "?movl %0,%c\nsubl %1,%c\n" 1 -reg: SUBU4(reg,mrc) "?movl %0,%c\nsubl %1,%c\n" 1 -reg: BANDI4(reg,mrc) "?movl %0,%c\nandl %1,%c\n" 1 -reg: BORI4(reg,mrc) "?movl %0,%c\norl %1,%c\n" 1 -reg: BXORI4(reg,mrc) "?movl %0,%c\nxorl %1,%c\n" 1 -reg: BANDU4(reg,mrc) "?movl %0,%c\nandl %1,%c\n" 1 -reg: BORU4(reg,mrc) "?movl %0,%c\norl %1,%c\n" 1 -reg: BXORU4(reg,mrc) "?movl %0,%c\nxorl %1,%c\n" 1 - -stmt: ASGNI4(addr,ADDI4(mem4,con1)) "incl %1\n" memop(a) -stmt: ASGNI4(addr,ADDU4(mem4,con1)) "incl %1\n" memop(a) -stmt: ASGNP4(addr,ADDP4(mem4,con1)) "incl %1\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem4,con1)) "decl %1\n" memop(a) -stmt: ASGNI4(addr,SUBU4(mem4,con1)) "decl %1\n" memop(a) -stmt: ASGNP4(addr,SUBP4(mem4,con1)) "decl %1\n" memop(a) -stmt: ASGNI4(addr,ADDI4(mem4,rc)) "addl %2,%1\n" memop(a) -stmt: ASGNI4(addr,SUBI4(mem4,rc)) "sub %2,%1\n" memop(a) -stmt: ASGNU4(addr,ADDU4(mem4,rc)) "add %2,%1\n" memop(a) -stmt: ASGNU4(addr,SUBU4(mem4,rc)) "sub %2,%1\n" memop(a) - -stmt: ASGNI4(addr,BANDI4(mem4,rc)) "andl %2,%1\n" memop(a) -stmt: ASGNI4(addr,BORI4(mem4,rc)) "orl %2,%1\n" memop(a) -stmt: ASGNI4(addr,BXORI4(mem4,rc)) "xorl %2,%1\n" memop(a) -stmt: ASGNU4(addr,BANDU4(mem4,rc)) "andl %2,%1\n" memop(a) -stmt: ASGNU4(addr,BORU4(mem4,rc)) "orl %2,%1\n" memop(a) -stmt: ASGNU4(addr,BXORU4(mem4,rc)) "xorl %2,%1\n" memop(a) -reg: BCOMI4(reg) "?movl %0,%c\nnotl %c\n" 2 -reg: BCOMU4(reg) "?movl %0,%c\nnotl %c\n" 2 -reg: NEGI4(reg) "?movl %0,%c\nnegl %c\n" 2 - -stmt: ASGNI4(addr,BCOMI4(mem4)) "notl %1\n" memop(a) -stmt: ASGNU4(addr,BCOMU4(mem4)) "notl %1\n" memop(a) -stmt: ASGNI4(addr,NEGI4(mem4)) "negl %1\n" memop(a) -reg: LSHI4(reg,rc5) "?movl %0,%c\nsall %1,%c\n" 2 -reg: LSHU4(reg,rc5) "?movl %0,%c\nshll %1,%c\n" 2 -reg: RSHI4(reg,rc5) "?movl %0,%c\nsarl %1,%c\n" 2 -reg: RSHU4(reg,rc5) "?movl %0,%c\nshrl %1,%c\n" 2 - -stmt: ASGNI4(addr,LSHI4(mem4,rc5)) "sall %2,%1\n" memop(a) -stmt: ASGNI4(addr,LSHU4(mem4,rc5)) "shll %2,%1\n" memop(a) -stmt: ASGNI4(addr,RSHI4(mem4,rc5)) "sarl %2,%1\n" memop(a) -stmt: ASGNI4(addr,RSHU4(mem4,rc5)) "shrl %2,%1\n" memop(a) - -rc5: CNSTI4 "$%a" range(a, 0, 31) -rc5: reg "%%cl" -reg: MULI4(reg,mrc) "?movl %0,%c\nimull %1,%c\n" 14 -reg: MULI4(con,mr) "imul %0,%1,%c\n" 13 -reg: MULU4(reg,mr) "mull %1\n" 13 -reg: DIVU4(reg,reg) "xorl %%edx,%%edx\ndivl %1\n" -reg: MODU4(reg,reg) "xorl %%edx,%%edx\ndivl %1\n" -reg: DIVI4(reg,reg) "cdq\nidivl %1\n" -reg: MODI4(reg,reg) "cdq\nidivl %1\n" -reg: CVPU4(reg) "movl %0,%c\n" move(a) -reg: CVUP4(reg) "movl %0,%c\n" move(a) -reg: CVII4(INDIRI1(addr)) "movsbl %0,%c\n" 3 -reg: CVII4(INDIRI2(addr)) "movswl %0,%c\n" 3 -reg: CVUU4(INDIRU1(addr)) "movzbl %0,%c\n" 3 -reg: CVUU4(INDIRU2(addr)) "movzwl %0,%c\n" 3 -reg: CVII4(reg) "# extend\n" 3 -reg: CVIU4(reg) "# extend\n" 3 -reg: CVUI4(reg) "# extend\n" 3 -reg: CVUU4(reg) "# extend\n" 3 - -reg: CVII1(reg) "# truncate\n" 1 -reg: CVII2(reg) "# truncate\n" 1 -reg: CVUU1(reg) "# truncate\n" 1 -reg: CVUU2(reg) "# truncate\n" 1 - -mrca: mem4 "%0" -mrca: rc "%0" -mrca: ADDRGP4 "$%a" -mrca: ADDRGP8 "$%a" - -stmt: ASGNI1(addr,rc) "movb %1,%0\n" 1 -stmt: ASGNI2(addr,rc) "movw %1,%0\n" 1 -stmt: ASGNI4(addr,rc) "movl %1,%0\n" 1 -stmt: ASGNU1(addr,rc) "movb %1,%0\n" 1 -stmt: ASGNU2(addr,rc) "movw %1,%0\n" 1 -stmt: ASGNU4(addr,rc) "movl %1,%0\n" 1 -stmt: ASGNP4(addr,rc) "movl %1,%0\n" 1 -stmt: ARGI4(mrca) "pushl %0\n" 1 -stmt: ARGU4(mrca) "pushl %0\n" 1 -stmt: ARGP4(mrca) "pushl %0\n" 1 -stmt: ASGNB(reg,INDIRB(reg)) "movl $%a,%%ecx\nrep\nmovsb\n" -stmt: ARGB(INDIRB(reg)) "subl $%a,%%esp\nmovl %%esp,%%edi\nmovl $%a,%%ecx\nrep\nmovsb\n" - -memf: INDIRF8(addr) "l %0" -memf: INDIRF4(addr) "s %0" -memf: CVFF8(INDIRF4(addr)) "s %0" -memf: CVFF4(INDIRF8(addr)) "l %0" - -freg: memf "fld%0\n" 3 - -stmt: ASGNF8(addr,freg) "fstpl %0\n" 7 -stmt: ASGNF4(addr,freg) "fstps %0\n" 7 -stmt: ASGNF4(addr,CVFF4(freg)) "fstps %0\n" 7 - -stmt: ARGF8(freg) "subl $8,%%esp\nfstpl (%%esp)\n" -stmt: ARGF4(freg) "subl $4,%%esp\nfstps (%%esp)\n" -freg: NEGF8(freg) "fchs\n" -freg: NEGF4(freg) "fchs\n" - -flt: memf "%0" -flt: freg "p %%st(1),%%st" - -freg: ADDF4(freg,flt) "fadd%1\n" -freg: ADDF8(freg,flt) "fadd%1\n" - -freg: DIVF4(freg,flt) "fdiv%1\n" -freg: DIVF8(freg,flt) "fdiv%1\n" - -freg: MULF4(freg,flt) "fmul%1\n" -freg: MULF8(freg,flt) "fmul%1\n" - -freg: SUBF4(freg,flt) "fsub%1\n" -freg: SUBF8(freg,flt) "fsub%1\n" - -freg: CVFF8(freg) "# CVFF8\n" -freg: CVFF4(freg) "sub $4,%%esp\nfstps (%%esp)\nflds (%%esp)\naddl $4,%%esp\n" 12 - -stmt: ASGNI4(addr,CVFI4(freg)) "fistpl %0\n" 29 -reg: CVFI4(freg) "subl $4,%%esp\nfistpl 0(%%esp)\npopl %c\n" 31 - -freg: CVIF8(INDIRI4(addr)) "fildl %0\n" 10 -freg: CVIF8(reg) "pushl %0\nfildl (%%esp)\naddl $4,%%esp\n" 12 - -freg: CVIF4(INDIRI4(addr)) "fildl %0\n" 10 -freg: CVIF4(reg) "pushl %0\nfildl (%%esp)\naddl $4,%%esp\n" 12 - -addrj: ADDRGP4 "%a" -addrj: reg "*%0" 2 -addrj: mem4 "*%0" 2 - -stmt: LABELV "%a:\n" -stmt: JUMPV(addrj) "jmp %0\n" 3 -stmt: EQI4(mem4,rc) "cmpl %1,%0\nje %a\n" 5 -stmt: GEI4(mem4,rc) "cmpl %1,%0\njge %a\n" 5 -stmt: GTI4(mem4,rc) "cmpl %1,%0\njg %a\n" 5 -stmt: LEI4(mem4,rc) "cmpl %1,%0\njle %a\n" 5 -stmt: LTI4(mem4,rc) "cmpl %1,%0\njl %a\n" 5 -stmt: NEI4(mem4,rc) "cmpl %1,%0\njne %a\n" 5 -stmt: GEU4(mem4,rc) "cmpl %1,%0\njae %a\n" 5 -stmt: GTU4(mem4,rc) "cmpl %1,%0\nja %a\n" 5 -stmt: LEU4(mem4,rc) "cmpl %1,%0\njbe %a\n" 5 -stmt: LTU4(mem4,rc) "cmpl %1,%0\njb %a\n" 5 -stmt: EQI4(reg,mrc) "cmpl %1,%0\nje %a\n" 4 -stmt: GEI4(reg,mrc) "cmpl %1,%0\njge %a\n" 4 -stmt: GTI4(reg,mrc) "cmpl %1,%0\njg %a\n" 4 -stmt: LEI4(reg,mrc) "cmpl %1,%0\njle %a\n" 4 -stmt: LTI4(reg,mrc) "cmpl %1,%0\njl %a\n" 4 -stmt: NEI4(reg,mrc) "cmpl %1,%0\njne %a\n" 4 - -stmt: EQU4(reg,mrc) "cmpl %1,%0\nje %a\n" 4 -stmt: GEU4(reg,mrc) "cmpl %1,%0\njae %a\n" 4 -stmt: GTU4(reg,mrc) "cmpl %1,%0\nja %a\n" 4 -stmt: LEU4(reg,mrc) "cmpl %1,%0\njbe %a\n" 4 -stmt: LTU4(reg,mrc) "cmpl %1,%0\njb %a\n" 4 -stmt: NEU4(reg,mrc) "cmpl %1,%0\njne %a\n" 4 - -stmt: EQI4(BANDU4(mr,con),con0) "testl %1,%0\nje %a\n" 3 -stmt: NEI4(BANDU4(mr,con),con0) "testl %1,%0\njne %a\n" - -stmt: EQI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "testw %1,%0\nje %a\n" -stmt: NEI4(BANDU4(CVII2(INDIRI2(addr)),con),con0) "testw %1,%0\njne %a\n" -stmt: EQI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "testw %1,%0\nje %a\n" -stmt: NEI4(BANDU4(CVIU2(INDIRI2(addr)),con),con0) "testw %1,%0\njne %a\n" -stmt: EQI4(BANDU4(CVII1(INDIRI1(addr)),con),con0) "testb %1,%0\nje %a\n" - -cmpf: INDIRF8(addr) "l %0" -cmpf: INDIRF4(addr) "s %0" -cmpf: CVFF8(INDIRF4(addr)) "s %0" -cmpf: freg "p" - -stmt: EQF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nje %a\n" -stmt: GEF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njbe %a\n" -stmt: GTF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njb %a\n" -stmt: LEF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njae %a\n" -stmt: LTF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nja %a\n" -stmt: NEF8(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njne %a\n" - -stmt: EQF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nje %a\n" -stmt: GEF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njbe %a\n" -stmt: GTF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njb %a\n" -stmt: LEF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njae %a\n" -stmt: LTF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\nja %a\n" -stmt: NEF4(cmpf,freg) "fcomp%0\nfstsw %%ax\nsahf\njne %a\n" - -freg: DIVF8(freg,CVIF8(INDIRI4(addr))) "fidivl %1\n" -freg: DIVF8(CVIF8(INDIRI4(addr)),freg) "fidivrl %0\n" -freg: DIVF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fidivs %1\n" -freg: DIVF8(CVIF8(CVII2(INDIRI2(addr))),freg) "fidivrs %0\n" -freg: MULF8(freg,CVIF8(INDIRI4(addr))) "fimull %1\n" -freg: MULF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fimuls %1\n" -freg: SUBF8(freg,CVIF8(INDIRI4(addr))) "fisubl %1\n" -freg: SUBF8(CVIF8(INDIRI4(addr)),freg) "fisubrl %0\n" -freg: SUBF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fisubs %1\n" -freg: SUBF8(CVIF8(CVII2(INDIRI2(addr))),freg) "fisubrs %0\n" -freg: ADDF8(freg,CVIF8(INDIRI4(addr))) "fiaddl %1\n" -freg: ADDF8(freg,CVIF8(CVII2(INDIRI2(addr)))) "fiadds %1\n" -freg: ADDF8(freg,CVFF8(INDIRF4(addr))) "fdivs %1\n" -freg: SUBF8(freg,CVFF8(INDIRF4(addr))) "fsubs %1\n" -freg: MULF8(freg,CVFF8(INDIRF4(addr))) "fmuls %1\n" -freg: DIVF8(freg,CVFF8(INDIRF4(addr))) "fdivs %1\n" -freg: LOADF8(memf) "fld%0\n" - -reg: CALLI4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -reg: CALLU4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -reg: CALLP4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) - -reg: CALLI4(addrj) "call %0\n" 1 -reg: CALLU4(addrj) "call %0\n" 1 -reg: CALLP4(addrj) "call %0\n" 1 - -stmt: CALLV(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -stmt: CALLV(addrj) "call %0\n" 1 - -freg: CALLF4(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -freg: CALLF4(addrj) "call %0\n" 1 - -stmt: CALLF4(addrj) "call %0\naddl $%a,%%esp\nfstp %%st(0)\n" hasargs(a) -stmt: CALLF4(addrj) "call %0\nfstp %%st(0)\n" 1 - -freg: CALLF8(addrj) "call %0\naddl $%a,%%esp\n" hasargs(a) -freg: CALLF8(addrj) "call %0\n" 1 - -stmt: CALLF8(addrj) "call %0\naddl $%a,%%esp\nfstp %%st(0)\n" hasargs(a) -stmt: CALLF8(addrj) "call %0\nfstp %%st(0)\n" 1 - -stmt: RETI4(reg) "# ret\n" -stmt: RETU4(reg) "# ret\n" -stmt: RETP4(reg) "# ret\n" -stmt: RETF4(freg) "# ret\n" -stmt: RETF8(freg) "# ret\n" -%% -static void progbeg(int argc, char *argv[]) { - int i; - - { - union { - char c; - int i; - } u; - u.i = 0; - u.c = 1; - swap = ((int)(u.i == 1)) != IR->little_endian; - } - parseflags(argc, argv); - for (i = 0; i < argc; i++) - if (strcmp(argv[i], "-p") == 0 || strcmp(argv[i], "-pg") == 0) - pflag = 1; - intreg[EAX] = mkreg("%%eax", EAX, 1, IREG); - intreg[EDX] = mkreg("%%edx", EDX, 1, IREG); - intreg[ECX] = mkreg("%%ecx", ECX, 1, IREG); - intreg[EBX] = mkreg("%%ebx", EBX, 1, IREG); - intreg[ESI] = mkreg("%%esi", ESI, 1, IREG); - intreg[EDI] = mkreg("%%edi", EDI, 1, IREG); - shortreg[EAX] = mkreg("%%ax", EAX, 1, IREG); - shortreg[ECX] = mkreg("%%cx", ECX, 1, IREG); - shortreg[EDX] = mkreg("%%dx", EDX, 1, IREG); - shortreg[EBX] = mkreg("%%bx", EBX, 1, IREG); - shortreg[ESI] = mkreg("%%si", ESI, 1, IREG); - shortreg[EDI] = mkreg("%%di", EDI, 1, IREG); - charreg[EAX] = mkreg("%%al", EAX, 1, IREG); - charreg[ECX] = mkreg("%%cl", ECX, 1, IREG); - charreg[EDX] = mkreg("%%dl", EDX, 1, IREG); - charreg[EBX] = mkreg("%%bl", EBX, 1, IREG); - for (i = 0; i < 8; i++) - fltreg[i] = mkreg("%d", i, 0, FREG); - charregw = mkwildcard(charreg); - shortregw = mkwildcard(shortreg); - intregw = mkwildcard(intreg); - fltregw = mkwildcard(fltreg); - - tmask[IREG] = (1<<EDI) | (1<<ESI) | (1<<EBX) - | (1<<EDX) | (1<<ECX) | (1<<EAX); - vmask[IREG] = 0; - tmask[FREG] = 0xff; - vmask[FREG] = 0; - - cseg = 0; - quo = mkreg("%%eax", EAX, 1, IREG); - quo->x.regnode->mask |= 1<<EDX; - rem = mkreg("%%edx", EDX, 1, IREG); - rem->x.regnode->mask |= 1<<EAX; - - stabprefix = ".LL"; -} - -static Symbol rmap(int opk) { - switch (optype(opk)) { - case B: case P: - return intregw; - case I: case U: - if (opsize(opk) == 1) - return charregw; - else if (opsize(opk) == 2) - return shortregw; - else - return intregw; - case F: - return fltregw; - default: - return 0; - } -} - -static Symbol prevg; - -static void globalend(void) { - if (prevg && prevg->type->size > 0) - print(".size %s,%d\n", prevg->x.name, prevg->type->size); - prevg = NULL; -} - -static void progend(void) { - globalend(); - (*IR->segment)(CODE); - print(".ident \"LCC: 4.1\"\n"); -} - -static void target(Node p) { - assert(p); - switch (specific(p->op)) { - case RSH+I: case RSH+U: case LSH+I: case LSH+U: - if (generic(p->kids[1]->op) != CNST - && !( generic(p->kids[1]->op) == INDIR - && specific(p->kids[1]->kids[0]->op) == VREG+P - && p->kids[1]->syms[RX]->u.t.cse - && generic(p->kids[1]->syms[RX]->u.t.cse->op) == CNST)) { - rtarget(p, 1, intreg[ECX]); - setreg(p, intreg[EAX]); - } - break; - case MUL+U: - setreg(p, quo); - rtarget(p, 0, intreg[EAX]); - break; - case DIV+I: case DIV+U: - setreg(p, quo); - rtarget(p, 0, intreg[EAX]); - rtarget(p, 1, intreg[ECX]); - break; - case MOD+I: case MOD+U: - setreg(p, rem); - rtarget(p, 0, intreg[EAX]); - rtarget(p, 1, intreg[ECX]); - break; - case ASGN+B: - rtarget(p, 0, intreg[EDI]); - rtarget(p->kids[1], 0, intreg[ESI]); - break; - case ARG+B: - rtarget(p->kids[0], 0, intreg[ESI]); - break; - case CVF+I: - setreg(p, intreg[EAX]); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - setreg(p, intreg[EAX]); - break; - case RET+I: case RET+U: case RET+P: - rtarget(p, 0, intreg[EAX]); - break; - } -} - -static void clobber(Node p) { - static int nstack = 0; - - assert(p); - nstack = ckstack(p, nstack); - switch (specific(p->op)) { - case ASGN+B: case ARG+B: - spill(1<<ECX | 1<<ESI | 1<<EDI, IREG, p); - break; - case EQ+F: case LE+F: case GE+F: case LT+F: case GT+F: case NE+F: - spill(1<<EAX, IREG, p); - break; - case CALL+F: - spill(1<<EDX | 1<<EAX | 1<<ECX, IREG, p); - break; - case CALL+I: case CALL+U: case CALL+P: case CALL+V: - spill(1<<EDX | 1<<ECX, IREG, p); - break; - } -} - -static void emit2(Node p) { - int op = specific(p->op); -#define preg(f) ((f)[getregnum(p->x.kids[0])]->x.name) - - if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movsbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVI+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movswl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (op == CVI+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movswl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 1) - print("movzbl %s,%s\n", preg(charreg), p->syms[RX]->x.name); - else if (op == CVU+I && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzwl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (op == CVU+U && opsize(p->op) == 4 && opsize(p->x.kids[0]->op) == 2) - print("movzwl %s,%s\n", preg(shortreg), p->syms[RX]->x.name); - else if (generic(op) == CVI || generic(op) == CVU || generic(op) == LOAD) { - char *dst = intreg[getregnum(p)]->x.name; - char *src = preg(intreg); - assert(opsize(p->op) <= opsize(p->x.kids[0]->op)); - if (dst != src) - print("movl %s,%s\n", src, dst); - } -} - -static void function(Symbol f, Symbol caller[], Symbol callee[], int n) { - int i; - - globalend(); - print(".align 16\n"); - print(".type %s,@function\n", f->x.name); - print("%s:\n", f->x.name); - print("pushl %%ebp\n"); - if (pflag) { - static int plab; - print("movl %%esp,%%ebp\n"); - (*IR->segment)(DATA); - print(".align 4\n.LP%d:\n.long 0\n", plab); - (*IR->segment)(CODE); - print("movl $.LP%d,%%edx\ncall mcount\n", plab); - plab++; - } - print("pushl %%ebx\n"); - print("pushl %%esi\n"); - print("pushl %%edi\n"); - print("movl %%esp,%%ebp\n"); - - usedmask[0] = usedmask[1] = 0; - freemask[0] = freemask[1] = ~0U; - offset = 16 + 4; - for (i = 0; callee[i]; i++) { - Symbol p = callee[i]; - Symbol q = caller[i]; - assert(q); - offset = roundup(offset, q->type->align); - p->x.offset = q->x.offset = offset; - p->x.name = q->x.name = stringf("%d", p->x.offset); - p->sclass = q->sclass = AUTO; - offset += roundup(q->type->size, 4); - } - assert(caller[i] == 0); - offset = maxoffset = 0; - gencode(caller, callee); - framesize = roundup(maxoffset, 4); - if (framesize > 0) - print("subl $%d,%%esp\n", framesize); - emitcode(); - print("movl %%ebp,%%esp\n"); - print("popl %%edi\n"); - print("popl %%esi\n"); - print("popl %%ebx\n"); - print("popl %%ebp\n"); - print("ret\n"); - { int l = genlabel(1); - print(".Lf%d:\n", l); - print(".size %s,.Lf%d-%s\n", f->x.name, l, f->x.name); - } -} - -static void defsymbol(Symbol p) { - if (p->scope >= LOCAL && p->sclass == STATIC) - p->x.name = stringf("%s.%d", p->name, genlabel(1)); - else if (p->generated) - p->x.name = stringf(".LC%s", p->name); - else if (p->scope == GLOBAL || p->sclass == EXTERN) - p->x.name = stringf("%s", p->name); - else - p->x.name = p->name; -} - -static void segment(int n) { - if (n == cseg) - return; - cseg = n; - if (cseg == CODE) - print(".text\n"); - else if (cseg == BSS) - print(".bss\n"); - else if (cseg == DATA || cseg == LIT) - print(".data\n"); -} - -static void defconst(int suffix, int size, Value v) { - if (suffix == I && size == 1) - print(".byte %d\n", v.u); - else if (suffix == I && size == 2) - print(".word %d\n", v.i); - else if (suffix == I && size == 4) - print(".long %d\n", v.i); - else if (suffix == U && size == 1) - print(".byte %d\n", v.u); - else if (suffix == U && size == 2) - print(".word %d\n", v.u); - else if (suffix == U && size == 4) - print(".long %d\n", v.u); - else if (suffix == P && size == 4) - print(".long %d\n", v.p); - else if (suffix == F && size == 4) { - float f = v.d; - print(".long %d\n", *(unsigned *)&f); - } else if (suffix == F && size == 8) { - double d = v.d; - unsigned *p = (unsigned *)&d; - print(".long %d\n.long %d\n", p[swap], p[!swap]); - } - else assert(0); -} - -static void defaddress(Symbol p) { - print(".long %s\n", p->x.name); -} - -static void defstring(int n, char *str) { - char *s; - - for (s = str; s < str + n; s++) - print(".byte %d\n", (*s)&0377); -} - -static void export(Symbol p) { - globalend(); - print(".globl %s\n", p->x.name); -} - -static void import(Symbol p) {} - -static void global(Symbol p) { - globalend(); - print(".align %d\n", p->type->align > 4 ? 4 : p->type->align); - if (!p->generated) { - print(".type %s,@%s\n", p->x.name, - isfunc(p->type) ? "function" : "object"); - if (p->type->size > 0) - print(".size %s,%d\n", p->x.name, p->type->size); - else - prevg = p; - } - if (p->u.seg == BSS) { - if (p->sclass == STATIC) - print(".lcomm %s,%d\n", p->x.name, p->type->size); - else - print(".comm %s,%d\n", p->x.name, p->type->size); - } else { - print("%s:\n", p->x.name); - } -} - -static void space(int n) { - if (cseg != BSS) - print(".space %d\n", n); -} - -Interface x86linuxIR = { - 1, 1, 0, /* char */ - 2, 2, 0, /* short */ - 4, 4, 0, /* int */ - 4, 4, 0, /* long */ - 4, 4, 0, /* long long */ - 4, 4, 1, /* float */ - 8, 4, 1, /* double */ - 8, 4, 1, /* long double */ - 4, 4, 0, /* T * */ - 0, 4, 0, /* struct; so that ARGB keeps stack aligned */ - 1, /* little_endian */ - 0, /* mulops_calls */ - 0, /* wants_callb */ - 1, /* wants_argb */ - 0, /* left_to_right */ - 0, /* wants_dag */ - 0, /* unsigned_char */ - 0, /* address */ - blockbeg, - blockend, - defaddress, - defconst, - defstring, - defsymbol, - emit, - export, - function, - gen, - global, - import, - 0, /* local */ - progbeg, - progend, - segment, - space, - stabblock, stabend, 0, stabinit, stabline, stabsym, stabtype, - {1, rmap, - 0, 0, 0, /* blkfetch, blkstore, blkloop */ - _label, - _rule, - _nts, - _kids, - _string, - _templates, - _isinstruction, - _ntname, - emit2, - 0, /* doarg */ - target, - clobber, - } -}; - -void x86linux_init(int argc, char *argv[]) { - static int inited; - extern Interface x86IR; - - if (inited) - return; - inited = 1; -#define xx(f) assert(!x86linuxIR.f); x86linuxIR.f = x86IR.f - xx(address); - xx(local); - xx(x.blkfetch); - xx(x.blkstore); - xx(x.blkloop); - xx(x.doarg); -#undef xx -} |