📄 pass2.c
字号:
int *uid = Seq_remlo(in->v.rcc_Function.callee);
callee[i] = uid2symbol(*uid);
free(uid);
}
callee[i] = NULL;
Seq_free(&in->v.rcc_Function.callee);
cfunc->u.f.callee = callee;
cfunc->defined = 1;
/*
Initialize the code list,
traverse the interfaces inside the function;
each call appends code list entries.
*/
codelist = &codehead;
codelist->next = NULL;
n = Seq_length(in->v.rcc_Function.codelist);
for (i = 0; i < n; i++)
interface(Seq_remlo(in->v.rcc_Function.codelist));
Seq_free(&in->v.rcc_Function.codelist);
/*
Call the back end,
Wrap-up.
*/
exitscope();
(*IR->function)(cfunc, caller, callee, in->v.rcc_Function.ncalls);
cfunc = NULL;
labels = NULL;
}
static struct block {
Code begin;
struct block *prev;
} *blockstack = NULL;
static void doBlockbeg(rcc_interface_ty in) {
struct block *b;
Code cp = code(Blockbeg);
enterscope();
cp->u.block.level = level;
cp->u.block.locals = newarray(1, sizeof *cp->u.block.locals, FUNC);
cp->u.block.locals[0] = NULL;
cp->u.block.identifiers = NULL;
cp->u.block.types = NULL;
NEW(b, FUNC);
b->begin = cp;
b->prev = blockstack;
blockstack = b;
}
static void doBlockend(rcc_interface_ty in) {
assert(blockstack);
code(Blockend)->u.begin = blockstack->begin;
blockstack = blockstack->prev;
exitscope();
}
static Node visit(rcc_node_ty node) {
int op;
Node left = NULL, right = NULL, p = NULL;
Symbol sym = NULL;
switch (node->kind) {
#define T(x) rcc_##x##_enum
case T(CSE): {
Symbol q = uid2symbol(node->v.rcc_CSE.uid);
assert(q->temporary);
q->u.t.cse = p = visit(node->v.rcc_CSE.node);
break;
}
case T(CNST): {
Value v;
v.i = node->v.rcc_CNST.value;
sym = constant(btot(node->suffix, node->size), v);
op = CNST;
break;
}
case T(CNSTF): {
Value v;
unsigned *p = (unsigned *)&v.d;
p[swap] = node->v.rcc_CNSTF.value->msb;
p[1-swap] = node->v.rcc_CNSTF.value->lsb;
sym = constant(btot(node->suffix, node->size), v);
free(node->v.rcc_CNSTF.value);
op = CNST;
break;
}
case T(ARG):
p = newnode(ARG + node->suffix + sizeop(node->size),
visit(node->v.rcc_ARG.left), NULL,
intconst(node->v.rcc_ARG.len));
p->syms[1] = intconst(node->v.rcc_ARG.align);
break;
case T(ASGN):
p = newnode(ASGN + node->suffix + sizeop(node->size),
visit(node->v.rcc_ASGN.left), visit(node->v.rcc_ASGN.right),
intconst(node->v.rcc_ASGN.len));
p->syms[1] = intconst(node->v.rcc_ASGN.align);
break;
case T(CVT):
op = node->v.rcc_CVT.op;
left = visit(node->v.rcc_CVT.left);
sym = intconst(node->v.rcc_CVT.fromsize);
break;
case T(CALL):
op = CALL;
left = visit(node->v.rcc_CALL.left);
NEW0(sym, FUNC);
sym->type = uid2type(node->v.rcc_CALL.type);
break;
case T(CALLB):
op = CALL;
left = visit(node->v.rcc_CALLB.left);
right = visit(node->v.rcc_CALLB.right);
NEW0(sym, FUNC);
sym->type = uid2type(node->v.rcc_CALLB.type);
break;
case T(RET):
op = RET;
break;
case T(ADDRG):
op = ADDRG;
sym = uid2symbol(node->v.rcc_ADDRG.uid);
break;
case T(ADDRL):
op = ADDRL;
sym = uid2symbol(node->v.rcc_ADDRG.uid);
break;
case T(ADDRF):
op = ADDRF;
sym = uid2symbol(node->v.rcc_ADDRG.uid);
break;
case T(Unary):
op = node->v.rcc_Unary.op;
left = visit(node->v.rcc_Unary.left);
break;
case T(Binary):
op = node->v.rcc_Binary.op;
left = visit(node->v.rcc_Binary.left);
right = visit(node->v.rcc_Binary.right);
break;
case T(Compare):
op = node->v.rcc_Compare.op;
left = visit(node->v.rcc_Compare.left);
right = visit(node->v.rcc_Compare.right);
sym = findlabel(node->v.rcc_Compare.label);
break;
case T(LABEL):
op = LABEL;
sym = findlabel(node->v.rcc_LABEL.label);
break;
case T(BRANCH):
op = JUMP;
left = newnode(ADDRG+P+sizeop(voidptype->size), NULL, NULL, findlabel(node->v.rcc_BRANCH.label));
break;
#undef T
default: assert(0);
}
if (p == NULL)
p = newnode(op + node->suffix + sizeop(node->size), left, right, sym);
free(node);
return p;
}
static void doForest(rcc_interface_ty in) {
Node *tail = &code(Gen)->u.forest;
int i, n = Seq_length(in->v.rcc_Forest.nodes);
for (i = 0; i < n; i++) {
*tail = visit(Seq_remlo(in->v.rcc_Forest.nodes));
assert(*tail);
tail = &(*tail)->link;
}
*tail = NULL;
Seq_free(&in->v.rcc_Forest.nodes);
}
int main(int argc, char *argv[]) {
int i, version;
float stamp = (assert(strstr(rcsid, ",v")), strtod(strstr(rcsid, ",v")+2, NULL))
;
char *infile = NULL, *outfile = NULL;
rcc_program_ty pickle;
for (i = 1; i < argc; i++)
if (*argv[i] != '-' || strcmp(argv[i], "-") == 0) {
if (infile == NULL)
infile = argv[i];
else if (outfile == NULL)
outfile = argv[i];
}
if (infile != NULL && strcmp(infile, "-") != 0
&& freopen(infile, "rb", stdin) == NULL) {
fprint(stderr, "%s: can't read `%s'\n", argv[0], infile);
exit(EXIT_FAILURE);
}
#if WIN32
else
_setmode(_fileno(stdin), _O_BINARY);
#endif
if (outfile != NULL && strcmp(outfile, "-") != 0
&& freopen(outfile, "w", stdout) == NULL) {
fprint(stderr, "%s: can't write `%s'\n", argv[0], outfile);
exit(EXIT_FAILURE);
}
version = read_int(stdin);
assert(version/100 == (int)stamp);
pickle = rcc_read_program(stdin);
argc = pickle->argc;
argv = newarray(argc + 1, sizeof *argv, PERM);
{
for (i = 0; i < argc; i++) {
string_ty *arg = Seq_remlo(pickle->argv);
argv[i] = (char *)arg->str;
free(arg);
}
argv[i] = NULL;
assert(i == argc);
Seq_free(&pickle->argv);
}
for (i = argc - 1; i > 0; i--)
if (strncmp(argv[i], "-target=", 8) == 0)
break;
if (i > 0) {
int j;
for (j = 0; bindings[j].name && bindings[j].ir; j++)
if (strcmp(&argv[i][8], bindings[j].name) == 0) {
IR = bindings[j].ir;
break;
}
}
if (!IR) {
fprint(stderr, "%s: unknown target", argv[0]);
if (i > 0)
fprint(stderr, " `%s'", &argv[i][8]);
fprint(stderr, "; must specify one of\n");
for (i = 0; bindings[i].name; i++)
fprint(stderr, "\t-target=%s\n", bindings[i].name);
exit(EXIT_FAILURE);
}
IR->wants_dag = 0; /* pickle's hold trees */
init(argc, argv);
genlabel(pickle->nlabels);
level = GLOBAL;
{
int i, count;
nuids = pickle->nuids;
items = newarray(nuids, sizeof *items, PERM);
itemmap = newarray(nuids, sizeof *items, PERM);
for (i = 0; i < nuids; i++) {
itemmap[i] = NULL;
items[i] = NULL;
}
(*IR->progbeg)(argc, argv);
count = Seq_length(pickle->items);
for (i = 0; i < count; i++) {
rcc_item_ty item = Seq_remlo(pickle->items);
int uid = item->uid;
assert(uid >= 0 && uid < nuids);
assert(items[uid] == NULL);
items[uid] = item;
}
Seq_free(&pickle->items);
#define xx(s) assert(rcc_##s##_enum < sizeof doX/sizeof doX[0] && doX[rcc_##s##_enum]==0); \
doX[rcc_##s##_enum] = do##s;
xx(Export)
xx(Import)
xx(Global)
xx(Local)
xx(Address)
xx(Segment)
xx(Defaddress)
xx(Deflabel)
xx(Defconst)
xx(Defconstf)
xx(Defstring)
xx(Space)
xx(Function)
xx(Blockbeg)
xx(Blockend)
xx(Forest)
#undef xx
count = Seq_length(pickle->interfaces);
for (i = 0; i < count; i++)
interface(Seq_remlo(pickle->interfaces));
Seq_free(&pickle->interfaces);
free(pickle);
(*IR->progend)();
}
deallocate(PERM);
return errcnt > 0;
}
/* main_init - process program arguments */
void main_init(int argc, char *argv[]) {
int i;
static int inited;
if (inited)
return;
inited = 1;
for (i = 1; i < argc; i++)
if (strcmp(argv[i], "-g") == 0 || strcmp(argv[i], "-g2") == 0)
glevel = 2;
else if (strcmp(argv[i], "-w") == 0)
wflag++;
else if (strcmp(argv[i], "-v") == 0) {
fprint(stderr, "%s %s\n", argv[0], rcsid);
verbose++;
} else if (strncmp(argv[i], "-errout=", 8) == 0) {
FILE *f = fopen(argv[i]+8, "w");
if (f == NULL) {
fprint(stderr, "%s: can't write errors to `%s'\n", argv[0], argv[i]+8);
exit(EXIT_FAILURE);
}
fclose(f);
f = freopen(argv[i]+8, "w", stderr);
assert(f);
} else if (strncmp(argv[i], "-e", 2) == 0) {
int x;
if ((x = strtol(&argv[i][2], NULL, 0)) > 0)
errlimit = x;
}
}
void init(int argc, char *argv[]) {
{extern void main_init(int, char *[]); main_init(argc, argv);}
{extern void prof_init(int, char *[]); prof_init(argc, argv);}
{extern void trace_init(int, char *[]); trace_init(argc, argv);}
{extern void type_init(int, char *[]); type_init(argc, argv);}
{extern void x86linux_init(int, char *[]); x86linux_init(argc, argv);}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -