ARM64: push/pop registers in stubs for safepoints

BUG=

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/209933003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@20210 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ff1186c8
......@@ -1133,6 +1133,39 @@ void StoreBufferOverflowStub::GenerateFixedRegStubsAheadOfTime(
}
void StoreRegistersStateStub::Generate(MacroAssembler* masm) {
MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm);
UseScratchRegisterScope temps(masm);
Register saved_lr = temps.UnsafeAcquire(to_be_pushed_lr());
Register return_address = temps.AcquireX();
__ Mov(return_address, lr);
// Restore lr with the value it had before the call to this stub (the value
// which must be pushed).
__ Mov(lr, saved_lr);
if (save_doubles_ == kSaveFPRegs) {
__ PushSafepointRegistersAndDoubles();
} else {
__ PushSafepointRegisters();
}
__ Ret(return_address);
}
void RestoreRegistersStateStub::Generate(MacroAssembler* masm) {
MacroAssembler::NoUseRealAbortsScope no_use_real_aborts(masm);
UseScratchRegisterScope temps(masm);
Register return_address = temps.AcquireX();
// Preserve the return address (lr will be clobbered by the pop).
__ Mov(return_address, lr);
if (save_doubles_ == kSaveFPRegs) {
__ PopSafepointRegistersAndDoubles();
} else {
__ PopSafepointRegisters();
}
__ Ret(return_address);
}
void MathPowStub::Generate(MacroAssembler* masm) {
// Stack on entry:
// jssp[0]: Exponent (as a tagged value).
......@@ -1394,10 +1427,28 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
BinaryOpICStub::GenerateAheadOfTime(isolate);
StoreRegistersStateStub::GenerateAheadOfTime(isolate);
RestoreRegistersStateStub::GenerateAheadOfTime(isolate);
BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
}
void StoreRegistersStateStub::GenerateAheadOfTime(Isolate* isolate) {
StoreRegistersStateStub stub1(kDontSaveFPRegs);
stub1.GetCode(isolate);
StoreRegistersStateStub stub2(kSaveFPRegs);
stub2.GetCode(isolate);
}
void RestoreRegistersStateStub::GenerateAheadOfTime(Isolate* isolate) {
RestoreRegistersStateStub stub1(kDontSaveFPRegs);
stub1.GetCode(isolate);
RestoreRegistersStateStub stub2(kSaveFPRegs);
stub2.GetCode(isolate);
}
void CodeStub::GenerateFPStubs(Isolate* isolate) {
// Floating-point code doesn't get special handling in ARM64, so there's
// nothing to do here.
......
......@@ -77,6 +77,37 @@ class StringHelper : public AllStatic {
};
class StoreRegistersStateStub: public PlatformCodeStub {
public:
explicit StoreRegistersStateStub(SaveFPRegsMode with_fp)
: save_doubles_(with_fp) {}
static Register to_be_pushed_lr() { return ip0; }
static void GenerateAheadOfTime(Isolate* isolate);
private:
Major MajorKey() { return StoreRegistersState; }
int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
SaveFPRegsMode save_doubles_;
void Generate(MacroAssembler* masm);
};
class RestoreRegistersStateStub: public PlatformCodeStub {
public:
explicit RestoreRegistersStateStub(SaveFPRegsMode with_fp)
: save_doubles_(with_fp) {}
static void GenerateAheadOfTime(Isolate* isolate);
private:
Major MajorKey() { return RestoreRegistersState; }
int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
SaveFPRegsMode save_doubles_;
void Generate(MacroAssembler* masm);
};
class RecordWriteStub: public PlatformCodeStub {
public:
// Stub to record the write of 'value' at 'address' in 'object'.
......
......@@ -377,14 +377,23 @@ class LCodeGen: public LCodeGenBase {
ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
codegen_->expected_safepoint_kind_ = kind;
UseScratchRegisterScope temps(codegen_->masm_);
// Preserve the value of lr which must be saved on the stack (the call to
// the stub will clobber it).
Register to_be_pushed_lr =
temps.UnsafeAcquire(StoreRegistersStateStub::to_be_pushed_lr());
codegen_->masm_->Mov(to_be_pushed_lr, lr);
switch (codegen_->expected_safepoint_kind_) {
case Safepoint::kWithRegisters:
codegen_->masm_->PushSafepointRegisters();
case Safepoint::kWithRegisters: {
StoreRegistersStateStub stub(kDontSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
case Safepoint::kWithRegistersAndDoubles:
codegen_->masm_->PushSafepointRegisters();
codegen_->masm_->PushSafepointFPRegisters();
}
case Safepoint::kWithRegistersAndDoubles: {
StoreRegistersStateStub stub(kSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
}
default:
UNREACHABLE();
}
......@@ -394,13 +403,16 @@ class LCodeGen: public LCodeGenBase {
Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
ASSERT((kind & Safepoint::kWithRegisters) != 0);
switch (kind) {
case Safepoint::kWithRegisters:
codegen_->masm_->PopSafepointRegisters();
case Safepoint::kWithRegisters: {
RestoreRegistersStateStub stub(kDontSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
case Safepoint::kWithRegistersAndDoubles:
codegen_->masm_->PopSafepointFPRegisters();
codegen_->masm_->PopSafepointRegisters();
}
case Safepoint::kWithRegistersAndDoubles: {
RestoreRegistersStateStub stub(kSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break;
}
default:
UNREACHABLE();
}
......
......@@ -4163,15 +4163,17 @@ void MacroAssembler::PushSafepointRegisters() {
}
void MacroAssembler::PushSafepointFPRegisters() {
void MacroAssembler::PushSafepointRegistersAndDoubles() {
PushSafepointRegisters();
PushCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
FPRegister::kAllocatableFPRegisters));
}
void MacroAssembler::PopSafepointFPRegisters() {
void MacroAssembler::PopSafepointRegistersAndDoubles() {
PopCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
FPRegister::kAllocatableFPRegisters));
PopSafepointRegisters();
}
......@@ -5120,6 +5122,14 @@ CPURegister UseScratchRegisterScope::AcquireNextAvailable(
}
CPURegister UseScratchRegisterScope::UnsafeAcquire(CPURegList* available,
const CPURegister& reg) {
ASSERT(available->IncludesAliasOf(reg));
available->Remove(reg);
return reg;
}
#define __ masm->
......
......@@ -1728,8 +1728,8 @@ class MacroAssembler : public Assembler {
void PushSafepointRegisters();
void PopSafepointRegisters();
void PushSafepointFPRegisters();
void PopSafepointFPRegisters();
void PushSafepointRegistersAndDoubles();
void PopSafepointRegistersAndDoubles();
// Store value in register src in the safepoint stack slot for register dst.
void StoreToSafepointRegisterSlot(Register src, Register dst) {
......@@ -2215,11 +2215,17 @@ class UseScratchRegisterScope {
FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
Register UnsafeAcquire(const Register& reg) {
return UnsafeAcquire(available_, reg);
}
Register AcquireSameSizeAs(const Register& reg);
FPRegister AcquireSameSizeAs(const FPRegister& reg);
private:
static CPURegister AcquireNextAvailable(CPURegList* available);
static CPURegister UnsafeAcquire(CPURegList* available,
const CPURegister& reg);
// Available scratch registers.
CPURegList* available_; // kRegister
......
......@@ -100,8 +100,8 @@ namespace internal {
V(StringLength) \
V(KeyedStringLength)
// List of code stubs only used on ARM platforms.
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64)
// List of code stubs only used on ARM 32 bits platforms.
#if V8_TARGET_ARCH_ARM
#define CODE_STUB_LIST_ARM(V) \
V(GetProperty) \
V(SetProperty) \
......@@ -111,6 +111,19 @@ namespace internal {
#define CODE_STUB_LIST_ARM(V)
#endif
// List of code stubs only used on ARM 64 bits platforms.
#if V8_TARGET_ARCH_ARM64
#define CODE_STUB_LIST_ARM64(V) \
V(GetProperty) \
V(SetProperty) \
V(InvokeBuiltin) \
V(DirectCEntry) \
V(StoreRegistersState) \
V(RestoreRegistersState)
#else
#define CODE_STUB_LIST_ARM64(V)
#endif
// List of code stubs only used on MIPS platforms.
#if V8_TARGET_ARCH_MIPS
#define CODE_STUB_LIST_MIPS(V) \
......@@ -126,6 +139,7 @@ namespace internal {
#define CODE_STUB_LIST(V) \
CODE_STUB_LIST_ALL_PLATFORMS(V) \
CODE_STUB_LIST_ARM(V) \
CODE_STUB_LIST_ARM64(V) \
CODE_STUB_LIST_MIPS(V)
// Stub is base classes of all stubs.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment