From fb3e9ae04d86cd7e80e8d4db3c1c444bfe7f7168 Mon Sep 17 00:00:00 2001 From: lemon Date: Mon, 5 Jun 2023 15:57:57 +0200 Subject: encode calls a different way in the IR --- abi0.c | 153 +++++++++++++++++++++++++++-------------------------------- amd64/sysv.c | 2 +- ir.c | 21 ++------ ir.h | 15 +++--- irdump.c | 73 +++++++++++++++------------- op.def | 1 + parse.c | 33 +++++-------- regalloc.c | 28 +++++++---- test/test.c | 10 ++-- 9 files changed, 158 insertions(+), 178 deletions(-) diff --git a/abi0.c b/abi0.c index c3673e4..3547f64 100644 --- a/abi0.c +++ b/abi0.c @@ -2,6 +2,9 @@ /** This pass adds in ABI arguments/returns register mappings ** and lowers aggregate params/args/returns into scalars + ** + ** invariant: all `call` instructions when doing this pass shall be preceded by + ** exactly narg `arg` instructions with no other instructions in between **/ struct abiargsvec { vec_of(struct abiarg); }; @@ -103,25 +106,29 @@ patchparam(struct function *fn, int *start, int param, int tydat, int to, struct } static int -patcharg(union ref newargs[2], union irtype newtyps[2], struct block *blk, int *icall, - struct call *call, int arg, int nabi, struct abiarg abi[2]) +patcharg(struct block *blk, int *icall, struct call *call, + int argidx, int nabi, struct abiarg abi[2]) { - if (call->typs[arg].isagg) { - /* originally aggregate argument */ + int arginst = *icall - (call->narg - argidx); + struct instr *arg = &instrtab[blk->ins.p[arginst]]; + assert(arg->op == Oarg && arg->l.t == RTYPE); + if (ref2type(arg->l).isagg) { + /* aggregate argument */ if (abi[0].ty.isagg /* aggregate in stack */ || abi[0].ty.cls == KPTR) /* aggregate by pointer */ { - newargs[0] = call->args[arg]; - newtyps[0] = call->typs[arg]; + return 1; } else { /* aggregate in registers */ - union ref src = call->args[arg]; + union ref src = arg->r; /* deconstruct into * %a = load* %x * (%b = load* %x + N) */ + delinstr(blk, arginst); for (int i = 0; i < nabi; ++i) { /* XXX this can generate unaligned loads */ struct instr ins = {0}; + union ref temp; switch (ins.cls = abi[i].ty.cls) { default: assert(0); case KI4: ins.op = Oloadu4; break; @@ -132,20 +139,19 @@ patcharg(union ref newargs[2], union irtype newtyps[2], struct block *blk, int * if (i == 0) ins.l = src; else - ins.l = insertinstr(blk, (*icall)++ - 1, + ins.l = insertinstr(blk, arginst++, mkinstr(Oadd, KPTR, src, mkref(RICON, cls2siz[abi[0].ty.cls]))); - newtyps[i] = (union irtype) { .cls = ins.cls }; - newargs[i] = insertinstr(blk, (*icall)++ - 1, ins); + temp = insertinstr(blk, arginst++, ins); + insertinstr(blk, arginst++, mkarginstr(abi[i].ty, temp)); } + *icall += arginst - (call->narg - argidx); return nabi; } } else { /* normal scalar argument */ - newargs[0] = call->args[arg]; - newtyps[0] = call->typs[arg]; + return 1; } - return 1; } void @@ -215,10 +221,6 @@ abi0(struct function *fn) for (int iinstr = 0; iinstr < blk->ins.n; ++iinstr) { struct instr *ins = &instrtab[blk->ins.p[iinstr]]; struct call *call = &calltab.p[ins->r.i]; - static union ref newargsbuf[32]; - static union irtype newtypsbuf[32]; - vec_of(union ref) newargs = VINIT(newargsbuf, arraylength(newargsbuf)); - vec_of(union irtype) newtyps = VINIT(newtypsbuf, arraylength(newtypsbuf)); bool structbyval; int vararg; @@ -226,58 +228,56 @@ abi0(struct function *fn) vararg = call->vararg; vinit(&abiargs, abiargsbuf, arraylength(abiargsbuf)); - if (!(structbyval = call->sret)) - for (int i = 0; i < call->narg; ++i) - if ((structbyval = call->typs[i].isagg)) + if (!(structbyval = call->ret.isagg)) + for (int i = iinstr - call->narg; i < iinstr; ++i) + if ((structbyval = ref2type(instrtab[blk->ins.p[i]].l).isagg)) break; ni = nf = ns = 0; memset(call->abiret, 0, sizeof call->abiret); - if (call->sret) { - union irtype retty = call->typs[call->narg]; + if (call->ret.isagg) { /* adjust struct return */ + union ref temp; + union irtype retty = call->ret; + struct instr alloca = { .cls = KPTR }; + struct typedata *td = &typedata[retty.dat]; int ret = abiret(call->abiret, &abiargs, &ni, retty); - if (retty.isagg) { - union ref temp; - struct instr alloca = { .cls = KPTR }; - struct typedata *td = &typedata[retty.dat]; - sretarghidden = ni == 0; - alloca.op = Oalloca8 + (td->align == 16); - alloca.l = mkref(RICON, td->align == 16 ? 1 : td->siz / 8); - temp = insertinstr(blk, iinstr++, alloca); - replref(fn, blk, iinstr, mkref(RTMP, ins - instrtab), temp); - if (!ret) { /* hidden pointer argument */ - vpush(&newargs, temp); - vpush(&newtyps, (union irtype) {.cls = KPTR}); - ins->cls = 0; - } else { - union ref call2r; - int to = iinstr + 1; - assert(in_range(ret, 1, 2)); - ins->cls = call->abiret[0].ty.cls; - if (ret == 2) - call2r = insertinstr(blk, to++, mkinstr(Ocall2r, call->abiret[1].ty.cls, - mkref(RTMP, ins - instrtab))); - for (int i = 0; i < ret; ++i) { - uchar cls; - struct instr store = {0}; - /* XXX this can generate unaligned stores */ - switch (cls = call->abiret[i].ty.cls) { - default: assert(0); - case KF4: case KI4: store.op = Ostore4; break; - case KI8: case KF8: store.op = Ostore8; break; - } - if (i == 0) { - store.l = temp; - store.r = mkref(RTMP, ins - instrtab); - } else { - store.l = insertinstr(blk, to++, - mkinstr(Oadd, KPTR, temp, - mkref(RICON, cls2siz[call->abiret[0].ty.cls]))); - store.r = call2r; - } - insertinstr(blk, to++, store); + sretarghidden = ni == 0; + alloca.op = Oalloca8 + (td->align == 16); + alloca.l = mkref(RICON, td->align == 16 ? 1 : td->siz / 8); + temp = insertinstr(blk, iinstr++ - call->narg, alloca); + replref(fn, blk, iinstr, mkref(RTMP, ins - instrtab), temp); + if (!ret) { /* hidden pointer argument */ + insertinstr(blk, iinstr++ - call->narg, + mkarginstr((union irtype){.cls = KPTR}, temp)); + ins->cls = 0; + } else { /* aggregate returned in regs */ + union ref call2r; + int to = iinstr + 1; + assert(in_range(ret, 1, 2)); + ins->cls = call->abiret[0].ty.cls; + if (ret == 2) + call2r = insertinstr(blk, to++, mkinstr(Ocall2r, call->abiret[1].ty.cls, + mkref(RTMP, ins - instrtab))); + for (int i = 0; i < ret; ++i) { + uchar cls; + struct instr store = {0}; + /* XXX this can generate unaligned stores */ + switch (cls = call->abiret[i].ty.cls) { + default: assert(0); + case KF4: case KI4: store.op = Ostore4; break; + case KI8: case KF8: store.op = Ostore8; break; } + if (i == 0) { + store.l = temp; + store.r = mkref(RTMP, ins - instrtab); + } else { + store.l = insertinstr(blk, to++, + mkinstr(Oadd, KPTR, temp, + mkref(RICON, cls2siz[call->abiret[0].ty.cls]))); + store.r = call2r; + } + insertinstr(blk, to++, store); } } } else if (ins->cls) { @@ -286,35 +286,20 @@ abi0(struct function *fn) } for (int i = 0; i < call->narg; ++i) { - union irtype pty = call->typs[i]; + union irtype pty = ref2type(instrtab[blk->ins.p[iinstr - call->narg + i]].l); int thisi = sretarghidden + ni + nf + ns; int first = abiargs.n; int ret = abiarg(&abiargs, &ni, &nf, &ns, pty); - union ref argss[2]; - union irtype typss[2]; - ret = patcharg(argss, typss, blk, &iinstr, call, i, ret, &abiargs.p[first]); - if (structbyval) { - vpushn(&newargs, argss, ret); - vpushn(&newtyps, typss, ret); - } + ret = patcharg(blk, &iinstr, call, i, ret, &abiargs.p[first]); if (call->vararg == i) vararg = thisi; } - call->sret = 0; + if (call->ret.isagg) call->ret = (union irtype){0}; call->vararg = vararg; - if (structbyval && newargs.n != call->narg) { - call->args = alloc(&fn->arena, newargs.n * (sizeof *newargs.p + sizeof *newtyps.p), 0); - call->typs = (union irtype *)((char *)call->args + newargs.n * sizeof *newargs.p); - } - memcpy(call->typs, newtyps.p, newtyps.n * sizeof *call->typs); - if (structbyval) - memcpy(call->args, newargs.p, newargs.n * sizeof *call->args); call->abiargregs = alloc(&fn->arena, abiargs.n * sizeof *call->abiargregs, 0); for (int i = 0; i < abiargs.n; ++i) call->abiargregs[i] = abiargs.p[i].reg; call->narg = abiargs.n; vfree(&abiargs); - vfree(&newargs); - vfree(&newtyps); } /* adjust returns */ @@ -344,10 +329,10 @@ abi0(struct function *fn) /* aggregate return (arg[0] is pointer to return value) */ if (rvovar == -1) { /* blit %sret, %arg */ - union ref args[2] = { sret, blk->jmp.arg[0] }; - union irtype typ[2] = { mkirtype(fn->retty) }; - typ[1] = typ[0]; - insertinstr(blk, blk->ins.n, mkintrin(fn, INstructcopy, 0, 2, args, typ)); + union irtype typ = mkirtype(fn->retty); + insertinstr(blk, blk->ins.n, mkarginstr(typ, sret)); + insertinstr(blk, blk->ins.n, mkarginstr(typ, blk->jmp.arg[0])); + insertinstr(blk, blk->ins.n, mkintrin(fn, INstructcopy, 0, 2)); } else assert(blk->jmp.arg[0].bits == mkref(RTMP, rvovar).bits); if (fn->abiret[0].ty.cls) blk->jmp.arg[0] = rvovar == -1 ? sret : mkref(RTMP, rvovar); else memset(blk->jmp.arg, 0, sizeof blk->jmp.arg); diff --git a/amd64/sysv.c b/amd64/sysv.c index e2f5b7b..f909067 100644 --- a/amd64/sysv.c +++ b/amd64/sysv.c @@ -48,7 +48,7 @@ classify(uchar cls[2], const struct typedata *td, uint off) if (!cls[(fld->off + off)/8]) cls[(fld->off + off)/8] = KF8; } else { /* INTEGER */ - assert(isint(fld->t) || chld.t == TYPTR); + assert(isint(fld->t) || fld->t.t == TYPTR); cls[(fld->off + off)/8] = KI8; } } diff --git a/ir.c b/ir.c index 96877e2..1d937cf 100644 --- a/ir.c +++ b/ir.c @@ -119,8 +119,7 @@ conputdat(struct irdat *dat, uint off, enum typetag t, const void *src) union irtype mkirtype(union type t) { - assert(t.t != TYVOID); - if (isscalar(t)) return (union irtype) { .cls = type2cls[t.t] }; + if (t.t == TYVOID || isscalar(t)) return (union irtype) { .cls = type2cls[t.t] }; assert(isagg(t)); return (union irtype) { .isagg = 1, .dat = t.dat }; } @@ -179,17 +178,10 @@ mkalloca(uint siz, uint align) } union ref -mkcallarg(struct function *fn, bool sret, uint narg, int vararg, union ref *args, union irtype *typs) +mkcallarg(struct function *fn, union irtype ret, uint narg, int vararg) { - struct call call = { .sret=sret, .narg=narg, .vararg=vararg }; - + struct call call = { .ret=ret, .narg=narg, .vararg=vararg }; assert((long) vararg <= narg); - if (narg) { - call.args = alloc(&fn->arena, narg*sizeof *args + (narg+sret)*sizeof(union irtype), 0); - call.typs = (union irtype *)((char *)call.args + narg*sizeof *args); - memcpy(call.args, args, narg*sizeof *args); - memcpy(call.typs, typs, (narg+sret)*sizeof *typs); - } vpush(&calltab, call); return mkref(RMORE, calltab.n-1); } @@ -359,13 +351,6 @@ replref(struct function *fn, struct block *blk, int i0, union ref from, union re for (int i = 0; i < 2; ++i) { union ref *r = &(&ins->l)[i]; if (r->bits == from.bits) *r = to; - else if (r->t == RMORE) { - struct call *call = &calltab.p[r->i]; - assert(ins->op == Ocall || ins->op == Ointrin); - for (int i = 0; i < call->narg; ++i) - if (call->args[i].bits == from.bits) - call->args[i] = to; - } } } i0 = 0; diff --git a/ir.h b/ir.h index c871fa7..2b6267a 100644 --- a/ir.h +++ b/ir.h @@ -48,11 +48,9 @@ struct abiarg { }; struct call { - ushort narg : 15; - ushort sret : 1; + union irtype ret; + ushort narg; short vararg; /* first variadic arg or -1 */ - union ref *args; - union irtype *typs; short *abiargregs; struct abiarg abiret[2]; }; @@ -71,7 +69,7 @@ enum refkind { RXCON, /* other constants (incl. external symbols) */ RDAT, /* reference to irdat */ RMORE, /* reference to extra data for Ocall and Ophi */ - RREG, /* machine register */ + RTYPE, /* irtype */ }; union ref { @@ -167,7 +165,10 @@ extern struct dattab {vec_of(struct irdat);} dattab; #define NOREF ((union ref) {0}) #define ZEROREF ((union ref) {{ RICON, 0 }}) #define mkref(t, x) ((union ref) {{ (t), (x) }}) +#define mktyperef(t) ((union ref) {{ RTYPE, (t).bits }}) +#define ref2type(r) ((union irtype) {.bits = (r).i}) #define mkinstr(O, C, ...) ((struct instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ }) +#define mkarginstr(ty, x) mkinstr(Oarg, 0, mktyperef(ty), (x)) void irinit(struct function *); void irfini(struct function *); union irtype mkirtype(union type); @@ -177,8 +178,8 @@ union ref mksymref(struct function *, const char *); union ref mkdatref(struct function *, uint siz, uint align, const void *, uint n); struct instr mkalloca(uint siz, uint align); void conputdat(struct irdat *, uint off, enum typetag t, const void *dat); -union ref mkcallarg(struct function *, bool sret, uint narg, int vararg, union ref *, union irtype *); -#define mkintrin(F, B, C, N, A, T) mkinstr(Ointrin, C, {.t=RICON,B}, mkcallarg(F,0,N,-1,A,T)) +union ref mkcallarg(struct function *, union irtype ret, uint narg, int vararg); +#define mkintrin(F, B, C, N) mkinstr(Ointrin, C, {.t=RICON,B}, mkcallarg(F,(union irtype){{0}},N,-1)) union ref addinstr(struct function *, struct instr); union ref insertinstr(struct block *, int idx, struct instr); void delinstr(struct block *, int idx); diff --git a/irdump.c b/irdump.c index d437fc4..0b6424b 100644 --- a/irdump.c +++ b/irdump.c @@ -76,7 +76,12 @@ dumpref(enum op o, union ref ref) { struct xcon *con; switch (ref.t) { - case RTMP: efmt("%%%d", ref.i); break; + case RTMP: + if (instrtab[ref.i].reg) + efmt("%s", mctarg->rnames[instrtab[ref.i].reg - 1]); + else + efmt("%%%d", ref.i); + break; case RPARAM: efmt("%%param%d", ref.i); break; case RICON: if (o == Ointrin) efmt("\"%s\"", intrinname[ref.i]); @@ -97,39 +102,32 @@ dumpref(enum op o, union ref ref) case RDAT: efmt("$^%d", ref.i); break; + case RTYPE: + prityp(ref2type(ref)); + break; case RMORE: - if (o == Ocall || o == Ointrin) { - struct call *call = &calltab.p[ref.i]; - if (call->sret) { - efmt("sret "); - prityp(call->typs[call->narg]); - } - for (int i = 0; i < call->narg; ++i) { - if (i > 0 || call->sret) efmt(", "); - if (call->vararg == i) - efmt("..., "); - if (call->abiargregs) { - short r = call->abiargregs[i]; - efmt("(%ls) ", r != -1 ? mctarg->rnames[r] : ""); - } - prityp(call->typs[i]); - efmt(" "); - dumpref(0, call->args[i]); - } - } else if (o == Ophi) { - struct phi *phi = &phitab.p[ref.i]; - for (int i = 0; i < phi->n; ++i) { - if (i > 0) efmt(", "); - efmt("[@%d ", phi->blk[i]->id); - dumpref(0, phi->ref[i]); - efmt("]"); - } - } else assert(0); + assert(0); break; default: assert(!"ref"); } } +static void +dumpcall(struct call *call) +{ + if (call->ret.isagg) { + efmt("sret "); + prityp(call->ret); + efmt(", "); + } + if (call->vararg < 0) { + efmt("#%d", call->narg); + } else { + assert(call->vararg <= call->narg); + efmt("#%d, ... #%d", call->vararg, call->narg - call->vararg); + } +} + static const char *opname[] = { "?\??", #define _(o,...) #o, @@ -148,15 +146,22 @@ dumpinst(const struct instr *ins) { int i; efmt(" "); - if (ins->cls) { + if (ins->reg) { + if (ins->cls) + efmt("%s ", clsname[ins->cls]); + efmt("%s = ", mctarg->rnames[ins->reg - 1]); + } else if (ins->cls) { efmt("%s %%%d", clsname[ins->cls], ins - instrtab); - if (ins->reg) efmt("(%ls)", mctarg->rnames[ins->reg - 1]); efmt(" = "); } efmt("%s ", opname[ins->op]); for (i = 0; i < opnarg[ins->op]; ++i) { if (i) efmt(", "); - dumpref(ins->op, (&ins->l)[i]); + if (i == 1 && (ins->op == Ocall || ins->op == Ointrin)) { + dumpcall(&calltab.p[ins->r.i]); + } else { + dumpref(ins->op, (&ins->l)[i]); + } } efmt("\n"); } @@ -203,7 +208,7 @@ irdump(struct function *fn, const char *fname) for (int i = 0; i < fn->nabiarg; ++i) { if (i > 0) efmt(", "); if (fn->abiarg[i].reg != -1) { - efmt("%ls", mctarg->rnames[fn->abiarg[i].reg]); + efmt("%s", mctarg->rnames[fn->abiarg[i].reg]); } else { prityp(fn->abiarg[i].ty); efmt(" "); @@ -211,9 +216,9 @@ irdump(struct function *fn, const char *fname) } efmt(")"); if (fn->retty.t != TYVOID) { - efmt(" -> %ls", mctarg->rnames[fn->abiret[0].reg]); + efmt(" -> %s", mctarg->rnames[fn->abiret[0].reg]); if (fn->nabiret > 1) - efmt(", %ls", mctarg->rnames[fn->abiret[1].reg]); + efmt(", %s", mctarg->rnames[fn->abiret[1].reg]); } efmt("\n"); } diff --git a/op.def b/op.def index 55d2159..d04f4ed 100644 --- a/op.def +++ b/op.def @@ -57,6 +57,7 @@ _(store1, 2) _(store2, 2) _(store4, 2) _(store8, 2) +_(arg, 2) _(call, 2) _(call2r, 1) _(intrin, 2) diff --git a/parse.c b/parse.c index 4fb44ec..1ea9dbd 100644 --- a/parse.c +++ b/parse.c @@ -987,10 +987,10 @@ expreffects(struct function *fn, const struct expr *ex) static void structcopy(struct function *fn, union type ty, union ref dst, union ref src) { - union ref args[2] = { dst, src }; - union irtype typs[2] = { mkirtype(ty) }; - typs[1] = typs[0]; - addinstr(fn, mkintrin(fn, INstructcopy, 0, 2, args, typs)); + union irtype typ = mkirtype(ty); + addinstr(fn, mkarginstr(typ, dst)); + addinstr(fn, mkarginstr(typ, src)); + addinstr(fn, mkintrin(fn, INstructcopy, 0, 2)); } static union ref @@ -1289,10 +1289,8 @@ compilecall(struct function *fn, const struct expr *ex) struct instr ins = {0}; struct expr *sub = ex->sub; const struct typedata *td = &typedata[sub[0].ty.dat]; - union ref argsbuf[10]; - union irtype typbuf[10]; - vec_of(union ref) args = VINIT(argsbuf, arraylength(argsbuf)); - vec_of(union irtype) typs = VINIT(typbuf, arraylength(typbuf)); + struct instr insnsbuf[10]; + vec_of(struct instr) insns = VINIT(insnsbuf, arraylength(insnsbuf)); ins.op = Ocall; if (isagg(ex->ty)) { @@ -1302,21 +1300,16 @@ compilecall(struct function *fn, const struct expr *ex) ins.cls = type2cls[ex->ty.t]; } ins.l = exprvalue(fn, &sub[0]); - vresize(&args, ex->narg); - vresize(&typs, ex->narg); - /* backwards because of RTL call stack order */ - for (int i = ex->narg - 1; i >= 0; --i) { + for (int i = 0; i < ex->narg; ++i) { struct expr *arg = &sub[i+1]; union type ty = i < td->nmemb ? td->param[i] : argpromote(arg->ty); - args.p[i] = cvt(fn, ty.t, arg->ty.t, exprvalue(fn, arg)); - typs.p[i] = mkirtype(ty); + union ref r = cvt(fn, ty.t, arg->ty.t, exprvalue(fn, arg)); + vpush(&insns, mkarginstr(mkirtype(ty), r)); } - if (isagg(ex->ty)) - vpush(&typs, mkirtype(ex->ty)); - ins.r = mkcallarg(fn, isagg(ex->ty), ex->narg, td->variadic ? td->nmemb : td->kandr ? 0 : -1, - args.p, typs.p); - vfree(&args); - vfree(&typs); + for (int i = 0; i < insns.n; ++i) + addinstr(fn, insns.p[i]); + vfree(&insns); + ins.r = mkcallarg(fn, mkirtype(ex->ty), ex->narg, td->variadic ? td->nmemb : td->kandr ? 0 : -1); return addinstr(fn, ins); } diff --git a/regalloc.c b/regalloc.c index d7fadf6..5833ed4 100644 --- a/regalloc.c +++ b/regalloc.c @@ -36,11 +36,7 @@ use(struct block *blk, enum op op, int hint, union ref *ref) { struct instr *ins; if (ref->t == RMORE) { - if (op == Ocall || op == Ointrin) { - struct call *call = &calltab.p[ref->i]; - for (int i = 0; i < call->narg; ++i) - use(blk, 0, op == Ocall ? call->abiargregs[i] : -1, &call->args[i]); - } else if (op == Ophi) { + if (op == Ophi) { struct phi *phi = &phitab.p[ref->i]; for (int i = 0; i < phi->n; ++i) use(blk, 0, hint, &phi->ref[i]); @@ -57,7 +53,6 @@ use(struct block *blk, enum op op, int hint, union ref *ref) /* result of comparison instr is only used to conditionally branch, * doesn't usually need a reg (handled by isel) */ return; - /* TODO implement actual constraints and stuff */ if (ins->op == Ocall) { struct call *call = &calltab.p[ins->r.i]; hint = call->abiret[0].reg; @@ -105,9 +100,24 @@ regalloc(struct function *fn) int hint0 = -1, hint1 = -1; ins = &instrtab[blk->ins.p[i]]; def(ins); - if (ins->op == Ocopy) hint0 = ins->reg - 1; - if (ins->l.t) use(blk, ins->op, hint0, &ins->l); - if (ins->r.t) use(blk, ins->op, hint1, &ins->r); + if (ins->op != Ocall) { + if (ins->op == Ocopy) hint0 = ins->reg - 1; + if (ins->l.t) use(blk, ins->op, hint0, &ins->l); + if (ins->r.t) use(blk, ins->op, hint1, &ins->r); + } else { + struct call *call = &calltab.p[ins->r.i]; + for (int iarg = 0; iarg < call->narg; ++iarg) { + struct instr *arg = &instrtab[blk->ins.p[i - call->narg + iarg]]; + int reg = call->abiargregs[iarg]; + assert(arg->op == Oarg); + if (reg != -1) { + assert(!bstest(taken, reg) && "nyi spill"); + arg->reg = reg + 1; + bsset(taken, reg); + } + } + use(blk, ins->op, hint0, &ins->l); + } } } while ((blk = blk->lprev) != last); diff --git a/test/test.c b/test/test.c index 40b59e6..e429104 100644 --- a/test/test.c +++ b/test/test.c @@ -51,18 +51,18 @@ void silly(struct pair *p, struct quad *q) *q = quad(1,2,3,4); } -void test2(struct big *b) { +int test2(struct big *b) { struct big s = *b; - extern void h(int, struct big, float); + extern int h(int,float, struct big, float); s.x[5] += 2; - h(0, s, 0); + return h(0, -.5f, s, 0); } struct f2 { float f,g; }; struct f2 f2test(struct f2 *r) { return *r; } - +#if 0 void fill(char *p, int c, unsigned long n) { int t; @@ -93,5 +93,5 @@ struct f{ union { int x,y;} ; char flex[]; }; - +#endif // -- cgit v1.2.3