FTLSaveRestore.cpp [plain text]
#include "config.h"
#include "FTLSaveRestore.h"
#if ENABLE(FTL_JIT)
#include "FPRInfo.h"
#include "GPRInfo.h"
#include "MacroAssembler.h"
#include "RegisterSet.h"
namespace JSC { namespace FTL {
static size_t bytesForGPRs()
{
return MacroAssembler::numberOfRegisters() * sizeof(int64_t);
}
static size_t bytesForFPRs()
{
return MacroAssembler::numberOfFPRegisters() * sizeof(double);
}
size_t requiredScratchMemorySizeInBytes()
{
return bytesForGPRs() + bytesForFPRs();
}
size_t offsetOfGPR(GPRReg reg)
{
return MacroAssembler::registerIndex(reg) * sizeof(int64_t);
}
size_t offsetOfFPR(FPRReg reg)
{
return bytesForGPRs() + MacroAssembler::fpRegisterIndex(reg) * sizeof(double);
}
size_t offsetOfReg(Reg reg)
{
if (reg.isGPR())
return offsetOfGPR(reg.gpr());
return offsetOfFPR(reg.fpr());
}
namespace {
struct Regs {
Regs()
{
special = RegisterSet::stackRegisters();
special.merge(RegisterSet::reservedHardwareRegisters());
first = MacroAssembler::firstRegister();
while (special.get(first))
first = MacroAssembler::nextRegister(first);
second = MacroAssembler::nextRegister(first);
while (special.get(second))
second = MacroAssembler::nextRegister(second);
}
RegisterSet special;
GPRReg first;
GPRReg second;
};
}
void saveAllRegisters(MacroAssembler& jit, char* scratchMemory)
{
Regs regs;
jit.poke64(regs.first, 0);
jit.move(MacroAssembler::TrustedImmPtr(scratchMemory), regs.first);
for (MacroAssembler::RegisterID reg = regs.second; reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
if (regs.special.get(reg))
continue;
jit.store64(reg, MacroAssembler::Address(regs.first, offsetOfGPR(reg)));
}
jit.peek64(regs.second, 0);
jit.store64(regs.second, MacroAssembler::Address(regs.first, offsetOfGPR(regs.first)));
for (MacroAssembler::FPRegisterID reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = MacroAssembler::nextFPRegister(reg)) {
if (regs.special.get(reg))
continue;
jit.storeDouble(reg, MacroAssembler::Address(regs.first, offsetOfFPR(reg)));
}
}
void restoreAllRegisters(MacroAssembler& jit, char* scratchMemory)
{
Regs regs;
jit.move(MacroAssembler::TrustedImmPtr(scratchMemory), regs.first);
for (MacroAssembler::FPRegisterID reg = MacroAssembler::firstFPRegister(); reg <= MacroAssembler::lastFPRegister(); reg = MacroAssembler::nextFPRegister(reg)) {
if (regs.special.get(reg))
continue;
jit.loadDouble(MacroAssembler::Address(regs.first, offsetOfFPR(reg)), reg);
}
for (MacroAssembler::RegisterID reg = regs.second; reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
if (regs.special.get(reg))
continue;
jit.load64(MacroAssembler::Address(regs.first, offsetOfGPR(reg)), reg);
}
jit.load64(MacroAssembler::Address(regs.first, offsetOfGPR(regs.first)), regs.first);
}
} }
#endif // ENABLE(FTL_JIT)