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)) : ""); }
static void prelabel(Node p) { if (p == NULL) return; prelabel(p->kids[0]); prelabel(p->kids[1]); if (NeedsReg[opindex(p->op)]) setreg(p, (*IR->x.rmap)(opkind(p->op))); switch (generic(p->op)) { case ADDRF: case ADDRL: if (p->syms[0]->sclass == REGISTER) p->op = VREG+P; break; case INDIR: if (p->kids[0]->op == VREG+P) setreg(p, p->kids[0]->syms[0]); break; case ASGN: if (p->kids[0]->op == VREG+P) rtarget(p, 1, p->kids[0]->syms[0]); break; case CVI: case CVU: case CVP: if (optype(p->op) != F && opsize(p->op) <= p->syms[0]->u.c.v.i) p->op = LOAD + opkind(p->op); break; } (IR->x.target)(p); }
/* static void I(asmcode)(char * s , Symbol ss[] ) { write(2, "EMIT ASM", strlen("EMIT ASM")); print("asm\n"); } */ static void I(emit)(Node p) { for (; p; p = p->link) { dumptree(p); if (generic(p->op) == CALL) { print("DISCARD%s%d\n", " "/*suffixes[optype(p->op)]*/, opsize(p->op)); } } }
static void spillr(Symbol r, Node here) { int i; Symbol tmp; Node p = r->x.lastuse; assert(p); while (p->x.prevuse) assert(r == p->syms[RX]), p = p->x.prevuse; assert(p->x.registered && !readsreg(p)); tmp = newtemp(AUTO, optype(p->op), opsize(p->op)); genspill(r, p, tmp); for (p = here->x.next; p; p = p->x.next) for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) { Node k = p->x.kids[i]; if (k->x.registered && k->syms[RX] == r) genreload(p, tmp, i); } putreg(r); }
static void emit2(Node p) { char* name; char* offset; int localoffset; int argoffset; long intval; long double fltval; int op = specific(p->op); int opsz = opsize(p->op); int i, j, k; Symbol s; switch (op) { case CNST + F: fltval = p->syms[0]->u.c.v.d; if (fltval < 0) emithex((short) (fltval * 256)); else printf("%d", (short) (fltval * 256)); break; case CNST + I: intval = p->syms[0]->u.c.v.i; if (intval < 0) emithex((short) intval); else print("%d", intval); break; case ARG + F: case ARG + I: case ARG + U: case ARG + P: if (p->x.argno > 2) { assert(maxargoffset); if (p->x.argno == 3) print("SET PEEK, "); else print("SET I, SP\nSET [%d+I], ", p->x.argno - 3); emitasm(p->kids[0], _bval_NT); print("\n"); } break; case CALL + F: case CALL + I: case CALL + U: case CALL + P: case CALL + V: assert(p->kids[0]); argoffset = p->syms[0]->u.c.v.i; print("JSR "); emitasm(p->kids[0], _addr_NT); print("\n"); if (argoffset > 3) popstack(argoffset - 3, "popping arguments from stack"); break; case ADDRL + P: localoffset = p->syms[0]->x.offset + maxoffset; if (p->x.inst) { if (localoffset) print("SET %s, %d\nADD %s, J\n", p->syms[RX]->name, localoffset, p->syms[RX]->name); else print("SET %s, J\n", p->syms[RX]->name); } else { if (localoffset) print("%d+J", localoffset); else print("J"); } break; case ADDRF + P: if (p->syms[0]->x.offset) print("%d+J", p->syms[0]->x.offset); else print("J"); break; case ASGN + B: assert(p->kids[0]); assert(p->kids[1]); assert(p->kids[1]->kids[0]); print(";starting block copy (%s %s %d)\n", p->kids[0]->syms[RX]->x.name, p->kids[1]->kids[0]->syms[RX]->x.name, p->syms[0]->u.c.v.i); for (i = 0; i < p->syms[0]->u.c.v.i; i++) { if (i == 0) print("SET [%s], [%s]\n", p->kids[0]->syms[RX]->x.name, p->kids[1]->kids[0]->syms[RX]->x.name); else print("SET [%d+%s], [%d+%s]\n", i, p->kids[0]->syms[RX]->x.name, i, p->kids[1]->kids[0]->syms[RX]->x.name); } break; /* case INDIR+P: if (p->kids[0]) { s = p->kids[0]->syms[0]; } else { s = p->syms[0]; } assert(s->x.name); debug(fprintf(stderr, "addrg emit2 %s->%s\n", s->x.name, p->syms[RX]->name)); name = (char*)malloc(strlen(s->x.name)); offset = (char*)malloc(strlen(s->x.name)); for( i = 0; s->x.name[i]; i++ ) { if ( s->x.name[i] == '+' ) break; name[i] = s->x.name[i]; } name[i+1] = 0; if (s->x.name[i] == '+') { i++; for( j = 0; s->x.name[i+j]; j++ ) { offset[j] = s->x.name[i+j]; } offset[i+j+1] = 0; print("SET %s, %s\nADD %s, %s\nSET %s, [%s]\n", p->syms[RX]->name, name, p->syms[RX]->name, offset, p->syms[RX]->name, p->syms[RX]->name); } else { print("SET %s, [", p->syms[RX]->name); emithex(atoi(s->x.name)); print("]\n"); } break; */ } }
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; }