From 79874c83bf76a5b3efd3d558933b90d9b53b829e Mon Sep 17 00:00:00 2001 From: lemon Date: Sat, 21 Mar 2026 22:20:34 +0100 Subject: IR: add 3rd operand to Instr The motivation is for aarch64 msub/madd instrs, for isel to produce. But it should be useful for other things too. --- src/c.c | 6 ++--- src/c_builtin.c | 18 ++------------- src/c_eval.c | 3 ++- src/ir.c | 2 +- src/ir.h | 15 ++++++++---- src/ir_abi0.c | 38 +++++++++++++++--------------- src/ir_builder.c | 6 ++--- src/ir_dump.c | 2 +- src/ir_inliner.c | 12 +++++----- src/ir_intrin.c | 10 ++++---- src/ir_mem2reg.c | 4 ++-- src/ir_op.def | 12 +++++----- src/ir_regalloc.c | 31 +++++++++++++++++-------- src/ir_simpl.c | 20 ++++++++-------- src/ir_ssa.c | 2 +- src/ir_stack.c | 2 +- src/t_aarch64_isel.c | 50 ++++++++++++++++++++-------------------- src/t_x86-64_isel.c | 65 ++++++++++++++++++++++++++-------------------------- src/t_x86-64_sysv.c | 40 ++++++++++++++++---------------- 19 files changed, 171 insertions(+), 167 deletions(-) diff --git a/src/c.c b/src/c.c index 90ff923..248a095 100644 --- a/src/c.c +++ b/src/c.c @@ -3121,7 +3121,7 @@ geninit(Function *fn, Type t, Ref dst, const Expr *src) /* write individual zeros at non initialized gaps */ for (uint i = 0; bsiter(&i, azero, countof(azero)) && i < siz; i += align) { adr = irbinop(fn, Oadd, KPTR, dst, mkref(RICON, i)); - addinstr(fn, mkinstr(Ostorei8 + ilog2(align), 0, .l = adr, .r = ZEROREF)); + addinstr(fn, mkinstr2(Ostorei8 + ilog2(align), 0, adr, ZEROREF)); } } else { goto Memset0; @@ -4564,7 +4564,7 @@ function(CComp *cm, Function *fn, internstr *pnames, const Span *pspans, uchar * EMITS { for (int i = 0; i < td->nmemb; ++i) { IRType pty = mkirtype(td->param[i]); - Ref r = addinstr(fn, mkinstr(Oparam, pty.isagg ? KPTR : pty.cls, + Ref r = addinstr(fn, mkinstr2(Oparam, pty.isagg ? KPTR : pty.cls, mkref(RICON, i), mktyperef(pty))); assert(r.t == RTMP && r.i == i); } @@ -4579,7 +4579,7 @@ function(CComp *cm, Function *fn, internstr *pnames, const Span *pspans, uchar * arg.id = addinstr(fn, mkalloca(typesize(arg.ty), typealign(arg.ty))).i; genstore(fn, arg.ty, mkref(RTMP, arg.id), mkref(RTMP, i)); } else { - arg.id = addinstr(fn, mkinstr(Ocopy, KPTR, mkref(RTMP, i))).i; + arg.id = addinstr(fn, mkinstr1(Ocopy, KPTR, mkref(RTMP, i))).i; } } putdecl(cm, &arg); diff --git a/src/c_builtin.c b/src/c_builtin.c index a8d4f4f..522c4dc 100644 --- a/src/c_builtin.c +++ b/src/c_builtin.c @@ -46,7 +46,7 @@ va_start_comp(Function *fn, Expr *ex, bool discard) assert(typedecay(ex->sub[1].ty).bits == typedecay(cvalistty).bits); if (!typedata[fn->fnty.dat].variadic) error(&ex->span, "va_start used in non-variadic function"); - addinstr(fn, mkinstr(Ovastart, 0, compileexpr(fn, &ex->sub[1], 0))); + addinstr(fn, mkinstr1(Ovastart, 0, compileexpr(fn, &ex->sub[1], 0))); return NOREF; } @@ -89,20 +89,6 @@ trap_comp(Function *fn, Expr *ex, bool discard) return NOREF; } -static inline Ref -cvtintref(Function *fn, enum irclass dst, Ref src) -{ - if (src.t == RTMP) { - if (insrescls(instrtab[src.i]) != dst) - return addinstr(fn, mkinstr(Ocopy, dst, src)); - return src; - } else if (isintcon(src)) { - vlong x = intconval(src); - return mkintcon(dst, cls2siz[dst] == 4 ? (int)x : x); - } - assert(!"int ref?"); -} - /* __builtin_bswap16 */ DEF_FNLIKE_SEMA(bswap16, mktype(TYUSHORT), mktype(TYUSHORT)) static Ref @@ -162,7 +148,7 @@ builtin_va_arg_comp(Function *fn, const Expr *ex, bool discard) { assert(ex->t == EVAARG && ex->ty.t); enum irclass k = isagg(ex->ty) ? KPTR : type2cls[scalartypet(ex->ty)]; - return addinstr(fn, mkinstr(Ovaarg, k, compileexpr(fn, ex->sub, 0), mktyperef(mkirtype(ex->ty)))); + return addinstr(fn, mkinstr2(Ovaarg, k, compileexpr(fn, ex->sub, 0), mktyperef(mkirtype(ex->ty)))); } bool diff --git a/src/c_eval.c b/src/c_eval.c index 20a5a12..927ea05 100644 --- a/src/c_eval.c +++ b/src/c_eval.c @@ -83,7 +83,8 @@ lit2ssym(Expr *ex) { ex->ssym.sym = xcon2sym(expraddr(NULL, ex).i); ex->ssym.local = 1; - ex->ssym.func = ex->ssym.off = 0; + ex->ssym.func = 0; + ex->ssym.off = 0; ex->t = ESSYMREF; return ex; } diff --git a/src/ir.c b/src/ir.c index ce36e64..6cdb43d 100644 --- a/src/ir.c +++ b/src/ir.c @@ -484,7 +484,7 @@ insertphi(Block *blk, enum irclass cls) assert(blk->npred > 0); xbgrowz(&refs, blk->npred); vpush(&phitab, refs); - instrtab[new] = mkinstr(Ophi, cls, mkref(RXXX, phitab.n - 1)); + instrtab[new] = mkinstr1(Ophi, cls, {.i = phitab.n - 1}); vpush(&blk->phi, new); return mkref(RTMP, new); } diff --git a/src/ir.h b/src/ir.h index f54c2fb..fef38b5 100644 --- a/src/ir.h +++ b/src/ir.h @@ -122,9 +122,12 @@ typedef struct Instr { keep : 1; /* for codegen, keep instr even if result seems unused */ uchar inplace : 1; /* set (by isel) for instructions which modify its first arg in place */ uchar reg; /* 0 -> no reg; else reg + 1 */ - Ref l, r; /* args */ + union { /* operands */ + struct { Ref l, r; }; + Ref oper[3]; + }; } Instr; -static_assert(sizeof(Instr) == 4*3); +static_assert(sizeof(Instr) == 4*4); enum jumpkind { JXXX, Jb, Jret, Jtrap, }; @@ -253,8 +256,10 @@ extern struct dattab {vec_of(IRDat);} dattab; extern struct contab {vec_of(IRCon);} contab; extern struct addrtab {vec_of(IRAddr);} addrtab; extern int visitmark; -#define mkinstr(O, C, ...) ((Instr) { .op = (O), .cls = (C), .reg=0, __VA_ARGS__ }) -#define mkarginstr(ty, x) mkinstr(Oarg, 0, mktyperef(ty), (x)) +#define mkinstr0(O, C) ((Instr) { .op = (O), .cls = (C), .reg=0 }) +#define mkinstr1(O, C, x) ((Instr) { .op = (O), .cls = (C), .reg=0, .l = x}) +#define mkinstr2(O, C, x,y) ((Instr) { .op = (O), .cls = (C), .reg=0, .l = x, .r = y}) +#define mkarginstr(ty, x) mkinstr2(Oarg, 0, mktyperef(ty), (x)) void irinit(Function *); void irfini(Function *); #define cls2type(k) ((IRType){.cls=(k)}) @@ -276,7 +281,7 @@ Ref mkdatref(internstr sym, Type ctype, uint siz, uint align, internstr xcon2sym(int ref); Instr mkalloca(uint siz, uint align); Ref mkcallarg(IRType ret, uint narg, int vararg); -#define mkintrin(B, C, N) mkinstr(Ointrin, C, {{.t=RICON,B}}, mkcallarg((IRType){{0}},N,-1)) +#define mkintrin(B, C, N) mkinstr2(Ointrin, C, mkref(RICON, B), mkcallarg((IRType){{0}},N,-1)) Ref mkaddr(IRAddr); void addpred(Block *blk, Block *p); diff --git a/src/ir_abi0.c b/src/ir_abi0.c index cd7ce27..61a310f 100644 --- a/src/ir_abi0.c +++ b/src/ir_abi0.c @@ -58,7 +58,7 @@ abiarg(ABIArgVec *abiargs, uchar *r2off, int *ni, int *nf, int *ns, IRType ty) static Instr copyparam(Function *fn, int *curi, int param, ABIArg abi) { - Instr par = mkinstr(Oparam, abi.ty.cls, mkref(RICON, param), mktyperef(abi.ty)); + Instr par = mkinstr2(Oparam, abi.ty.cls, mkref(RICON, param), mktyperef(abi.ty)); if (!abi.isstk) { /* reg */ assert(!abi.ty.isagg); return par; @@ -75,7 +75,7 @@ copyparam(Function *fn, int *curi, int param, ABIArg abi) case KF32: ld = Oloadf32; break; case KF64: ld = Oloadf64; break; } - return mkinstr(ld, abi.ty.cls, insertinstr(fn->entry, (*curi)++, par)); + return mkinstr1(ld, abi.ty.cls, insertinstr(fn->entry, (*curi)++, par)); } else { /* aggregate in stack */ par.cls = KPTR; return par; @@ -109,7 +109,7 @@ patchparam(Function *fn, int *curi, int *param, int tydat, int nabi, ABIArg abi[ assert(td->siz <= 16 && td->align <= 16); align = td->siz <= 4 ? 4 : alignup(td->align, 8); nalloc = td->siz/align + (td->siz%align != 0); - *ins = mkinstr(Oalloca1 + ilog2(align), KPTR, mkref(RICON, nalloc)); + *ins = mkinstr1(Oalloca1 + ilog2(align), KPTR, mkref(RICON, nalloc)); alloc = mkref(RTMP, ins - instrtab); r[0] = insertinstr(blk, ++*curi, copyparam(fn, NULL, *param, abi[0])); if (nabi > 1) @@ -121,11 +121,11 @@ patchparam(Function *fn, int *curi, int *param, int tydat, int nabi, ABIArg abi[ * store* %x, %a * store* %x + N, %b */ - st = mkinstr(cls2store[abi[0].ty.cls], 0, alloc, r[0]); + st = mkinstr2(cls2store[abi[0].ty.cls], 0, alloc, r[0]); insertinstr(blk, ++*curi, st); if (nabi > 1) { - Instr tmp = mkinstr(Oadd, KPTR, alloc, mkref(RICON, r2off)); - st = mkinstr(cls2store[abi[1].ty.cls], 0, insertinstr(blk, ++*curi, tmp), r[1]); + Instr tmp = mkinstr2(Oadd, KPTR, alloc, mkref(RICON, r2off)); + st = mkinstr2(cls2store[abi[1].ty.cls], 0, insertinstr(blk, ++*curi, tmp), r[1]); insertinstr(blk, ++*curi, st); } } @@ -165,7 +165,7 @@ load2regs(Ref out[2], IRType typ, Ref src, int nabi, ABIArg abi[2], uchar r2off, if (i == 0) ins.l = src; else { - Instr adr = mkinstr(Oadd, KPTR, src, mkref(RICON, r2off)); + Instr adr = mkinstr2(Oadd, KPTR, src, mkref(RICON, r2off)); ins.l = insertinstr(blk, (*curi)++, adr); } temp = insertinstr(blk, (*curi)++, ins); @@ -184,13 +184,13 @@ load2regs(Ref out[2], IRType typ, Ref src, int nabi, ABIArg abi[2], uchar r2off, if (i+o == 0) ld.l = src; else { - Instr adr = mkinstr(Oadd, KPTR, src, mkref(RICON, (i == 0 ? 0 : r2off) + o*align)); + Instr adr = mkinstr2(Oadd, KPTR, src, mkref(RICON, (i == 0 ? 0 : r2off) + o*align)); ld.l = insertinstr(blk, (*curi)++, adr); } temp = insertinstr(blk, (*curi)++, ld); if (o > 0) { - Ref t = insertinstr(blk, (*curi)++, mkinstr(Oshl, ld.cls, temp, mkref(RICON, o*align*8))); - reg = insertinstr(blk, (*curi)++, mkinstr(Oior, ld.cls, reg, t)); + Ref t = insertinstr(blk, (*curi)++, mkinstr2(Oshl, ld.cls, temp, mkref(RICON, o*align*8))); + reg = insertinstr(blk, (*curi)++, mkinstr2(Oior, ld.cls, reg, t)); } else { reg = temp; } @@ -223,10 +223,10 @@ patcharg(Block *blk, int *icall, IRCall *call, arg->cls = KPTR; arg->r = mkref(RICON, abi->stk); for (uint off = 0; off < siz; off += align) { - Ref sadr = off == 0 ? src : insertinstr(blk, ++arginst, mkinstr(Oadd, KPTR, src, mkref(RICON, off))); - Ref tmp = insertinstr(blk, ++arginst, mkinstr(Oloads8+2*ilog2(align), align < 8 ? KI32 : KI64, sadr)); - Ref dadr = off == 0 ? dst : insertinstr(blk, ++arginst, mkinstr(Oadd, KPTR, dst, mkref(RICON, off))); - insertinstr(blk, ++arginst, mkinstr(Ostorei8+ilog2(align), 0, dadr, tmp)); + Ref sadr = off == 0 ? src : insertinstr(blk, ++arginst, mkinstr2(Oadd, KPTR, src, mkref(RICON, off))); + Ref tmp = insertinstr(blk, ++arginst, mkinstr1(Oloads8+2*ilog2(align), align < 8 ? KI32 : KI64, sadr)); + Ref dadr = off == 0 ? dst : insertinstr(blk, ++arginst, mkinstr2(Oadd, KPTR, dst, mkref(RICON, off))); + insertinstr(blk, ++arginst, mkinstr2(Ostorei8+ilog2(align), 0, dadr, tmp)); } *icall = arginst + (call->narg - argidx); return 1; @@ -238,7 +238,7 @@ patcharg(Block *blk, int *icall, IRCall *call, delinstr(blk, arginst); load2regs(r, ref2type(arg->l), arg->r, nabi, abi, r2off, blk, &arginst); for (int i = 0; i < nabi; ++i) - insertinstr(blk, arginst++, mkinstr(Oarg, 0, mktyperef(abi[i].ty), r[i])); + insertinstr(blk, arginst++, mkinstr2(Oarg, 0, mktyperef(abi[i].ty), r[i])); *icall = arginst + (call->narg - argidx - 1); return nabi; } @@ -281,7 +281,7 @@ abi0_call(Function *fn, Instr *ins, Block *blk, int *curi) if (!nret) /* hidden pointer argument */ insertinstr(blk, (*curi)++ - call->narg, - mkinstr(Oarg, 0, mktyperef((IRType){.cls=KPTR}), retmem)); + mkinstr2(Oarg, 0, mktyperef((IRType){.cls=KPTR}), retmem)); } /* adjust args */ @@ -316,7 +316,7 @@ abi0_call(Function *fn, Instr *ins, Block *blk, int *curi) ins->cls = call->abiret[0].ty.cls; r[0] = mkref(RTMP, ins - instrtab); if (nret == 2) { - ret2 = mkinstr(Ocall2r, call->abiret[1].ty.cls, r[0]); + ret2 = mkinstr1(Ocall2r, call->abiret[1].ty.cls, r[0]); r[1] = insertinstr(blk, ++*curi, ret2); } for (int i = 0; i < nret; ++i) { @@ -324,7 +324,7 @@ abi0_call(Function *fn, Instr *ins, Block *blk, int *curi) if (i == 0) { store.l = retmem; } else { - Instr addr = mkinstr(Oadd, KPTR, retmem, mkref(RICON, call->r2off)); + Instr addr = mkinstr2(Oadd, KPTR, retmem, mkref(RICON, call->r2off)); store.l = insertinstr(blk, ++*curi, addr); } store.r = r[i]; @@ -404,7 +404,7 @@ abi0(Function *fn) } } while ((blk = blk->lnext) != fn->entry); if (rvovar != -1) - instrtab[rvovar] = mkinstr(Ocopy, KPTR, sret); + instrtab[rvovar] = mkinstr1(Ocopy, KPTR, sret); } blk = fn->entry->lnext; diff --git a/src/ir_builder.c b/src/ir_builder.c index 0c4b910..7f46574 100644 --- a/src/ir_builder.c +++ b/src/ir_builder.c @@ -100,7 +100,7 @@ irbinop(Function *fn, enum op op, enum irclass k, Ref l, Ref r) default: assert(!"binop?"); } - return fn ? addinstr(fn, mkinstr(op, k, l, r)) : NOREF; + return fn ? addinstr(fn, mkinstr2(op, k, l, r)) : NOREF; } /* implements f32/f64 -> u64 conversion */ @@ -195,7 +195,7 @@ irunop(Function *fn, enum op op, enum irclass k, Ref a) break; default: assert(!"unop?"); } - return fn ? addinstr(fn, mkinstr(op, k, a)) : NOREF; + return fn ? addinstr(fn, mkinstr1(op, k, a)) : NOREF; } int allocinstr(void); @@ -242,7 +242,7 @@ addphi(Function *fn, enum irclass cls, Ref *r) vpush(&phitab, refs); /*assert(fn->curblk->ins.n == 0);*/ int new = allocinstr(); - instrtab[new] = mkinstr(Ophi, cls, .l.i = phitab.n-1); + instrtab[new] = mkinstr1(Ophi, cls, {.i=phitab.n-1}); for (int i = 0; i < fn->curblk->npred; ++i) { adduse(fn->curblk, new, r[i]); } diff --git a/src/ir_dump.c b/src/ir_dump.c index 7534370..89d34d4 100644 --- a/src/ir_dump.c +++ b/src/ir_dump.c @@ -215,7 +215,7 @@ dumpinst(const Instr *ins) if (i == 1 && (ins->op == Ocall || ins->op == Ointrin)) { dumpcall(&calltab.p[ins->r.i]); } else { - dumpref(ins->op, (&ins->l)[i]); + dumpref(ins->op, ins->oper[i]); } } if (oisalloca(ins->op) && ins->l.t == RICON) { diff --git a/src/ir_inliner.c b/src/ir_inliner.c index c3e0777..db89479 100644 --- a/src/ir_inliner.c +++ b/src/ir_inliner.c @@ -125,7 +125,7 @@ inlcall(Function *fn, Block *blk, int curi, SavedFunc *sv) Instr *ins = &instrtab[blk->ins.p[i]]; if (ins->op == Oarg) { args[--n] = ins->r; - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); } } if (call->abiret[1].ty.bits) { @@ -135,14 +135,14 @@ inlcall(Function *fn, Block *blk, int curi, SavedFunc *sv) } Block *exit = blksplitafter(fn, blk, curi-1); if (!ins->cls) { - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); } else { if (sv->nretpoints == 1) { - *ins = mkinstr(Ocopy, ins->cls, ); + *ins = mkinstr1(Ocopy, ins->cls, NOREF); } else { /* turn into a phi */ - *ins = mkinstr(Ophi, ins->cls, ); - exit->ins.p[0] = newinstr(blk, mkinstr(Onop,0,)); + *ins = mkinstr1(Ophi, ins->cls, NOREF); + exit->ins.p[0] = newinstr(blk, mkinstr0(Onop,0)); vpush(&exit->phi, res); } } @@ -187,7 +187,7 @@ inlcall(Function *fn, Block *blk, int curi, SavedFunc *sv) for (int i = 0; i < b->npred; ++i) refs[i] = mapref(instrmap, sv, src[i]); vpush(&phitab, refs); - instrtab[instrmap[t]] = mkinstr(Ophi, sv->instrtab[t].cls, .l.i = phitab.n-1); + instrtab[instrmap[t]] = mkinstr1(Ophi, sv->instrtab[t].cls, {.i = phitab.n-1}); new->phi.p[i] = instrmap[t]; } vresize(&new->ins, b->ins.n); diff --git a/src/ir_intrin.c b/src/ir_intrin.c index 6c73784..e2ea1d0 100644 --- a/src/ir_intrin.c +++ b/src/ir_intrin.c @@ -24,7 +24,7 @@ intrin(Block *blk, int *curi, enum intrin in, Arg *args, int narg, IRType ret) /* memcpy */ *args[1].ty = *args[0].ty = mktyperef(cls2type(KPTR)); insertinstr(blk, (*curi)++, mkarginstr(cls2type(cls), mkintcon(cls, td->siz))); - *this = mkinstr(Ocall, 0, mksymref(intern("memcpy"), SFUNC), this->r); + *this = mkinstr2(Ocall, 0, mksymref(intern("memcpy"), SFUNC), this->r); calltab.p[this->r.i].narg = 3; calltab.p[this->r.i].ret = cls2type(0); return 0; @@ -33,11 +33,11 @@ intrin(Block *blk, int *curi, enum intrin in, Arg *args, int narg, IRType ret) for (int off = 0; off < td->siz; off += step) { Ref psrc = *args[1].arg, pdst = *args[0].arg, src; if (off) { - pdst = insertinstr(blk, ++*curi, mkinstr(Oadd, KPTR, *args[0].arg, mkref(RICON, off))); - psrc = insertinstr(blk, ++*curi, mkinstr(Oadd, KPTR, *args[1].arg, mkref(RICON, off))); + pdst = insertinstr(blk, ++*curi, mkinstr2(Oadd, KPTR, *args[0].arg, mkref(RICON, off))); + psrc = insertinstr(blk, ++*curi, mkinstr2(Oadd, KPTR, *args[1].arg, mkref(RICON, off))); } - src = insertinstr(blk, ++*curi, mkinstr(Oloads8 + 2*ilog2(step), step < 8 ? KI32 : KI64, psrc)); - insertinstr(blk, ++*curi, mkinstr(Ostorei8 + ilog2(step), 0, pdst, src)); + src = insertinstr(blk, ++*curi, mkinstr1(Oloads8 + 2*ilog2(step), step < 8 ? KI32 : KI64, psrc)); + insertinstr(blk, ++*curi, mkinstr2(Ostorei8 + ilog2(step), 0, pdst, src)); } return 1; } diff --git a/src/ir_mem2reg.c b/src/ir_mem2reg.c index 8890439..ae41833 100644 --- a/src/ir_mem2reg.c +++ b/src/ir_mem2reg.c @@ -276,7 +276,7 @@ mem2reg(Function *fn) if (oisstore(ins->op)) { writevar(&sb, var, use->blk, ins->r); - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); } else if (oisload(ins->op)) { Ref val = readvar(&sb, var, k = ins->cls, use->blk); adduse(use->blk, use->u, val); @@ -285,7 +285,7 @@ mem2reg(Function *fn) assert(val.bits); ext = Ocopy; } - *ins = mkinstr(ext, k, val); + *ins = mkinstr1(ext, k, val); } } /* remove alloca */ diff --git a/src/ir_op.def b/src/ir_op.def index 4a18b4b..4e775a1 100644 --- a/src/ir_op.def +++ b/src/ir_op.def @@ -60,12 +60,12 @@ _(loadu32, 1) _(loadi64, 1) _(loadf32, 1) _(loadf64, 1) -_(storei8, 2) -_(storei16, 2) -_(storei32, 2) -_(storei64, 2) -_(storef32, 2) -_(storef64, 2) +_(storei8, 2) +_(storei16, 2) +_(storei32, 2) +_(storei64, 2) +_(storef32, 2) +_(storef64, 2) _(param, 2) _(arg, 2) _(call, 2) diff --git a/src/ir_regalloc.c b/src/ir_regalloc.c index 54f5d59..41a4026 100644 --- a/src/ir_regalloc.c +++ b/src/ir_regalloc.c @@ -215,7 +215,7 @@ pmadd(PMState *pms, enum irclass k, Alloc dst, Alloc src) pms->pmove[pms->npmove++] = (struct PMove) { k, PMTOMOVE, dst, src }; } -#define mkmove(k, rd, rs) mkinstr(Omove, k, mkref(RREG, rd), mkref(RREG, rs)) +#define mkmove(k, rd, rs) mkinstr2(Omove, k, mkref(RREG, rd), mkref(RREG, rs)) static void emitmove(Function *fn, enum irclass k, Alloc dst, Alloc src, Block *blk, int curi) { @@ -243,7 +243,7 @@ emitmove(Function *fn, enum irclass k, Alloc dst, Alloc src, Block *blk, int cur insertinstr(blk, curi++, mv); } else reg = src.a; if (dst.t == ASTACK) { - mv = mkinstr(cls2store[k], 0, stkslotref(fn, dst.a*8), mkref(RREG, reg)); + mv = mkinstr2(cls2store[k], 0, stkslotref(fn, dst.a*8), mkref(RREG, reg)); insertinstr(blk, curi, mv); } } @@ -275,7 +275,7 @@ pmrec(PMState *pms, int i, Block *blk, int curi, enum irclass *k) Swap: if (pm->src.t == AREG && pm->dst.t == AREG) { insertinstr(blk, curi, - mkinstr(Oswap, *k, mkref(RREG, pm->dst.a), mkref(RREG, pm->src.a), .keep = 1)); + (Instr){Oswap, *k, .keep=1, .l = mkref(RREG, pm->dst.a), .r = mkref(RREG, pm->src.a)}); } else if (pm->src.t != pm->dst.t) { Alloc reg, stk, regtmp; if (pm->src.t == AREG) @@ -286,7 +286,7 @@ pmrec(PMState *pms, int i, Block *blk, int curi, enum irclass *k) regtmp = areg(kisint(*k) ? mctarg->gprscratch : mctarg->fprscratch); emitmove(pms->fn, *k, regtmp, stk, blk, curi++); insertinstr(blk, curi++, - mkinstr(Oswap, *k, mkref(RREG, reg.a), mkref(RREG, regtmp.a), .keep = 1)); + (Instr){Oswap, *k, .keep=1, .l = mkref(RREG, reg.a), .r = mkref(RREG, regtmp.a)}); emitmove(pms->fn, *k, stk, regtmp, blk, curi++); } else { /* FIXME using scratch gpr and fpr for this is hackish */ @@ -411,7 +411,7 @@ fixcssa(Function *fn) for (int i = 0; i < blk->phi.n; ++i) { int phi = blk->phi.p[i]; Ref *args = phitab.p[instrtab[phi].l.i]; - args[p] = insertinstr(n, n->ins.n, mkinstr(Ocopy, instrtab[phi].cls, args[p])); + args[p] = insertinstr(n, n->ins.n, mkinstr1(Ocopy, instrtab[phi].cls, args[p])); } } } while ((blk = blk->lnext) != fn->entry); @@ -660,7 +660,7 @@ buildintervals(RegAlloc *ra) if (!intervaldef(ra, out, blk, pos, reghint)) { if (insrescls(*ins) && ins->op != Omove && !ins->keep && !(ins->op == Ocopy && ins->l.t == RREG)) { /* dead */ - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); } } bsclr(live, out); @@ -680,7 +680,7 @@ buildintervals(RegAlloc *ra) * move RCX, %1 * %2 = shl 1, RCX * and %2 is dead, the move to RCX can be killed */ - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); } } else { rsset(&ra->fn->regusage, ins->l.i); @@ -719,14 +719,25 @@ buildintervals(RegAlloc *ra) * live.add(opd) */ reghint = (ins && ins->op == Omove && ins->l.t == RREG) ? ins->l.i : -1; - queue[0] = ins->r, queue[1] = ins->l; + int nqueue; + if (ins->op == Omove) { + nqueue = 1; + queue[0] = ins->r; + } else { + switch ((nqueue = opnarg[ins->op])) { + case 2: queue[2] = ins->oper[2]; + case 1: queue[1] = ins->oper[1]; + case 0: queue[0] = ins->oper[0]; + } + } if (0) { Branchopd: reghint = -1; curi = blk->ins.n; pos = blk->inumstart + blk->ins.n + 1; + nqueue = 2; } - for (int nqueue = ins && ins->op == Omove ? 1 : 2; nqueue > 0;) { + while (nqueue > 0) { Ref r = queue[--nqueue]; /* do not allocate a reg for a cmp op used as branch argument, since it's a pseudo op */ @@ -1252,7 +1263,7 @@ devirt(RegAlloc *ra, Block *blk) } ins->reg = reg+1; insertinstr(blk, ++curi, - mkinstr(store, 0, stkslotref(fn, alloc->a*8), mkref(RREG, reg))); + mkinstr2(store, 0, stkslotref(fn, alloc->a*8), mkref(RREG, reg))); if (nspill > 0 && dosave) { emitmove(fn, isgpr(reg) ? KPTR : KF64, areg(reg), spillsave[nspill-1], blk, ++curi); diff --git a/src/ir_simpl.c b/src/ir_simpl.c index 8bf8c98..ad25a9f 100644 --- a/src/ir_simpl.c +++ b/src/ir_simpl.c @@ -21,12 +21,12 @@ mulk(Instr *ins, Block *blk, int *curi) /* x * 5 ==> (x << 2) + x */ ins->op = Oadd; ins->r = ins->l; - ins->l = insertinstr(blk, (*curi)++, mkinstr(Oshl, cls, ins->l, mkref(RICON, ilog2(iv-1)))); + ins->l = insertinstr(blk, (*curi)++, mkinstr2(Oshl, cls, ins->l, mkref(RICON, ilog2(iv-1)))); } else if (ispo2(iv+1)) { /* x * 7 ==> (x << 3) - x */ ins->op = Osub; ins->r = ins->l; - ins->l = insertinstr(blk, (*curi)++, mkinstr(Oshl, cls, ins->l, mkref(RICON, ilog2(iv+1)))); + ins->l = insertinstr(blk, (*curi)++, mkinstr2(Oshl, cls, ins->l, mkref(RICON, ilog2(iv+1)))); } else return 0; if (neg) { ins->l = insertinstr(blk, (*curi)++, *ins); @@ -58,12 +58,12 @@ divmodk(Instr *ins, Block *blk, int *curi) case Odiv: case Orem: /* have to adjust to round negatives toward zero */ /* x' = (((x < 0 ? -1 : 0) >>> (Nbit - s)) + x) */ - temp = insertinstr(blk, (*curi)++, mkinstr(Osar, cls, ins->l, mkref(RICON, nbit - 1))); - temp = insertinstr(blk, (*curi)++, mkinstr(Oslr, cls, temp, mkref(RICON, nbit - s))); - temp = insertinstr(blk, (*curi)++, mkinstr(Oadd, cls, ins->l, temp)); + temp = insertinstr(blk, (*curi)++, mkinstr2(Osar, cls, ins->l, mkref(RICON, nbit - 1))); + temp = insertinstr(blk, (*curi)++, mkinstr2(Oslr, cls, temp, mkref(RICON, nbit - s))); + temp = insertinstr(blk, (*curi)++, mkinstr2(Oadd, cls, ins->l, temp)); if (op == Odiv) { /* (-) (x' >> s) */ - Instr sar = mkinstr(Osar, cls, temp, mkref(RICON, s)); + Instr sar = mkinstr2(Osar, cls, temp, mkref(RICON, s)); if (!neg) *ins = sar; else { temp = insertinstr(blk, (*curi)++, sar); @@ -71,7 +71,7 @@ divmodk(Instr *ins, Block *blk, int *curi) } } else { /* x - (x' & -(2^s)) */ - temp = insertinstr(blk, (*curi)++, mkinstr(Oand, cls, temp, mkintcon(cls, neg ? iv : -iv))); + temp = insertinstr(blk, (*curi)++, mkinstr2(Oand, cls, temp, mkintcon(cls, neg ? iv : -iv))); ins->op = Osub, ins->r = temp; } break; @@ -89,7 +89,7 @@ doins(Instr *ins, Block *blk, int *curi) Ref r = narg == 1 ? irunop(NULL, ins->op, ins->cls, ins->l) : irbinop(NULL, ins->op, ins->cls, ins->l, ins->r); if (r.bits) { - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); replcuses(mkref(RTMP, ins - instrtab), r); return 1; } @@ -101,7 +101,7 @@ doins(Instr *ins, Block *blk, int *curi) || (isnumcon(ins->l) && k == concls(ins->l)) || (kisint(k) && ins->l.t == RICON)) { Ref it = ins->l; - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); replcuses(mkref(RTMP, ins - instrtab), it); return 1; } @@ -130,7 +130,7 @@ doins(Instr *ins, Block *blk, int *curi) } ins->l = lhs->l, ins->r = mkintcon(ins->cls, c); deluse(blk, ins - instrtab, mkref(RTMP, lhs - instrtab)); - if (!instruse[lhs - instrtab]) *lhs = mkinstr(Onop,0,); + if (!instruse[lhs - instrtab]) *lhs = mkinstr0(Onop,0); return 1; } } diff --git a/src/ir_ssa.c b/src/ir_ssa.c index f3fcb5d..6e7945b 100644 --- a/src/ir_ssa.c +++ b/src/ir_ssa.c @@ -35,7 +35,7 @@ copyopt(Function *fn) if (ins->cls != k) continue; replcuses(var, arg); - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); deluses(var.i); } } diff --git a/src/ir_stack.c b/src/ir_stack.c index d15a764..ff49805 100644 --- a/src/ir_stack.c +++ b/src/ir_stack.c @@ -18,7 +18,7 @@ lowerstack(Function *fn) fn->stksiz += siz; fn->stksiz = alignup(fn->stksiz, 1 << alignlog2); if (fn->stksiz > (1<<20)-1) error(NULL, "'%s' stack frame too big", fn->name); - *ins = mkinstr(Onop,0,); + *ins = mkinstr0(Onop,0); replcuses(mkref(RTMP, t), mkref(RSTACK, fn->stksiz)); } } diff --git a/src/t_aarch64_isel.c b/src/t_aarch64_isel.c index 16eb022..381a57d 100644 --- a/src/t_aarch64_isel.c +++ b/src/t_aarch64_isel.c @@ -74,7 +74,7 @@ static void regarg(Ref *r, enum irclass k, Block *blk, int *curi) { if (r->t != RTMP) { - *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, k, *r)); + *r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, k, *r)); if (kisflt(k) || instrtab[r->i].l.t == RSTACK) { int iprev = *curi-1; fixarg(&instrtab[r->i].l, &instrtab[r->i], blk, &iprev); @@ -123,15 +123,15 @@ fixarg(Ref *r, Instr *ins, Block *blk, int *curi) pun.f64 = contab.p[r->i].f; i = pun.i64; } - Ref gpr = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ki, mkintcon(ki, i))); - *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, k, gpr)); + Ref gpr = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, ki, mkintcon(ki, i))); + *r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, k, gpr)); } else if (oiscmp(op)) { return; } else { - *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, k, *r)); + *r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, k, *r)); } } else if (r->t == RSTACK) { - Instr adr = mkinstr(Osub, KPTR, mkref(RREG, FP), mkintcon(KI32, r->i)); + Instr adr = mkinstr2(Osub, KPTR, mkref(RREG, FP), mkintcon(KI32, r->i)); if (op == Ocopy) *ins = adr; else @@ -148,7 +148,7 @@ arithfold(Instr *ins) Ref r; bool ok = ins->r.t ? foldbinop(&r, ins->op, ins->cls, ins->l, ins->r) : foldunop(&r, ins->op, ins->cls, ins->l); assert(ok && "fold?"); - *ins = mkinstr(Ocopy, insrescls(*ins), r); + *ins = mkinstr1(Ocopy, insrescls(*ins), r); return 1; } return 0; @@ -173,44 +173,44 @@ selcall(Function *fn, Instr *ins, Block *blk, int *curi) if (!abi.isstk) { assert(!abi.ty.isagg); - *arg = mkinstr(Omove, call->abiarg[i].ty.cls, mkref(RREG, abi.reg), arg->r); + *arg = mkinstr2(Omove, call->abiarg[i].ty.cls, mkref(RREG, abi.reg), arg->r); } else { Ref adr = mkaddr((IRAddr){mkref(RREG, SP), .disp = abi.stk}); int iargsave = iarg; if (!abi.ty.isagg) { /* scalar arg in stack */ - *arg = mkinstr(cls2store[abi.ty.cls], 0, adr, arg->r); + *arg = mkinstr2(cls2store[abi.ty.cls], 0, adr, arg->r); if (isaddrcon(arg->r,1) || arg->r.t == RADDR) - arg->r = insertinstr(blk, iarg++, mkinstr(Ocopy, abi.ty.cls, arg->r)); + arg->r = insertinstr(blk, iarg++, mkinstr1(Ocopy, abi.ty.cls, arg->r)); else fixarg(&ins->r, ins, blk, &iarg); } else { /* aggregate arg in stack, callee stack frame destination address */ - *arg = mkinstr(Ocopy, KPTR, adr); + *arg = mkinstr1(Ocopy, KPTR, adr); } *curi += iarg - iargsave; } } if (call->argstksiz) { Ref disp = mkref(RICON, argstksiz); - insertinstr(blk, iarg--, (Instr){Osub, KPTR, .keep=1, .reg = SP+1, .l=mkref(RREG,SP), disp}); + insertinstr(blk, iarg--, (Instr){Osub, KPTR, .keep=1, .reg = SP+1, .l=mkref(RREG,SP), .r=disp}); ++*curi; - insertinstr(blk, *curi+1, (Instr){Oadd, KPTR, .keep=1, .reg = SP+1, .l=mkref(RREG,SP), disp}); + insertinstr(blk, *curi+1, (Instr){Oadd, KPTR, .keep=1, .reg = SP+1, .l=mkref(RREG,SP), .r=disp}); } if (isimm32(ins->l)) ins->l = mkaddr((IRAddr){.base = ins->l}); else if (isintcon(ins->l)) - ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->l)); + ins->l = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, ins->l)); cls = ins->cls; ins->cls = 0; if (cls) { /* duplicate to reuse same TMP ref */ insertinstr(blk, (*curi)++, *ins); - *ins = mkinstr(Ocopy, cls, mkref(RREG, call->abiret[0].reg)); + *ins = mkinstr1(Ocopy, cls, mkref(RREG, call->abiret[0].reg)); for (int i = 1; i <= 2; ++i) { if (*curi + i >= blk->ins.n) break; if (instrtab[blk->ins.p[*curi + i]].op == Ocall2r) { ins = &instrtab[blk->ins.p[*curi += i]]; - *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, call->abiret[1].reg)); + *ins = mkinstr1(Ocopy, ins->cls, mkref(RREG, call->abiret[1].reg)); break; } } @@ -280,7 +280,7 @@ aadd(IRAddr *addr, Block *blk, int *curi, Ref r, uint siz/*1,2,4,8*/) if (!rstest(mctarg->rglob, r.i)) return 0; Ref: if (r.t == RSTACK && (addr->base.bits || addr->index.bits)) { - r = insertinstr(blk, (*curi)++, mkinstr(Oadd, KPTR, mkref(RREG, FP), mkref(RICON, -r.i))); + r = insertinstr(blk, (*curi)++, mkinstr2(Oadd, KPTR, mkref(RREG, FP), mkref(RICON, -r.i))); } if (!addr->base.bits) addr->base = r; else if (!addr->index.bits) addr->index = r; @@ -304,9 +304,9 @@ fuseaddr(Ref *r, Block *blk, int *curi, uint siz/*1,2,4,8*/) if (isaddrcon(addr.base,0) && (!(contab.p[addr.base.i].flag & SLOCAL) || addr.index.bits)) { /* first load symbol address into a temp register */ if (addr.disp && (ccopt.pic || (contab.p[addr.base.i].flag & SFUNC)) && !addr.index.bits) { - addr.base = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, .l = addr.base)); + addr.base = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, addr.base)); } else { - addr.base = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, + addr.base = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, mkaddr((IRAddr){addr.base, .disp = addr.disp}))); addr.disp = 0; } @@ -344,7 +344,7 @@ loadstoreaddr(Block *blk, Ref *r, int *curi, enum op op) } else if (r->t == RTMP || r->t == RSTACK) { fuseaddr(r, blk, curi, siz); } else if (r->t != RREG) { - *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, *r)); + *r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, *r)); } } @@ -371,9 +371,9 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) case Oparam: assert(ins->l.t == RICON && ins->l.i < fn->nabiarg); if (!fn->abiarg[ins->l.i].isstk) - *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, fn->abiarg[ins->l.i].reg)); + *ins = mkinstr1(Ocopy, ins->cls, mkref(RREG, fn->abiarg[ins->l.i].reg)); else /* stack */ - *ins = mkinstr(Oadd, KPTR, mkref(RREG, FP), mkref(RICON, 16+fn->abiarg[ins->l.i].stk)); + *ins = mkinstr2(Oadd, KPTR, mkref(RREG, FP), mkref(RICON, 16+fn->abiarg[ins->l.i].stk)); break; case Oneg: case Onot: case Ocvtf32s: case Ocvtf32u: @@ -456,12 +456,12 @@ seljmp(Function *fn, Block *blk) enum irclass cls = c.t == RICON ? KI32 : c.t == RXCON && contab.p[c.i].cls ? contab.p[c.i].cls : KPTR; int curi = blk->ins.n; - c = insertinstr(blk, blk->ins.n, mkinstr(Ocopy, cls, c)); + c = insertinstr(blk, blk->ins.n, mkinstr1(Ocopy, cls, c)); sel(fn, &instrtab[c.i], blk, &curi); } if (!oiscmp(instrtab[c.i].op)) { enum irclass k = insrescls(instrtab[c.i]); - blk->jmp.arg[0] = insertinstr(blk, blk->ins.n, mkinstr(Oneq, k, c, kisint(k) ? ZEROREF : mkfltcon(k, 0))); + blk->jmp.arg[0] = insertinstr(blk, blk->ins.n, mkinstr2(Oneq, k, c, kisint(k) ? ZEROREF : mkfltcon(k, 0))); Instr *ins = &instrtab[blk->jmp.arg[0].i]; ins->keep = 1; } else { @@ -470,13 +470,13 @@ seljmp(Function *fn, Block *blk) } else if (blk->jmp.t == Jret) { if (blk->jmp.arg[0].bits) { Ref r = mkref(RREG, fn->abiret[0].reg); - Instr *ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr(Omove, fn->abiret[0].ty.cls, r, blk->jmp.arg[0])).i]; + Instr *ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr2(Omove, fn->abiret[0].ty.cls, r, blk->jmp.arg[0])).i]; int curi = blk->ins.n-1; fixarg(&ins->r, ins, blk, &curi); blk->jmp.arg[0] = r; if (blk->jmp.arg[1].bits) { r = mkref(RREG, fn->abiret[1].reg); - ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr(Omove, fn->abiret[1].ty.cls, r, blk->jmp.arg[1])).i]; + ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr2(Omove, fn->abiret[1].ty.cls, r, blk->jmp.arg[1])).i]; } } } diff --git a/src/t_x86-64_isel.c b/src/t_x86-64_isel.c index ac3950c..d4a22d4 100644 --- a/src/t_x86-64_isel.c +++ b/src/t_x86-64_isel.c @@ -40,7 +40,7 @@ static const uchar opflags[NOPER] = { static int iflagsrc = -1; -#define inscopy(blk, pcuri, k, r) insertinstr((blk), (*(pcuri))++, mkinstr(Ocopy, k, .l = (r))) +#define inscopy(blk, pcuri, k, r) insertinstr((blk), (*(pcuri))++, mkinstr1(Ocopy, k, (r))) static void picfixsym(Ref *r, Block *blk, int *curi) { @@ -110,7 +110,7 @@ Begin: ShiftImm: /* shift immediate is always 8bit */ *r = mkref(RICON, sh & 255); } else if (r->t == RSTACK) { - Instr adr = mkinstr(Oadd, KPTR, mkref(RREG, RBP), mkintcon(KI32, -r->i)); + Instr adr = mkinstr2(Oadd, KPTR, mkref(RREG, RBP), mkintcon(KI32, -r->i)); if (op == Ocopy) *ins = adr; else @@ -143,28 +143,28 @@ selcall(Function *fn, Instr *ins, Block *blk, int *curi) if (!abi.isstk) { assert(!abi.ty.isagg); - *arg = mkinstr(Omove, call->abiarg[i].ty.cls, mkref(RREG, abi.reg), arg->r); + *arg = mkinstr2(Omove, call->abiarg[i].ty.cls, mkref(RREG, abi.reg), arg->r); if (abi.reg >= XMM0) ++nsse; } else { Ref adr = mkaddr((IRAddr){mkref(RREG, RSP), .disp = abi.stk}); int iargsave = iarg; if (!abi.ty.isagg) { /* scalar arg in stack */ - *arg = mkinstr(cls2store[abi.ty.cls], 0, adr, arg->r); + *arg = mkinstr2(cls2store[abi.ty.cls], 0, adr, arg->r); if (isaddrcon(arg->r,1) || arg->r.t == RADDR) - arg->r = insertinstr(blk, iarg++, mkinstr(Ocopy, abi.ty.cls, arg->r)); + arg->r = insertinstr(blk, iarg++, mkinstr1(Ocopy, abi.ty.cls, arg->r)); else fixarg(&ins->r, ins, blk, &iarg); } else { /* aggregate arg in stack, callee stack frame destination address */ - *arg = mkinstr(Ocopy, KPTR, adr); + *arg = mkinstr1(Ocopy, KPTR, adr); } *curi += iarg - iargsave; } } if (call->argstksiz) { Ref disp = mkref(RICON, argstksiz); - insertinstr(blk, iarg--, (Instr){Osub, KPTR, .keep=1, .reg = RSP+1, .l=mkref(RREG,RSP), disp}); + insertinstr(blk, iarg--, (Instr){Osub, KPTR, .keep=1, .reg = RSP+1, .l=mkref(RREG,RSP), .r=disp}); ++*curi; - insertinstr(blk, *curi+1, (Instr){Oadd, KPTR, .keep=1, .reg = RSP+1, .l=mkref(RREG,RSP), disp}); + insertinstr(blk, *curi+1, (Instr){Oadd, KPTR, .keep=1, .reg = RSP+1, .l=mkref(RREG,RSP), .r=disp}); } if (isimm32(ins->l)) ins->l = mkaddr((IRAddr){.base = ins->l}); @@ -173,19 +173,20 @@ selcall(Function *fn, Instr *ins, Block *blk, int *curi) if (call->vararg >= 0) { /* variadic calls write number of sse regs used to AL */ - insertinstr(blk, (*curi)++, mkinstr(Omove, KI32, mkref(RREG, RAX), mkref(RICON, nsse), .keep=1)); + insertinstr(blk, (*curi)++, + (Instr){Omove, KI32, .keep = 1, .l = mkref(RREG, RAX), .r = mkref(RICON, nsse)}); } cls = ins->cls; ins->cls = 0; if (cls) { /* duplicate to reuse same TMP ref */ insertinstr(blk, (*curi)++, *ins); - *ins = mkinstr(Ocopy, cls, mkref(RREG, call->abiret[0].reg)); + *ins = mkinstr1(Ocopy, cls, mkref(RREG, call->abiret[0].reg)); for (int i = 1; i <= 2; ++i) { if (*curi + i >= blk->ins.n) break; if (instrtab[blk->ins.p[*curi + i]].op == Ocall2r) { ins = &instrtab[blk->ins.p[*curi += i]]; - *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, call->abiret[1].reg)); + *ins = mkinstr1(Ocopy, ins->cls, mkref(RREG, call->abiret[1].reg)); break; } } @@ -239,7 +240,7 @@ aadd(IRAddr *out, Block *blk, int *curi, Ref r, bool recurring) { if (r.t == RSTACK) { if (out->base.bits || !aimm(out, -r.i)) { - r = insertinstr(blk, (*curi)++, mkinstr(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, -r.i))); + r = insertinstr(blk, (*curi)++, mkinstr2(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, -r.i))); goto Ref; } out->base = mkref(RREG, RBP); @@ -344,7 +345,7 @@ loadstoreaddr(Block *blk, Ref *r, int *curi) } else if (r->t == RSTACK || (r->t == RTMP && addarg4addrp(*r))) { fuseaddr(r, blk, curi); } else if (r->t != RREG) { - *r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, *r)); + *r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, *r)); } } @@ -355,7 +356,7 @@ arithfold(Instr *ins) Ref r; bool ok = ins->r.t ? foldbinop(&r, ins->op, ins->cls, ins->l, ins->r) : foldunop(&r, ins->op, ins->cls, ins->l); if (ok) { - *ins = mkinstr(Ocopy, insrescls(*ins), r); + *ins = mkinstr1(Ocopy, insrescls(*ins), r); return 1; } } @@ -383,9 +384,9 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) case Oparam: assert(ins->l.t == RICON && ins->l.i < fn->nabiarg); if (!fn->abiarg[ins->l.i].isstk) - *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, fn->abiarg[ins->l.i].reg)); + *ins = mkinstr1(Ocopy, ins->cls, mkref(RREG, fn->abiarg[ins->l.i].reg)); else /* stack */ - *ins = mkinstr(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, 16+fn->abiarg[ins->l.i].stk)); + *ins = mkinstr2(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, 16+fn->abiarg[ins->l.i].stk)); break; case Oarg: fixarg(&ins->r, ins, blk, curi); @@ -398,7 +399,7 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) case Oshl: case Osar: case Oslr: if (!isintcon(ins->r)) { /* shift amount register is always CL */ - insertinstr(blk, (*curi)++, mkinstr(Omove, KI32, mkref(RREG, RCX), ins->r)); + insertinstr(blk, (*curi)++, mkinstr2(Omove, KI32, mkref(RREG, RCX), ins->r)); ins->r = mkref(RREG, RCX); } goto ALU; @@ -422,17 +423,17 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) /* TODO fuse div/rem pair */ /* (I)DIV dividend is always in RDX:RAX, output also in those regs */ - insertinstr(blk, (*curi)++, mkinstr(Omove, ins->cls, mkref(RREG, RAX), ins->l)); + insertinstr(blk, (*curi)++, mkinstr2(Omove, ins->cls, mkref(RREG, RAX), ins->l)); /* mark RDX as clobbered. sign/zero-extending RAX into RDX is handled in emit() */ - insertinstr(blk, (*curi)++, mkinstr(Omove, ins->cls, mkref(RREG, RDX), mkref(RREG, RDX))); + insertinstr(blk, (*curi)++, mkinstr2(Omove, ins->cls, mkref(RREG, RDX), mkref(RREG, RDX))); fixarg(&ins->r, ins, blk, curi); /* make sure rhs is memory or reg */ ins->l = mkref(RREG, RAX); ins->keep = 1; if (op == Orem) ins->op = Odiv; else if (op == Ourem) ins->op = Oudiv; insertinstr(blk, (*curi)++, *ins); /* duplicate ins to reuse tmp ref */ - *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, op < Orem ? RAX : RDX)); /* get output */ - temp = mkinstr(Ocopy, ins->cls, mkref(RREG, op < Orem ? RDX : RAX)); /* clobber other reg*/ + *ins = mkinstr1(Ocopy, ins->cls, mkref(RREG, op < Orem ? RAX : RDX)); /* get output */ + temp = mkinstr1(Ocopy, ins->cls, mkref(RREG, op < Orem ? RDX : RAX)); /* clobber other reg*/ insertinstr(blk, ++(*curi), temp); /* swap instrs so that clobber goes first */ t = blk->ins.p[*curi - 1]; @@ -461,7 +462,7 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) if (kisint(ins->cls) && (addarg4addrp(ins->l) || addarg4addrp(ins->r))) { Ref it = mkref(RTMP, ins - instrtab); if (fuseaddr(&it, blk, curi)) { - *ins = mkinstr(Ocopy, ins->cls, it); + *ins = mkinstr1(Ocopy, ins->cls, it); break; } } @@ -490,7 +491,7 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) ins->inplace = 1; if (iscon(ins->l) || ins->l.t == RSTACK) { fixarg(&ins->l, ins, blk, curi); - ins->l = insertinstr(blk, (*curi)++, mkinstr(Ocopy, ins->cls, ins->l)); + ins->l = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, ins->cls, ins->l)); } if (ins->r.bits) case Omove: @@ -505,19 +506,19 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) case Ostorei8: case Ostorei16: case Ostorei32: case Ostorei64: case Ostoref32: case Ostoref64: loadstoreaddr(blk, &ins->l, curi); if (isaddrcon(ins->r,1) || ins->r.t == RADDR) - ins->r = insertinstr(blk, (*curi)++, mkinstr(Ocopy, KPTR, ins->r)); + ins->r = insertinstr(blk, (*curi)++, mkinstr1(Ocopy, KPTR, ins->r)); else fixarg(&ins->r, ins, blk, curi); break; case Ocvtu32f: fixarg(&ins->l, ins, blk, curi); - ins->l = insertinstr(blk, (*curi)++, mkinstr(Oextu32, KI64, ins->l)); + ins->l = insertinstr(blk, (*curi)++, mkinstr1(Oextu32, KI64, ins->l)); ins->op = Ocvts64f; break; case Ocvtf32u: case Ocvtf64u: fixarg(&ins->l, ins, blk, curi); if (ins->cls == KI32) { - ins->l = insertinstr(blk, (*curi)++, mkinstr(ins->op == Ocvtf32u ? Ocvtf32s : Ocvtf64s, KI64, ins->l)); + ins->l = insertinstr(blk, (*curi)++, mkinstr1(ins->op == Ocvtf32u ? Ocvtf32s : Ocvtf64s, KI64, ins->l)); ins->op = Oextu32; } else assert(!"nyi flt -> u64"); break; @@ -546,7 +547,7 @@ sel(Function *fn, Instr *ins, Block *blk, int *curi) case Obswap16: case Obswap32: case Obswap64: ins->inplace = 1; if (ins->l.t != RTMP) { - ins->l = insertinstr(blk, *curi, mkinstr(Ocopy, ins->cls, ins->l)); + ins->l = insertinstr(blk, *curi, mkinstr1(Ocopy, ins->cls, ins->l)); fixarg(&instrtab[ins->l.i].l, ins, blk, curi); ++*curi; } @@ -575,7 +576,7 @@ seljmp(Function *fn, Block *blk) enum irclass cls = c.t == RICON ? KI32 : c.t == RXCON && contab.p[c.i].cls ? contab.p[c.i].cls : KPTR; int curi = blk->ins.n; - c = insertinstr(blk, blk->ins.n, mkinstr(Ocopy, cls, c)); + c = insertinstr(blk, blk->ins.n, mkinstr1(Ocopy, cls, c)); sel(fn, &instrtab[c.i], blk, &curi); } if (iflagsrc == c.i /* test cmp */ @@ -585,10 +586,10 @@ seljmp(Function *fn, Block *blk) if (kisflt(instrtab[c.i].cls) || !(opflags[instrtab[c.i].op] & ZF) || blk->ins.n == 0 || c.i != blk->ins.p[blk->ins.n - 1]) { Instr *ins; int curi = blk->ins.n; - blk->jmp.arg[0] = insertinstr(blk, blk->ins.n, mkinstr(Oneq, insrescls(instrtab[c.i]), c, ZEROREF)); + blk->jmp.arg[0] = insertinstr(blk, blk->ins.n, mkinstr2(Oneq, insrescls(instrtab[c.i]), c, ZEROREF)); ins = &instrtab[blk->jmp.arg[0].i]; if (kisflt(ins->cls)) { - ins->r = insertinstr(blk, curi, mkinstr(Ocopy, ins->cls, ZEROREF)); + ins->r = insertinstr(blk, curi, mkinstr1(Ocopy, ins->cls, ZEROREF)); } ins->keep = 1; } else if (instrtab[c.i].op == Oadd) { @@ -600,13 +601,13 @@ seljmp(Function *fn, Block *blk) if (blk->jmp.arg[0].bits) { int curi; Ref r = mkref(RREG, fn->abiret[0].reg); - Instr *ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr(Omove, fn->abiret[0].ty.cls, r, blk->jmp.arg[0])).i]; + Instr *ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr2(Omove, fn->abiret[0].ty.cls, r, blk->jmp.arg[0])).i]; curi = blk->ins.n-1; fixarg(&ins->r, ins, blk, &curi); blk->jmp.arg[0] = r; if (blk->jmp.arg[1].bits) { r = mkref(RREG, fn->abiret[1].reg); - ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr(Omove, fn->abiret[1].ty.cls, r, blk->jmp.arg[1])).i]; + ins = &instrtab[insertinstr(blk, blk->ins.n, mkinstr2(Omove, fn->abiret[1].ty.cls, r, blk->jmp.arg[1])).i]; curi = blk->ins.n-1; fixarg(&ins->r, ins, blk, &curi); blk->jmp.arg[1] = r; diff --git a/src/t_x86-64_sysv.c b/src/t_x86-64_sysv.c index 6477af2..852aa24 100644 --- a/src/t_x86-64_sysv.c +++ b/src/t_x86-64_sysv.c @@ -179,7 +179,7 @@ vastart(Function *fn, Block *blk, int *curi) assert(instrtab[rsave.i].op == Oalloca16); } else { rsave = insertinstr(fn->entry, 0, mkalloca(192, 16)); - insertinstr(fn->entry, 1, mkinstr(Oxvaprologue, 0, rsave, .keep=1)); + insertinstr(fn->entry, 1, (Instr){Oxvaprologue, 0, .keep=1, .l=rsave}); } /* find first unnamed gpr and fpr */ for (int i = 0; i < fn->nabiarg; ++i) { @@ -192,19 +192,19 @@ vastart(Function *fn, Block *blk, int *curi) } } /* set ap->reg_save_area */ - *ins = mkinstr(Oadd, KPTR, ap, mkref(RICON, 16)); + *ins = mkinstr2(Oadd, KPTR, ap, mkref(RICON, 16)); dst = mkref(RTMP, ins - instrtab); int i = *curi + 1; - insertinstr(blk, i++, mkinstr(Ostorei64, 0, dst, rsave)); + insertinstr(blk, i++, mkinstr2(Ostorei64, 0, dst, rsave)); /* set ap->overflow_arg_area */ - src = insertinstr(blk, i++, mkinstr(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, 16+stk0))); - dst = insertinstr(blk, i++, mkinstr(Oadd, KPTR, ap, mkref(RICON, 8))); - insertinstr(blk, i++, mkinstr(Ostorei64, 0, dst, src)); + src = insertinstr(blk, i++, mkinstr2(Oadd, KPTR, mkref(RREG, RBP), mkref(RICON, 16+stk0))); + dst = insertinstr(blk, i++, mkinstr2(Oadd, KPTR, ap, mkref(RICON, 8))); + insertinstr(blk, i++, mkinstr2(Ostorei64, 0, dst, src)); /* set ap->gp_offset */ - insertinstr(blk, i++, mkinstr(Ostorei32, 0, ap, mkref(RICON, gpr0*8))); + insertinstr(blk, i++, mkinstr2(Ostorei32, 0, ap, mkref(RICON, gpr0*8))); /* set ap->fp_offset */ - dst = insertinstr(blk, i++, mkinstr(Oadd, KPTR, ap, mkref(RICON, 4))); - insertinstr(blk, i++, mkinstr(Ostorei32, 0, dst, mkref(RICON, 6*8 + fpr0*16))); + dst = insertinstr(blk, i++, mkinstr2(Oadd, KPTR, ap, mkref(RICON, 4))); + insertinstr(blk, i++, mkinstr2(Ostorei32, 0, dst, mkref(RICON, 6*8 + fpr0*16))); *curi = i-1; } @@ -231,9 +231,9 @@ vaarg(Function *fn, Block *blk, int *curi) Ref phi, phiargs[2]; /* int: l->gp_offset < 48 - num_gp * 8 */ /* sse: l->fp_offset < 304 - num_gp * 16 (why 304? ... 176) */ - tmp = ni ? ap : insertinstr(blk, (*curi)++, mkinstr(Oadd, KPTR, ap, mkref(RICON, 4))); - tmp = insertinstr(blk, (*curi)++, mkinstr(Oloadu32, KI32, tmp)); - tmp = insertinstr(blk, (*curi)++, mkinstr(Oulte, KI32, tmp, mkref(RICON, ni ? 48 - ni*8 : 176 - nf*16))); + tmp = ni ? ap : insertinstr(blk, (*curi)++, mkinstr2(Oadd, KPTR, ap, mkref(RICON, 4))); + tmp = insertinstr(blk, (*curi)++, mkinstr1(Oloadu32, KI32, tmp)); + tmp = insertinstr(blk, (*curi)++, mkinstr2(Oulte, KI32, tmp, mkref(RICON, ni ? 48 - ni*8 : 176 - nf*16))); merge = blksplitafter(fn, blk, *curi); blk->jmp.t = 0; useblk(fn, blk); @@ -241,12 +241,12 @@ vaarg(Function *fn, Block *blk, int *curi) useblk(fn, blk->s1); { /* phi0: &l->reg_save_area[l->gp/fp_offset] */ - Ref sav = addinstr(fn, mkinstr(Oloadi64, KPTR, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, 16)))); - Ref roff = addinstr(fn, mkinstr(Oloadu32, KI32, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, ni ? 0 : 4)))); + Ref sav = addinstr(fn, mkinstr1(Oloadi64, KPTR, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, 16)))); + Ref roff = addinstr(fn, mkinstr1(Oloadu32, KI32, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, ni ? 0 : 4)))); phiargs[0] = irbinop(fn, Oadd, KPTR, sav, roff); /* l->gp/fp_offset += num_gp/fp * 8(16) */ roff = irbinop(fn, Oadd, KI32, roff, mkref(RICON, ni ? ni * 8 : nf * 16)); - addinstr(fn, mkinstr(Ostorei32, 0, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, ni ? 0 : 4)), roff)); + addinstr(fn, mkinstr2(Ostorei32, 0, irbinop(fn, Oadd, KPTR, ap, mkref(RICON, ni ? 0 : 4)), roff)); assert(merge->npred == 1); blkpred(merge, 0) = blk->s1; blk->s1->jmp.t = Jb; @@ -256,13 +256,13 @@ vaarg(Function *fn, Block *blk, int *curi) { /* phi1: l->overflow_arg_area */ Ref adr = irbinop(fn, Oadd, KPTR, ap, mkref(RICON, 8)); - Ref ovf = addinstr(fn, mkinstr(Oloadi64, KPTR, adr)); + Ref ovf = addinstr(fn, mkinstr1(Oloadi64, KPTR, adr)); /* align no-op */ phiargs[1] = ovf; /* update l->overflow_arg_area += size */ int siz = 8; - addinstr(fn, mkinstr(Ostorei64, 0, adr, irbinop(fn, Oadd, KPTR, ovf, mkref(RICON, siz)))); + addinstr(fn, mkinstr2(Ostorei64, 0, adr, irbinop(fn, Oadd, KPTR, ovf, mkref(RICON, siz)))); putbranch(fn, merge); } assert(merge->npred == 2); @@ -272,11 +272,11 @@ vaarg(Function *fn, Block *blk, int *curi) phi = insertphi(merge, KPTR); memcpy(phitab.p[instrtab[phi.i].l.i], phiargs, sizeof phiargs); if (!ty.isagg) { - instrtab[var] = mkinstr(cls2load[cls[0]], cls[0], phi); + instrtab[var] = mkinstr1(cls2load[cls[0]], cls[0], phi); } else { instrtab[var] = mkalloca(8, 8); - tmp = insertinstr(merge, 1, mkinstr(Oloadi64, KI64, phi)); - insertinstr(merge, 2, mkinstr(Ostorei64, 0, mkref(RTMP, var), tmp)); + tmp = insertinstr(merge, 1, mkinstr1(Oloadi64, KI64, phi)); + insertinstr(merge, 2, mkinstr2(Ostorei64, 0, mkref(RTMP, var), tmp)); } fn->prop &= ~FNUSE; } else { -- cgit v1.2.3