| Index: src/ppc/debug-ppc.cc
|
| diff --git a/src/arm/debug-arm.cc b/src/ppc/debug-ppc.cc
|
| similarity index 68%
|
| copy from src/arm/debug-arm.cc
|
| copy to src/ppc/debug-ppc.cc
|
| index ec98a7ed3624aa055633416554a151a5ee94fe48..f07477771334df18da926c9efc7061d43c3c0ab4 100644
|
| --- a/src/arm/debug-arm.cc
|
| +++ b/src/ppc/debug-ppc.cc
|
| @@ -1,10 +1,13 @@
|
| // Copyright 2012 the V8 project authors. All rights reserved.
|
| +//
|
| +// Copyright IBM Corp. 2012, 2013. 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 +22,25 @@ 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
|
| + // addi sp, sp, <delta>
|
| + // 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()->mtlr(v8::internal::r0);
|
| + patcher.masm()->bclr(BA, SetLK);
|
| patcher.masm()->bkpt(0);
|
| }
|
|
|
| @@ -62,18 +70,25 @@ 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()->mtlr(v8::internal::r0);
|
| + patcher.masm()->bclr(BA, SetLK);
|
| }
|
|
|
|
|
| @@ -94,11 +109,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
|
| @@ -113,27 +128,27 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
|
| 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 };
|
| @@ -159,7 +174,7 @@ 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));
|
| + __ LoadP(ip, MemOperand(ip));
|
| __ Jump(ip);
|
| }
|
|
|
| @@ -167,15 +182,15 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
|
| 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 = LoadIC::ReceiverRegister();
|
| Register name = LoadIC::NameRegister();
|
| Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
|
| @@ -183,7 +198,7 @@ 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 = StoreIC::ReceiverRegister();
|
| Register name = StoreIC::NameRegister();
|
| Register value = StoreIC::ValueRegister();
|
| @@ -193,13 +208,13 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
|
|
|
|
|
| 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 = KeyedStoreIC::ReceiverRegister();
|
| Register name = KeyedStoreIC::NameRegister();
|
| Register value = KeyedStoreIC::ValueRegister();
|
| @@ -211,56 +226,56 @@ void DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
|
| 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();
|
| @@ -289,29 +304,27 @@ 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);
|
| }
|
|
|
|
|
| @@ -321,4 +334,4 @@ const bool LiveEdit::kFrameDropperSupported = true;
|
|
|
| } } // namespace v8::internal
|
|
|
| -#endif // V8_TARGET_ARCH_ARM
|
| +#endif // V8_TARGET_ARCH_PPC
|
|
|