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( ...@@ -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) { void MathPowStub::Generate(MacroAssembler* masm) {
// Stack on entry: // Stack on entry:
// jssp[0]: Exponent (as a tagged value). // jssp[0]: Exponent (as a tagged value).
...@@ -1394,10 +1427,28 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { ...@@ -1394,10 +1427,28 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
CreateAllocationSiteStub::GenerateAheadOfTime(isolate); CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
BinaryOpICStub::GenerateAheadOfTime(isolate); BinaryOpICStub::GenerateAheadOfTime(isolate);
StoreRegistersStateStub::GenerateAheadOfTime(isolate);
RestoreRegistersStateStub::GenerateAheadOfTime(isolate);
BinaryOpICWithAllocationSiteStub::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) { void CodeStub::GenerateFPStubs(Isolate* isolate) {
// Floating-point code doesn't get special handling in ARM64, so there's // Floating-point code doesn't get special handling in ARM64, so there's
// nothing to do here. // nothing to do here.
......
...@@ -77,6 +77,37 @@ class StringHelper : public AllStatic { ...@@ -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 { class RecordWriteStub: public PlatformCodeStub {
public: public:
// Stub to record the write of 'value' at 'address' in 'object'. // Stub to record the write of 'value' at 'address' in 'object'.
......
...@@ -377,14 +377,23 @@ class LCodeGen: public LCodeGenBase { ...@@ -377,14 +377,23 @@ class LCodeGen: public LCodeGenBase {
ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple); ASSERT(codegen_->expected_safepoint_kind_ == Safepoint::kSimple);
codegen_->expected_safepoint_kind_ = kind; 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_) { switch (codegen_->expected_safepoint_kind_) {
case Safepoint::kWithRegisters: case Safepoint::kWithRegisters: {
codegen_->masm_->PushSafepointRegisters(); StoreRegistersStateStub stub(kDontSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break; break;
case Safepoint::kWithRegistersAndDoubles: }
codegen_->masm_->PushSafepointRegisters(); case Safepoint::kWithRegistersAndDoubles: {
codegen_->masm_->PushSafepointFPRegisters(); StoreRegistersStateStub stub(kSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break; break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -394,13 +403,16 @@ class LCodeGen: public LCodeGenBase { ...@@ -394,13 +403,16 @@ class LCodeGen: public LCodeGenBase {
Safepoint::Kind kind = codegen_->expected_safepoint_kind_; Safepoint::Kind kind = codegen_->expected_safepoint_kind_;
ASSERT((kind & Safepoint::kWithRegisters) != 0); ASSERT((kind & Safepoint::kWithRegisters) != 0);
switch (kind) { switch (kind) {
case Safepoint::kWithRegisters: case Safepoint::kWithRegisters: {
codegen_->masm_->PopSafepointRegisters(); RestoreRegistersStateStub stub(kDontSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break; break;
case Safepoint::kWithRegistersAndDoubles: }
codegen_->masm_->PopSafepointFPRegisters(); case Safepoint::kWithRegistersAndDoubles: {
codegen_->masm_->PopSafepointRegisters(); RestoreRegistersStateStub stub(kSaveFPRegs);
codegen_->masm_->CallStub(&stub);
break; break;
}
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -4163,15 +4163,17 @@ void MacroAssembler::PushSafepointRegisters() { ...@@ -4163,15 +4163,17 @@ void MacroAssembler::PushSafepointRegisters() {
} }
void MacroAssembler::PushSafepointFPRegisters() { void MacroAssembler::PushSafepointRegistersAndDoubles() {
PushSafepointRegisters();
PushCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, PushCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
FPRegister::kAllocatableFPRegisters)); FPRegister::kAllocatableFPRegisters));
} }
void MacroAssembler::PopSafepointFPRegisters() { void MacroAssembler::PopSafepointRegistersAndDoubles() {
PopCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits, PopCPURegList(CPURegList(CPURegister::kFPRegister, kDRegSizeInBits,
FPRegister::kAllocatableFPRegisters)); FPRegister::kAllocatableFPRegisters));
PopSafepointRegisters();
} }
...@@ -5120,6 +5122,14 @@ CPURegister UseScratchRegisterScope::AcquireNextAvailable( ...@@ -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-> #define __ masm->
......
...@@ -1728,8 +1728,8 @@ class MacroAssembler : public Assembler { ...@@ -1728,8 +1728,8 @@ class MacroAssembler : public Assembler {
void PushSafepointRegisters(); void PushSafepointRegisters();
void PopSafepointRegisters(); void PopSafepointRegisters();
void PushSafepointFPRegisters(); void PushSafepointRegistersAndDoubles();
void PopSafepointFPRegisters(); void PopSafepointRegistersAndDoubles();
// Store value in register src in the safepoint stack slot for register dst. // Store value in register src in the safepoint stack slot for register dst.
void StoreToSafepointRegisterSlot(Register src, Register dst) { void StoreToSafepointRegisterSlot(Register src, Register dst) {
...@@ -2215,11 +2215,17 @@ class UseScratchRegisterScope { ...@@ -2215,11 +2215,17 @@ class UseScratchRegisterScope {
FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); } FPRegister AcquireS() { return AcquireNextAvailable(availablefp_).S(); }
FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); } FPRegister AcquireD() { return AcquireNextAvailable(availablefp_).D(); }
Register UnsafeAcquire(const Register& reg) {
return UnsafeAcquire(available_, reg);
}
Register AcquireSameSizeAs(const Register& reg); Register AcquireSameSizeAs(const Register& reg);
FPRegister AcquireSameSizeAs(const FPRegister& reg); FPRegister AcquireSameSizeAs(const FPRegister& reg);
private: private:
static CPURegister AcquireNextAvailable(CPURegList* available); static CPURegister AcquireNextAvailable(CPURegList* available);
static CPURegister UnsafeAcquire(CPURegList* available,
const CPURegister& reg);
// Available scratch registers. // Available scratch registers.
CPURegList* available_; // kRegister CPURegList* available_; // kRegister
......
...@@ -100,8 +100,8 @@ namespace internal { ...@@ -100,8 +100,8 @@ namespace internal {
V(StringLength) \ V(StringLength) \
V(KeyedStringLength) V(KeyedStringLength)
// List of code stubs only used on ARM platforms. // List of code stubs only used on ARM 32 bits platforms.
#if defined(V8_TARGET_ARCH_ARM) || defined(V8_TARGET_ARCH_ARM64) #if V8_TARGET_ARCH_ARM
#define CODE_STUB_LIST_ARM(V) \ #define CODE_STUB_LIST_ARM(V) \
V(GetProperty) \ V(GetProperty) \
V(SetProperty) \ V(SetProperty) \
...@@ -111,6 +111,19 @@ namespace internal { ...@@ -111,6 +111,19 @@ namespace internal {
#define CODE_STUB_LIST_ARM(V) #define CODE_STUB_LIST_ARM(V)
#endif #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. // List of code stubs only used on MIPS platforms.
#if V8_TARGET_ARCH_MIPS #if V8_TARGET_ARCH_MIPS
#define CODE_STUB_LIST_MIPS(V) \ #define CODE_STUB_LIST_MIPS(V) \
...@@ -126,6 +139,7 @@ namespace internal { ...@@ -126,6 +139,7 @@ namespace internal {
#define CODE_STUB_LIST(V) \ #define CODE_STUB_LIST(V) \
CODE_STUB_LIST_ALL_PLATFORMS(V) \ CODE_STUB_LIST_ALL_PLATFORMS(V) \
CODE_STUB_LIST_ARM(V) \ CODE_STUB_LIST_ARM(V) \
CODE_STUB_LIST_ARM64(V) \
CODE_STUB_LIST_MIPS(V) CODE_STUB_LIST_MIPS(V)
// Stub is base classes of all stubs. // 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