// Return the set of physical registers implicitly accessed (used or defined) // TODO: t4779515: replace this, and other switches, with logic using // attributes, instead of hardcoded opcode names. void getEffects(const Abi& abi, const Vinstr& i, RegSet& uses, RegSet& defs) { uses = defs = RegSet(); switch (i.op) { case Vinstr::mccall: case Vinstr::call: case Vinstr::callm: case Vinstr::callr: defs = abi.all() - abi.calleeSaved; break; case Vinstr::callstub: defs = i.callstub_.kills; break; case Vinstr::bindcall: case Vinstr::contenter: defs = abi.all(); break; case Vinstr::cqo: uses = RegSet(rax); defs = RegSet(rdx); break; case Vinstr::idiv: uses = defs = RegSet(rax).add(rdx); break; case Vinstr::shlq: case Vinstr::sarq: uses = RegSet(rcx); break; default: break; } }
void getEffects(const Abi& abi, const Vinstr& i, RegSet& uses, RegSet& across, RegSet& defs) { uses = defs = across = RegSet(); switch (i.op) { case Vinstr::mccall: case Vinstr::call: case Vinstr::callm: case Vinstr::callr: defs = abi.all() - abi.calleeSaved; switch (arch()) { case Arch::ARM: defs.add(PhysReg(arm::rLinkReg)); defs.remove(PhysReg(arm::rVmFp)); break; case Arch::X64: defs.remove(reg::rbp); break; } break; case Vinstr::bindcall: defs = abi.all(); switch (arch()) { case Arch::ARM: break; case Arch::X64: defs.remove(x64::rVmTl); break; } break; case Vinstr::contenter: case Vinstr::callstub: defs = abi.all(); switch (arch()) { case Arch::ARM: defs.remove(PhysReg(arm::rVmFp)); break; case Arch::X64: defs -= reg::rbp | x64::rVmTl; break; } break; case Vinstr::cqo: uses = RegSet(reg::rax); defs = reg::rax | reg::rdx; break; case Vinstr::idiv: uses = defs = reg::rax | reg::rdx; break; case Vinstr::shlq: case Vinstr::sarq: across = RegSet(reg::rcx); break; // arm instrs case Vinstr::hostcall: defs = (abi.all() - abi.calleeSaved) | RegSet(PhysReg(arm::rHostCallReg)); break; case Vinstr::vcall: case Vinstr::vinvoke: case Vinstr::vcallstub: always_assert(false && "Unsupported instruction in vxls"); default: break; } }
void getEffects(const Abi& abi, const Vinstr& i, RegSet& uses, RegSet& across, RegSet& defs) { uses = defs = across = RegSet(); switch (i.op) { case Vinstr::mccall: case Vinstr::call: case Vinstr::callm: case Vinstr::callr: defs = abi.all() - (abi.calleeSaved | rvmfp()); switch (arch()) { case Arch::ARM: defs.add(PhysReg(arm::rLinkReg)); break; case Arch::X64: break; case Arch::PPC64: not_implemented(); break; } break; case Vinstr::bindcall: defs = abi.all(); switch (arch()) { case Arch::ARM: break; case Arch::X64: defs.remove(rvmtl()); break; case Arch::PPC64: not_implemented(); break; } break; case Vinstr::contenter: case Vinstr::callarray: defs = abi.all() - RegSet(rvmfp()); switch (arch()) { case Arch::ARM: break; case Arch::X64: defs.remove(rvmtl()); break; case Arch::PPC64: not_implemented(); break; } break; case Vinstr::callfaststub: defs = abi.all() - abi.calleeSaved - abi.gpUnreserved; break; case Vinstr::cqo: uses = RegSet(reg::rax); defs = reg::rax | reg::rdx; break; case Vinstr::idiv: uses = defs = reg::rax | reg::rdx; break; case Vinstr::shlq: case Vinstr::sarq: across = RegSet(reg::rcx); break; // arm instrs case Vinstr::hostcall: defs = (abi.all() - abi.calleeSaved) | RegSet(PhysReg(arm::rHostCallReg)); break; case Vinstr::vcall: case Vinstr::vinvoke: case Vinstr::vcallarray: always_assert(false && "Unsupported instruction in vxls"); default: break; } }