newlines fixed

This commit is contained in:
Zachary Slater 2005-08-26 17:39:27 +00:00
parent 7830940da6
commit 59cce31e75
1121 changed files with 717537 additions and 717537 deletions

File diff suppressed because it is too large Load diff

View file

@ -1,94 +1,94 @@
#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
#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

File diff suppressed because it is too large Load diff

View file

@ -1,399 +1,399 @@
#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 */
}
}
#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 */
}
}

View file

@ -1,23 +1,23 @@
#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
};
#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
};

View file

@ -1,365 +1,365 @@
#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) */
};
#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) */
};

File diff suppressed because it is too large Load diff

View file

@ -1,102 +1,102 @@
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
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

File diff suppressed because it is too large Load diff

View file

@ -1,210 +1,210 @@
%{
#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);
}
%{
#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);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,137 +1,137 @@
#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);
}
#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);
}

View file

@ -1,28 +1,28 @@
#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);
}
}
#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);
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,318 +1,318 @@
#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;
}
#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;
}

View file

@ -1,8 +1,8 @@
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);}
{extern void x86linux_init(int, char *[]); x86linux_init(argc, argv);}
}
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);}
{extern void x86linux_init(int, char *[]); x86linux_init(argc, argv);}
}

View file

@ -1,134 +1,134 @@
#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;
}
#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;
}

File diff suppressed because it is too large Load diff

View file

@ -1,56 +1,56 @@
#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;
}
#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;
}

View file

@ -1,225 +1,225 @@
#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);
}
#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);
}

File diff suppressed because it is too large Load diff

View file

@ -1,74 +1,74 @@
#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)
};
#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)
};

View file

@ -1,134 +1,134 @@
#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';
}
#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';
}

File diff suppressed because it is too large Load diff

View file

@ -1,227 +1,227 @@
#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);
}
}
}
#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);
}
}
}

View file

@ -1,276 +1,276 @@
/* 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;
}
/* 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;
}

View file

@ -1,70 +1,70 @@
-- 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)
}
-- 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)
}

View file

@ -1,51 +1,51 @@
#!/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
#!/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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,330 +1,330 @@
#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++);
if (IR == &sparcIR)
print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev);
else {
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;
}
if (IR == &sparcIR)
print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y);
else {
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);
}
#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++);
if (IR == &sparcIR)
print(".stabd 0x%x,0,%d\n", brace == '{' ? N_LBRAC : N_RBRAC, lev);
else {
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;
}
if (IR == &sparcIR)
print(".stabd 0x%x,0,%d\n", N_SLINE, cp->y);
else {
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);
}

View file

@ -1,113 +1,113 @@
/* @(#)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
/* @(#)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

File diff suppressed because it is too large Load diff

View file

@ -1,122 +1,122 @@
#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;
}
}
#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;
}
}

View file

@ -1,315 +1,315 @@
#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) {
char buf[50];
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;
}
#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) {
char buf[50];
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;
}

View file

@ -1,494 +1,494 @@
#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("&amp;");
else if (*s == '<' && html)
print("&lt;");
else if (*s == '>' && html)
print("&lt;");
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)
};
#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("&amp;");
else if (*s == '<' && html)
print("&lt;");
else if (*s == '>' && html)
print("&lt;");
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)
};

View file

@ -1,133 +1,133 @@
/*
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
/*
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

View file

@ -1,180 +1,180 @@
#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;
}
}
#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;
}
}

View file

@ -1,223 +1,223 @@
#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);
}
#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);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff