Index: src/ppc/debug-ppc.cc |
diff --git a/src/arm/debug-arm.cc b/src/ppc/debug-ppc.cc |
similarity index 63% |
copy from src/arm/debug-arm.cc |
copy to src/ppc/debug-ppc.cc |
index c9100576d2f61813654edfb34f3b91f0d50c42c7..8106853134922f73efeb7ca6526396299246c416 100644 |
--- a/src/arm/debug-arm.cc |
+++ b/src/ppc/debug-ppc.cc |
@@ -1,10 +1,10 @@ |
-// Copyright 2012 the V8 project authors. All rights reserved. |
+// Copyright 2014 the V8 project authors. All rights reserved. |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
#include "src/v8.h" |
-#if V8_TARGET_ARCH_ARM |
+#if V8_TARGET_ARCH_PPC |
#include "src/codegen.h" |
#include "src/debug.h" |
@@ -19,20 +19,28 @@ bool BreakLocationIterator::IsDebugBreakAtReturn() { |
void BreakLocationIterator::SetDebugBreakAtReturn() { |
// Patch the code changing the return from JS function sequence from |
- // mov sp, fp |
- // ldmia sp!, {fp, lr} |
- // add sp, sp, #4 |
- // bx lr |
+ // |
+ // LeaveFrame |
+ // blr |
+ // |
// to a call to the debug break return code. |
- // ldr ip, [pc, #0] |
- // blx ip |
- // <debug break return code entry point address> |
- // bkpt 0 |
+ // this uses a FIXED_SEQUENCE to load an address constant |
+ // |
+ // mov r0, <address> |
+ // mtlr r0 |
+ // blrl |
+ // bkpt |
+ // |
CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions); |
- patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); |
- patcher.masm()->blx(v8::internal::ip); |
- patcher.Emit( |
- debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry()); |
+ Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm()); |
+ patcher.masm()->mov( |
+ v8::internal::r0, |
+ Operand(reinterpret_cast<intptr_t>(debug_info_->GetIsolate() |
+ ->builtins() |
+ ->Return_DebugBreak() |
+ ->entry()))); |
+ patcher.masm()->mtctr(v8::internal::r0); |
+ patcher.masm()->bctrl(); |
patcher.masm()->bkpt(0); |
} |
@@ -62,18 +70,27 @@ bool BreakLocationIterator::IsDebugBreakAtSlot() { |
void BreakLocationIterator::SetDebugBreakAtSlot() { |
DCHECK(IsDebugBreakSlot()); |
// Patch the code changing the debug break slot code from |
- // mov r2, r2 |
- // mov r2, r2 |
- // mov r2, r2 |
- // to a call to the debug break slot code. |
- // ldr ip, [pc, #0] |
- // blx ip |
- // <debug break slot code entry point address> |
+ // |
+ // ori r3, r3, 0 |
+ // ori r3, r3, 0 |
+ // ori r3, r3, 0 |
+ // ori r3, r3, 0 |
+ // ori r3, r3, 0 |
+ // |
+ // to a call to the debug break code, using a FIXED_SEQUENCE. |
+ // |
+ // mov r0, <address> |
+ // mtlr r0 |
+ // blrl |
+ // |
CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions); |
- patcher.masm()->ldr(v8::internal::ip, MemOperand(v8::internal::pc, 0)); |
- patcher.masm()->blx(v8::internal::ip); |
- patcher.Emit( |
- debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()); |
+ Assembler::BlockTrampolinePoolScope block_trampoline_pool(patcher.masm()); |
+ patcher.masm()->mov( |
+ v8::internal::r0, |
+ Operand(reinterpret_cast<intptr_t>( |
+ debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry()))); |
+ patcher.masm()->mtctr(v8::internal::r0); |
+ patcher.masm()->bctrl(); |
} |
@@ -94,11 +111,11 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
// Load padding words on stack. |
- __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue))); |
+ __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingValue)); |
for (int i = 0; i < LiveEdit::kFramePaddingInitialSize; i++) { |
__ push(ip); |
} |
- __ mov(ip, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize))); |
+ __ LoadSmiLiteral(ip, Smi::FromInt(LiveEdit::kFramePaddingInitialSize)); |
__ push(ip); |
// Store the registers containing live values on the expression stack to |
@@ -110,38 +127,38 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
if ((object_regs | non_object_regs) != 0) { |
for (int i = 0; i < kNumJSCallerSaved; i++) { |
int r = JSCallerSavedCode(i); |
- Register reg = { r }; |
+ Register reg = {r}; |
if ((non_object_regs & (1 << r)) != 0) { |
if (FLAG_debug_code) { |
- __ tst(reg, Operand(0xc0000000)); |
- __ Assert(eq, kUnableToEncodeValueAsSmi); |
+ __ TestUnsignedSmiCandidate(reg, r0); |
+ __ Assert(eq, kUnableToEncodeValueAsSmi, cr0); |
} |
__ SmiTag(reg); |
} |
} |
- __ stm(db_w, sp, object_regs | non_object_regs); |
+ __ MultiPush(object_regs | non_object_regs); |
} |
#ifdef DEBUG |
__ RecordComment("// Calling from debug break to runtime - come in - over"); |
#endif |
- __ mov(r0, Operand::Zero()); // no arguments |
- __ mov(r1, Operand(ExternalReference::debug_break(masm->isolate()))); |
+ __ mov(r3, Operand::Zero()); // no arguments |
+ __ mov(r4, Operand(ExternalReference::debug_break(masm->isolate()))); |
CEntryStub ceb(masm->isolate(), 1); |
__ CallStub(&ceb); |
// Restore the register values from the expression stack. |
if ((object_regs | non_object_regs) != 0) { |
- __ ldm(ia_w, sp, object_regs | non_object_regs); |
+ __ MultiPop(object_regs | non_object_regs); |
for (int i = 0; i < kNumJSCallerSaved; i++) { |
int r = JSCallerSavedCode(i); |
- Register reg = { r }; |
+ Register reg = {r}; |
if ((non_object_regs & (1 << r)) != 0) { |
__ SmiUntag(reg); |
} |
if (FLAG_debug_code && |
- (((object_regs |non_object_regs) & (1 << r)) == 0)) { |
+ (((object_regs | non_object_regs) & (1 << r)) == 0)) { |
__ mov(reg, Operand(kDebugZapValue)); |
} |
} |
@@ -159,23 +176,23 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, |
ExternalReference after_break_target = |
ExternalReference::debug_after_break_target_address(masm->isolate()); |
__ mov(ip, Operand(after_break_target)); |
- __ ldr(ip, MemOperand(ip)); |
- __ Jump(ip); |
+ __ LoadP(ip, MemOperand(ip)); |
+ __ JumpToJSEntry(ip); |
} |
void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) { |
// Register state for CallICStub |
// ----------- S t a t e ------------- |
- // -- r1 : function |
- // -- r3 : slot in feedback array (smi) |
+ // -- r4 : function |
+ // -- r6 : slot in feedback array (smi) |
// ----------------------------------- |
- Generate_DebugBreakCallHelper(masm, r1.bit() | r3.bit(), 0); |
+ Generate_DebugBreakCallHelper(masm, r4.bit() | r6.bit(), 0); |
} |
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { |
- // Calling convention for IC load (from ic-arm.cc). |
+ // Calling convention for IC load (from ic-ppc.cc). |
Register receiver = LoadDescriptor::ReceiverRegister(); |
Register name = LoadDescriptor::NameRegister(); |
RegList regs = receiver.bit() | name.bit(); |
@@ -187,84 +204,84 @@ void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { |
void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) { |
- // Calling convention for IC store (from ic-arm.cc). |
+ // Calling convention for IC store (from ic-ppc.cc). |
Register receiver = StoreDescriptor::ReceiverRegister(); |
Register name = StoreDescriptor::NameRegister(); |
Register value = StoreDescriptor::ValueRegister(); |
- Generate_DebugBreakCallHelper( |
- masm, receiver.bit() | name.bit() | value.bit(), 0); |
+ Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit() | value.bit(), |
+ 0); |
} |
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { |
- // Calling convention for keyed IC load (from ic-arm.cc). |
+ // Calling convention for keyed IC load (from ic-ppc.cc). |
GenerateLoadICDebugBreak(masm); |
} |
void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) { |
- // Calling convention for IC keyed store call (from ic-arm.cc). |
+ // Calling convention for IC keyed store call (from ic-ppc.cc). |
Register receiver = StoreDescriptor::ReceiverRegister(); |
Register name = StoreDescriptor::NameRegister(); |
Register value = StoreDescriptor::ValueRegister(); |
- Generate_DebugBreakCallHelper( |
- masm, receiver.bit() | name.bit() | value.bit(), 0); |
+ Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit() | value.bit(), |
+ 0); |
} |
void DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) { |
// Register state for CompareNil IC |
// ----------- S t a t e ------------- |
- // -- r0 : value |
+ // -- r3 : value |
// ----------------------------------- |
- Generate_DebugBreakCallHelper(masm, r0.bit(), 0); |
+ Generate_DebugBreakCallHelper(masm, r3.bit(), 0); |
} |
void DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) { |
- // In places other than IC call sites it is expected that r0 is TOS which |
+ // In places other than IC call sites it is expected that r3 is TOS which |
// is an object - this is not generally the case so this should be used with |
// care. |
- Generate_DebugBreakCallHelper(masm, r0.bit(), 0); |
+ Generate_DebugBreakCallHelper(masm, r3.bit(), 0); |
} |
void DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) { |
- // Register state for CallFunctionStub (from code-stubs-arm.cc). |
+ // Register state for CallFunctionStub (from code-stubs-ppc.cc). |
// ----------- S t a t e ------------- |
- // -- r1 : function |
+ // -- r4 : function |
// ----------------------------------- |
- Generate_DebugBreakCallHelper(masm, r1.bit(), 0); |
+ Generate_DebugBreakCallHelper(masm, r4.bit(), 0); |
} |
void DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) { |
- // Calling convention for CallConstructStub (from code-stubs-arm.cc) |
+ // Calling convention for CallConstructStub (from code-stubs-ppc.cc) |
// ----------- S t a t e ------------- |
- // -- r0 : number of arguments (not smi) |
- // -- r1 : constructor function |
+ // -- r3 : number of arguments (not smi) |
+ // -- r4 : constructor function |
// ----------------------------------- |
- Generate_DebugBreakCallHelper(masm, r1.bit(), r0.bit()); |
+ Generate_DebugBreakCallHelper(masm, r4.bit(), r3.bit()); |
} |
void DebugCodegen::GenerateCallConstructStubRecordDebugBreak( |
MacroAssembler* masm) { |
- // Calling convention for CallConstructStub (from code-stubs-arm.cc) |
+ // Calling convention for CallConstructStub (from code-stubs-ppc.cc) |
// ----------- S t a t e ------------- |
- // -- r0 : number of arguments (not smi) |
- // -- r1 : constructor function |
- // -- r2 : feedback array |
- // -- r3 : feedback slot (smi) |
+ // -- r3 : number of arguments (not smi) |
+ // -- r4 : constructor function |
+ // -- r5 : feedback array |
+ // -- r6 : feedback slot (smi) |
// ----------------------------------- |
- Generate_DebugBreakCallHelper(masm, r1.bit() | r2.bit() | r3.bit(), r0.bit()); |
+ Generate_DebugBreakCallHelper(masm, r4.bit() | r5.bit() | r6.bit(), r3.bit()); |
} |
void DebugCodegen::GenerateSlot(MacroAssembler* masm) { |
// Generate enough nop's to make space for a call instruction. Avoid emitting |
- // the constant pool in the debug break slot code. |
- Assembler::BlockConstPoolScope block_const_pool(masm); |
+ // the trampoline pool in the debug break slot code. |
+ Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); |
Label check_codesize; |
__ bind(&check_codesize); |
__ RecordDebugBreakSlot(); |
@@ -293,36 +310,34 @@ void DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) { |
ExternalReference::debug_restarter_frame_function_pointer_address( |
masm->isolate()); |
__ mov(ip, Operand(restarter_frame_function_slot)); |
- __ mov(r1, Operand::Zero()); |
- __ str(r1, MemOperand(ip, 0)); |
+ __ li(r4, Operand::Zero()); |
+ __ StoreP(r4, MemOperand(ip, 0)); |
// Load the function pointer off of our current stack frame. |
- __ ldr(r1, MemOperand(fp, |
- StandardFrameConstants::kConstantPoolOffset - kPointerSize)); |
+ __ LoadP(r4, MemOperand(fp, StandardFrameConstants::kConstantPoolOffset - |
+ kPointerSize)); |
// Pop return address, frame and constant pool pointer (if |
// FLAG_enable_ool_constant_pool). |
__ LeaveFrame(StackFrame::INTERNAL); |
- { ConstantPoolUnavailableScope constant_pool_unavailable(masm); |
- // Load context from the function. |
- __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); |
+ // Load context from the function. |
+ __ LoadP(cp, FieldMemOperand(r4, JSFunction::kContextOffset)); |
- // Get function code. |
- __ ldr(ip, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset)); |
- __ ldr(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset)); |
- __ add(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
+ // Get function code. |
+ __ LoadP(ip, FieldMemOperand(r4, JSFunction::kSharedFunctionInfoOffset)); |
+ __ LoadP(ip, FieldMemOperand(ip, SharedFunctionInfo::kCodeOffset)); |
+ __ addi(ip, ip, Operand(Code::kHeaderSize - kHeapObjectTag)); |
- // Re-run JSFunction, r1 is function, cp is context. |
- __ Jump(ip); |
- } |
+ // Re-run JSFunction, r4 is function, cp is context. |
+ __ Jump(ip); |
} |
const bool LiveEdit::kFrameDropperSupported = true; |
#undef __ |
+} |
+} // namespace v8::internal |
-} } // namespace v8::internal |
- |
-#endif // V8_TARGET_ARCH_ARM |
+#endif // V8_TARGET_ARCH_PPC |