PPC: Clean up register save/restore logic.
NOPRESUBMIT=true R=titzer@chromium.org, michael_dawson@ca.ibm.com, jyan@ca.ibm.com, joransiu@ca.ibm.com BUG= Review URL: https://codereview.chromium.org/1271583002 Cr-Commit-Position: refs/heads/master@{#29978}
This commit is contained in:
parent
80efc9d2fb
commit
e16cfe562d
@ -138,7 +138,11 @@ LinkageLocation stackloc(int i) {
|
||||
#define CALLEE_SAVE_REGISTERS \
|
||||
r14.bit() | r15.bit() | r16.bit() | r17.bit() | r18.bit() | r19.bit() | \
|
||||
r20.bit() | r21.bit() | r22.bit() | r23.bit() | r24.bit() | r25.bit() | \
|
||||
r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit() | fp.bit()
|
||||
r26.bit() | r27.bit() | r28.bit() | r29.bit() | r30.bit()
|
||||
#define CALLEE_SAVE_FP_REGISTERS \
|
||||
d14.bit() | d15.bit() | d16.bit() | d17.bit() | d18.bit() | d19.bit() | \
|
||||
d20.bit() | d21.bit() | d22.bit() | d23.bit() | d24.bit() | d25.bit() | \
|
||||
d26.bit() | d27.bit() | d28.bit() | d29.bit() | d30.bit() | d31.bit()
|
||||
|
||||
#else
|
||||
// ===========================================================================
|
||||
|
@ -1296,27 +1296,34 @@ void CodeGenerator::AssemblePrologue() {
|
||||
int stack_slots = frame()->GetSpillSlotCount();
|
||||
if (descriptor->kind() == CallDescriptor::kCallAddress) {
|
||||
__ function_descriptor();
|
||||
int register_save_area_size = 0;
|
||||
RegList frame_saves = fp.bit();
|
||||
RegList frame_saves = 0;
|
||||
__ mflr(r0);
|
||||
if (FLAG_enable_embedded_constant_pool) {
|
||||
__ Push(r0, fp, kConstantPoolRegister);
|
||||
// Adjust FP to point to saved FP.
|
||||
__ subi(fp, sp, Operand(StandardFrameConstants::kConstantPoolOffset));
|
||||
register_save_area_size += kPointerSize;
|
||||
frame_saves |= kConstantPoolRegister.bit();
|
||||
} else {
|
||||
__ Push(r0, fp);
|
||||
__ mr(fp, sp);
|
||||
}
|
||||
|
||||
// Save callee-saved registers.
|
||||
const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves;
|
||||
for (int i = Register::kNumRegisters - 1; i >= 0; i--) {
|
||||
if (!((1 << i) & saves)) continue;
|
||||
register_save_area_size += kPointerSize;
|
||||
}
|
||||
frame()->SetRegisterSaveAreaSize(register_save_area_size);
|
||||
__ MultiPush(saves);
|
||||
// register save area does not include the fp.
|
||||
DCHECK(kNumCalleeSaved - 1 ==
|
||||
base::bits::CountPopulation32(saves | frame_saves));
|
||||
int register_save_area_size = (kNumCalleeSaved - 1) * kPointerSize;
|
||||
|
||||
// Save callee-saved Double registers.
|
||||
const RegList double_saves = descriptor->CalleeSavedFPRegisters();
|
||||
__ MultiPushDoubles(double_saves);
|
||||
DCHECK(kNumCalleeSavedDoubles ==
|
||||
base::bits::CountPopulation32(double_saves));
|
||||
register_save_area_size += kNumCalleeSavedDoubles * kDoubleSize;
|
||||
|
||||
frame()->SetRegisterSaveAreaSize(register_save_area_size);
|
||||
} else if (descriptor->IsJSFunctionCall()) {
|
||||
CompilationInfo* info = this->info();
|
||||
__ Prologue(info->IsCodePreAgingActive());
|
||||
@ -1359,15 +1366,17 @@ void CodeGenerator::AssembleReturn() {
|
||||
if (stack_slots > 0) {
|
||||
__ Add(sp, sp, stack_slots * kPointerSize, r0);
|
||||
}
|
||||
// Restore double registers.
|
||||
const RegList double_saves = descriptor->CalleeSavedFPRegisters();
|
||||
__ MultiPopDoubles(double_saves);
|
||||
|
||||
// Restore registers.
|
||||
RegList frame_saves = fp.bit();
|
||||
RegList frame_saves = 0;
|
||||
if (FLAG_enable_embedded_constant_pool) {
|
||||
frame_saves |= kConstantPoolRegister.bit();
|
||||
}
|
||||
const RegList saves = descriptor->CalleeSavedRegisters() & ~frame_saves;
|
||||
if (saves != 0) {
|
||||
__ MultiPop(saves);
|
||||
}
|
||||
__ MultiPop(saves);
|
||||
}
|
||||
__ LeaveFrame(StackFrame::MANUAL);
|
||||
__ Ret();
|
||||
|
@ -749,7 +749,7 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
|
||||
__ mflr(r0);
|
||||
__ MultiPush(kJSCallerSaved | r0.bit());
|
||||
if (save_doubles()) {
|
||||
__ SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
|
||||
__ MultiPushDoubles(kCallerSavedDoubles);
|
||||
}
|
||||
const int argument_count = 1;
|
||||
const int fp_argument_count = 0;
|
||||
@ -761,7 +761,7 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
|
||||
__ CallCFunction(ExternalReference::store_buffer_overflow_function(isolate()),
|
||||
argument_count);
|
||||
if (save_doubles()) {
|
||||
__ RestoreFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
|
||||
__ MultiPopDoubles(kCallerSavedDoubles);
|
||||
}
|
||||
__ MultiPop(kJSCallerSaved | r0.bit());
|
||||
__ mtlr(r0);
|
||||
@ -1234,11 +1234,10 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// Save callee saved registers on the stack.
|
||||
__ MultiPush(kCalleeSaved);
|
||||
|
||||
// Floating point regs FPR0 - FRP13 are volatile
|
||||
// FPR14-FPR31 are non-volatile, but sub-calls will save them for us
|
||||
|
||||
// int offset_to_argv = kPointerSize * 22; // matches (22*4) above
|
||||
// __ lwz(r7, MemOperand(sp, offset_to_argv));
|
||||
// Save callee-saved double registers.
|
||||
__ MultiPushDoubles(kCalleeSavedDoubles);
|
||||
// Set up the reserved register for 0.0.
|
||||
__ LoadDoubleLiteral(kDoubleRegZero, 0.0, r0);
|
||||
|
||||
// Push a frame with special values setup to mark it as an entry frame.
|
||||
// r3: code entry
|
||||
@ -1360,20 +1359,16 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// Reset the stack to the callee saved registers.
|
||||
__ addi(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
|
||||
|
||||
// Restore callee-saved registers and return.
|
||||
#ifdef DEBUG
|
||||
if (FLAG_debug_code) {
|
||||
Label here;
|
||||
__ b(&here, SetLK);
|
||||
__ bind(&here);
|
||||
}
|
||||
#endif
|
||||
// Restore callee-saved double registers.
|
||||
__ MultiPopDoubles(kCalleeSavedDoubles);
|
||||
|
||||
// Restore callee-saved registers.
|
||||
__ MultiPop(kCalleeSaved);
|
||||
|
||||
// Return
|
||||
__ LoadP(r0, MemOperand(sp, kStackFrameLRSlot * kPointerSize));
|
||||
__ mtctr(r0);
|
||||
__ bctr();
|
||||
__ mtlr(r0);
|
||||
__ blr();
|
||||
}
|
||||
|
||||
|
||||
|
@ -181,7 +181,7 @@ class RecordWriteStub : public PlatformCodeStub {
|
||||
masm->MultiPush(kJSCallerSaved & ~scratch1_.bit());
|
||||
if (mode == kSaveFPRegs) {
|
||||
// Save all volatile FP registers except d0.
|
||||
masm->SaveFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1);
|
||||
masm->MultiPushDoubles(kCallerSavedDoubles & ~d0.bit());
|
||||
}
|
||||
}
|
||||
|
||||
@ -189,7 +189,7 @@ class RecordWriteStub : public PlatformCodeStub {
|
||||
SaveFPRegsMode mode) {
|
||||
if (mode == kSaveFPRegs) {
|
||||
// Restore all volatile FP registers except d0.
|
||||
masm->RestoreFPRegs(sp, 1, DoubleRegister::kNumVolatileRegisters - 1);
|
||||
masm->MultiPopDoubles(kCallerSavedDoubles & ~d0.bit());
|
||||
}
|
||||
masm->MultiPop(kJSCallerSaved & ~scratch1_.bit());
|
||||
masm->pop(r0);
|
||||
|
@ -55,6 +55,43 @@ const RegList kCalleeSaved = 1 << 14 | // r14
|
||||
|
||||
const int kNumCalleeSaved = 18;
|
||||
|
||||
const RegList kCallerSavedDoubles = 1 << 0 | // d0
|
||||
1 << 1 | // d1
|
||||
1 << 2 | // d2
|
||||
1 << 3 | // d3
|
||||
1 << 4 | // d4
|
||||
1 << 5 | // d5
|
||||
1 << 6 | // d6
|
||||
1 << 7 | // d7
|
||||
1 << 8 | // d8
|
||||
1 << 9 | // d9
|
||||
1 << 10 | // d10
|
||||
1 << 11 | // d11
|
||||
1 << 12 | // d12
|
||||
1 << 13; // d13
|
||||
|
||||
const RegList kCalleeSavedDoubles = 1 << 14 | // d14
|
||||
1 << 15 | // d15
|
||||
1 << 16 | // d16
|
||||
1 << 17 | // d17
|
||||
1 << 18 | // d18
|
||||
1 << 19 | // d19
|
||||
1 << 20 | // d20
|
||||
1 << 21 | // d21
|
||||
1 << 22 | // d22
|
||||
1 << 23 | // d23
|
||||
1 << 24 | // d24
|
||||
1 << 25 | // d25
|
||||
1 << 26 | // d26
|
||||
1 << 27 | // d27
|
||||
1 << 28 | // d28
|
||||
1 << 29 | // d29
|
||||
1 << 30 | // d30
|
||||
1 << 31; // d31
|
||||
|
||||
const int kNumCalleeSavedDoubles = 18;
|
||||
|
||||
|
||||
// Number of registers for which space is reserved in safepoints. Must be a
|
||||
// multiple of 8.
|
||||
const int kNumSafepointRegisters = 32;
|
||||
|
@ -224,30 +224,59 @@ void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) {
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::MultiPush(RegList regs) {
|
||||
void MacroAssembler::MultiPush(RegList regs, Register location) {
|
||||
int16_t num_to_push = NumberOfBitsSet(regs);
|
||||
int16_t stack_offset = num_to_push * kPointerSize;
|
||||
|
||||
subi(sp, sp, Operand(stack_offset));
|
||||
for (int16_t i = kNumRegisters - 1; i >= 0; i--) {
|
||||
subi(location, location, Operand(stack_offset));
|
||||
for (int16_t i = Register::kNumRegisters - 1; i >= 0; i--) {
|
||||
if ((regs & (1 << i)) != 0) {
|
||||
stack_offset -= kPointerSize;
|
||||
StoreP(ToRegister(i), MemOperand(sp, stack_offset));
|
||||
StoreP(ToRegister(i), MemOperand(location, stack_offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::MultiPop(RegList regs) {
|
||||
void MacroAssembler::MultiPop(RegList regs, Register location) {
|
||||
int16_t stack_offset = 0;
|
||||
|
||||
for (int16_t i = 0; i < kNumRegisters; i++) {
|
||||
for (int16_t i = 0; i < Register::kNumRegisters; i++) {
|
||||
if ((regs & (1 << i)) != 0) {
|
||||
LoadP(ToRegister(i), MemOperand(sp, stack_offset));
|
||||
LoadP(ToRegister(i), MemOperand(location, stack_offset));
|
||||
stack_offset += kPointerSize;
|
||||
}
|
||||
}
|
||||
addi(sp, sp, Operand(stack_offset));
|
||||
addi(location, location, Operand(stack_offset));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::MultiPushDoubles(RegList dregs, Register location) {
|
||||
int16_t num_to_push = NumberOfBitsSet(dregs);
|
||||
int16_t stack_offset = num_to_push * kDoubleSize;
|
||||
|
||||
subi(location, location, Operand(stack_offset));
|
||||
for (int16_t i = DoubleRegister::kNumRegisters - 1; i >= 0; i--) {
|
||||
if ((dregs & (1 << i)) != 0) {
|
||||
DoubleRegister dreg = DoubleRegister::from_code(i);
|
||||
stack_offset -= kDoubleSize;
|
||||
stfd(dreg, MemOperand(location, stack_offset));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::MultiPopDoubles(RegList dregs, Register location) {
|
||||
int16_t stack_offset = 0;
|
||||
|
||||
for (int16_t i = 0; i < DoubleRegister::kNumRegisters; i++) {
|
||||
if ((dregs & (1 << i)) != 0) {
|
||||
DoubleRegister dreg = DoubleRegister::from_code(i);
|
||||
lfd(dreg, MemOperand(location, stack_offset));
|
||||
stack_offset += kDoubleSize;
|
||||
}
|
||||
}
|
||||
addi(location, location, Operand(stack_offset));
|
||||
}
|
||||
|
||||
|
||||
@ -825,7 +854,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
|
||||
|
||||
// Optionally save all volatile double registers.
|
||||
if (save_doubles) {
|
||||
SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters);
|
||||
MultiPushDoubles(kCallerSavedDoubles);
|
||||
// Note that d0 will be accessible at
|
||||
// fp - ExitFrameConstants::kFrameSize -
|
||||
// kNumVolatileRegisters * kDoubleSize,
|
||||
@ -891,7 +920,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
|
||||
const int offset =
|
||||
(ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize);
|
||||
addi(r6, fp, Operand(-offset));
|
||||
RestoreFPRegs(r6, 0, kNumRegs);
|
||||
MultiPopDoubles(kCallerSavedDoubles, r6);
|
||||
}
|
||||
|
||||
// Clear top frame.
|
||||
@ -2955,28 +2984,6 @@ void MacroAssembler::InitializeFieldsWithFiller(Register start_offset,
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::SaveFPRegs(Register location, int first, int count) {
|
||||
DCHECK(count > 0);
|
||||
int cur = first;
|
||||
subi(location, location, Operand(count * kDoubleSize));
|
||||
for (int i = 0; i < count; i++) {
|
||||
DoubleRegister reg = DoubleRegister::from_code(cur++);
|
||||
stfd(reg, MemOperand(location, i * kDoubleSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::RestoreFPRegs(Register location, int first, int count) {
|
||||
DCHECK(count > 0);
|
||||
int cur = first + count - 1;
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
DoubleRegister reg = DoubleRegister::from_code(cur--);
|
||||
lfd(reg, MemOperand(location, i * kDoubleSize));
|
||||
}
|
||||
addi(location, location, Operand(count * kDoubleSize));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte(
|
||||
Register first, Register second, Register scratch1, Register scratch2,
|
||||
Label* failure) {
|
||||
|
@ -152,8 +152,11 @@ class MacroAssembler : public Assembler {
|
||||
void Move(Register dst, Register src, Condition cond = al);
|
||||
void Move(DoubleRegister dst, DoubleRegister src);
|
||||
|
||||
void MultiPush(RegList regs);
|
||||
void MultiPop(RegList regs);
|
||||
void MultiPush(RegList regs, Register location = sp);
|
||||
void MultiPop(RegList regs, Register location = sp);
|
||||
|
||||
void MultiPushDoubles(RegList dregs, Register location = sp);
|
||||
void MultiPopDoubles(RegList dregs, Register location = sp);
|
||||
|
||||
// Load an object from the root table.
|
||||
void LoadRoot(Register destination, Heap::RootListIndex index,
|
||||
@ -888,12 +891,6 @@ class MacroAssembler : public Assembler {
|
||||
bind(&label);
|
||||
}
|
||||
|
||||
// Pushes <count> double values to <location>, starting from d<first>.
|
||||
void SaveFPRegs(Register location, int first, int count);
|
||||
|
||||
// Pops <count> double values from <location>, starting from d<first>.
|
||||
void RestoreFPRegs(Register location, int first, int count);
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Runtime calls
|
||||
|
||||
|
@ -171,8 +171,7 @@ void RegExpMacroAssemblerPPC::Backtrack() {
|
||||
// Pop Code* offset from backtrack stack, add Code* and jump to location.
|
||||
Pop(r3);
|
||||
__ add(r3, r3, code_pointer());
|
||||
__ mtctr(r3);
|
||||
__ bctr();
|
||||
__ Jump(r3);
|
||||
}
|
||||
|
||||
|
||||
@ -834,8 +833,8 @@ Handle<HeapObject> RegExpMacroAssemblerPPC::GetCode(Handle<String> source) {
|
||||
// Restore registers r25..r31 and return (restoring lr to pc).
|
||||
__ MultiPop(registers_to_retain);
|
||||
__ pop(r0);
|
||||
__ mtctr(r0);
|
||||
__ bctr();
|
||||
__ mtlr(r0);
|
||||
__ blr();
|
||||
|
||||
// Backtrack code (branch target for conditional backtracks).
|
||||
if (backtrack_label_.is_linked()) {
|
||||
|
Loading…
Reference in New Issue
Block a user