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 Tree addrtree(Tree e, long n, Type ty) { Symbol p = e->u.sym, q; if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) NEW0(q, PERM); else NEW0(q, FUNC); q->name = stringd(genlabel(1)); q->sclass = p->sclass; q->scope = p->scope; assert(isptr(ty) || isarray(ty)); q->type = isptr(ty) ? ty->type : ty; q->temporary = p->temporary; q->generated = p->generated; q->addressed = p->addressed; q->computed = 1; q->defined = 1; q->ref = 1; assert(IR->address); if (p->scope == GLOBAL || p->sclass == STATIC || p->sclass == EXTERN) { if (p->sclass == AUTO) q->sclass = STATIC; (*IR->address)(q, p, n); } else { Code cp; addlocal(p); cp = code(Address); cp->u.addr.sym = q; cp->u.addr.base = p; cp->u.addr.offset = n; } e = tree(e->op, ty, NULL, NULL); e->u.sym = q; return e; }
void mkauto(Symbol p) { assert(p->sclass == AUTO); offset = roundup(offset + p->type->size, p->type->align); p->x.offset = -offset; p->x.name = stringd(-offset); }
//function(..) module saved jan 1 2013 as part of prep for scrt integration static void function(Symbol f, Symbol caller[], Symbol callee[], int ncalls) { int i, saved, sizefsave, sizeisave, varargs; Symbol r, argregs[NUM_ARG_REGS]; usedmask[0] = usedmask[1] = 0; freemask[0] = freemask[1] = ~(unsigned)0; offset = maxoffset = maxargoffset = 0; for (i = 0; callee[i]; i++) //find last argument ; varargs = variadic(f->type) //see if variable arguments by type or by name of final argument || i > 0 && strcmp(callee[i-1]->name, "va_alist") == 0; for (i = 0; callee[i]; i++) { //for each argument Symbol p = callee[i]; Symbol q = caller[i]; assert(q); offset = roundup(offset, q->type->align); //calculate the offset from the caller's sp p->x.offset = q->x.offset = offset; p->x.name = q->x.name = stringd(offset); r = argreg(i, offset, optype(ttob(q->type)), q->type->size, optype(ttob(caller[0]->type))); if (i < NUM_ARG_REGS) argregs[i] = r; offset = roundup(offset + q->type->size, 2); //i dunno if (varargs) p->sclass = AUTO; //variable args are always auto? else if (r && ncalls == 0 && //I dunno !isstruct(q->type) && !p->addressed && !(isfloat(q->type) && r->x.regnode->set == IREG)) { p->sclass = q->sclass = REGISTER; askregvar(p, r); assert(p->x.regnode && p->x.regnode->vbl == p); q->x = p->x; q->type = p->type; } else if (askregvar(p, rmap(ttob(p->type))) && r != NULL && (isint(p->type) || p->type == q->type)) { assert(q->sclass != REGISTER); p->sclass = q->sclass = REGISTER; q->type = p->type; } } assert(!caller[i]); //done with arguments, their individual offsets and maxargoffset have been set offset = 0; gencode(caller, callee); if (ncalls) //prepare to save return address if necessary(i.e. we do calls of our own) usedmask[IREG] |= ((unsigned)1)<<REG_RETADDR; usedmask[IREG] &= INT_CALLEE_SAVE; //limit saving to those we're responsible for usedmask[FREG] &= 0xfff00000; maxargoffset = roundup(maxargoffset, usedmask[FREG] ? 8 : 2); if (ncalls && maxargoffset < NUM_ARG_REGS*2) maxargoffset = NUM_ARG_REGS*2; sizefsave = 4*bitcount(usedmask[FREG]); //space needed to save the float regs sizeisave = 2*bitcount(usedmask[IREG]); //space needed to save the int regs framesize = roundup(maxargoffset + sizefsave //space for outgoing arguments, space for saving floats, + sizeisave + maxoffset, 2); //space for saving ints, space for locals //segment(CODE); //printf("\talign 16\n"); printf("%s:\n", f->x.name); i = maxargoffset + sizefsave - framesize; //I dunno but it's -v and it's never used! if (framesize > 0) print("\talu2I sp,sp,%d,smi,smbi\n", framesize); saved = maxargoffset; /space needed for outgoing arguments