void lower(VLS& env, syncvmrettype& inst, Vlabel b, size_t i) { switch (arch()) { case Arch::X64: // fall through case Arch::PPC64: env.unit.blocks[b].code[i] = copy{inst.type, rret_type()}; break; case Arch::ARM: // For ARM64 we need to clear the bits 8..31 from the type value. // That allows us to use the resulting register values in // type comparisons without the need for truncation there. // We must not touch bits 63..32 as they contain the AUX data. lower_impl(env.unit, b, i, [&] (Vout& v) { v << andq{v.cns(0xffffffff000000ff), inst.type, rret_type(), v.makeReg()}; }); break; } }
void lower(VLS& env, vcallarray& inst, Vlabel b, size_t i) { // vcallarray can only appear at the end of a block. assertx(i == env.unit.blocks[b].code.size() - 1); lower_impl(env.unit, b, i, [&] (Vout& v) { auto const& srcs = env.unit.tuples[inst.extraArgs]; auto args = inst.args; auto dsts = jit::vector<Vreg>{}; for (auto i = 0; i < srcs.size(); ++i) { dsts.emplace_back(rarg(i)); args |= rarg(i); } v << copyargs{env.unit.makeTuple(srcs), env.unit.makeTuple(std::move(dsts))}; v << callarray{inst.target, args}; v << unwind{{inst.targets[0], inst.targets[1]}}; }); }
nir_foreach_overload(shader, overload) { if (overload->impl) lower_impl(overload->impl, shader_program, shader->stage); }