112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// found in the LICENSE file.
412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/v8.h"
812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#if V8_TARGET_ARCH_MIPS64
1012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/codegen.h"
1212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#include "src/debug.h"
1312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace v8 {
1512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgnamespace internal {
1612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
1712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() {
1812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return Debug::IsDebugBreakAtReturn(rinfo());
1912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
2012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
2212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() {
2312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Mips return sequence:
2412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // mov sp, fp
2512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // lw fp, sp(0)
2612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // lw ra, sp(4)
2712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // addiu sp, sp, 8
2812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // addiu sp, sp, N
2912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // jr ra
3012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // nop (in branch delay slot)
3112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
3212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Make sure this constant matches the number if instructions we emit.
33e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Assembler::kJSReturnSequenceInstructions == 7);
3412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
3512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // li and Call pseudo-instructions emit 6 + 2 instructions.
3612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int64_t>(
3712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry())),
3812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ADDRESS_LOAD);
3912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  patcher.masm()->Call(v8::internal::t9);
4012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Place nop to match return sequence size.
4112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  patcher.masm()->nop();
4212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // TODO(mips): Open issue about using breakpoint instruction instead of nops.
4312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // patcher.masm()->bkpt(0);
4412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
4512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
4612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
4712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// Restore the JS frame exit code.
4812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() {
4912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rinfo()->PatchCode(original_rinfo()->pc(),
5012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                     Assembler::kJSReturnSequenceInstructions);
5112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
5212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
5312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
5412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// A debug break in the exit code is identified by the JS frame exit code
5512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org// having been patched with li/call psuedo-instrunction (liu/ori/jalr).
5612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
57e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(RelocInfo::IsJSReturn(rinfo->rmode()));
5812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return rinfo->IsPatchedReturnSequence();
5912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
6012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() {
63e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
6412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Check whether the debug break slot instructions have been patched.
6512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  return rinfo()->IsPatchedDebugBreakSlotSequence();
6612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
6712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
6912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() {
70e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
7112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Patch the code changing the debug break slot code from:
7212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
7312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   nop(DEBUG_BREAK_NOP)
7412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   nop(DEBUG_BREAK_NOP)
7512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   nop(DEBUG_BREAK_NOP)
7612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   nop(DEBUG_BREAK_NOP)
7712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   nop(DEBUG_BREAK_NOP)
7812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // to a call to the debug break slot code.
7912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   li t9, address   (4-instruction sequence on mips64)
8012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //   call t9          (jalr t9 / nop instruction pair)
8112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
8212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  patcher.masm()->li(v8::internal::t9,
8312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      Operand(reinterpret_cast<int64_t>(
8412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())),
8512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ADDRESS_LOAD);
8612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  patcher.masm()->Call(v8::internal::t9);
8712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
8812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
8912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() {
91e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
9212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  rinfo()->PatchCode(original_rinfo()->pc(),
9312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                     Assembler::kDebugBreakSlotInstructions);
9412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
9512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#define __ ACCESS_MASM(masm)
9812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
9912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
10012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
10112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm,
10212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                          RegList object_regs,
10312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org                                          RegList non_object_regs) {
10412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  {
10512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    FrameScope scope(masm, StackFrame::INTERNAL);
10612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
10712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Load padding words on stack.
10812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
10912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ Dsubu(sp, sp,
11012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org            Operand(kPointerSize * LiveEdit::kFramePaddingInitialSize));
11112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    for (int i = LiveEdit::kFramePaddingInitialSize - 1; i >= 0; i--) {
11212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      __ sd(at, MemOperand(sp, kPointerSize * i));
11312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
11412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
11512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ push(at);
11612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
11712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
11812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // TODO(plind): This needs to be revised to store pairs of smi's per
11912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    //    the other 64-bit arch's.
12012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
12112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Store the registers containing live values on the expression stack to
12212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // make sure that these are correctly updated during GC. Non object values
12312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // are stored as a smi causing it to be untouched by GC.
124e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((object_regs & ~kJSCallerSaved) == 0);
125e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((non_object_regs & ~kJSCallerSaved) == 0);
126e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((object_regs & non_object_regs) == 0);
12712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    for (int i = 0; i < kNumJSCallerSaved; i++) {
12812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int r = JSCallerSavedCode(i);
12912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      Register reg = { r };
13012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if ((object_regs & (1 << r)) != 0) {
13112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        __ push(reg);
13212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
13312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if ((non_object_regs & (1 << r)) != 0) {
13412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        __ PushRegisterAsTwoSmis(reg);
13512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
13612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
13712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
13812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#ifdef DEBUG
13912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ RecordComment("// Calling from debug break to runtime - come in - over");
14012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif
14112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ PrepareCEntryArgs(0);  // No arguments.
14212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ PrepareCEntryFunction(ExternalReference::debug_break(masm->isolate()));
14312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
14412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    CEntryStub ceb(masm->isolate(), 1);
14512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ CallStub(&ceb);
14612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
14712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Restore the register values from the expression stack.
14812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    for (int i = kNumJSCallerSaved - 1; i >= 0; i--) {
14912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      int r = JSCallerSavedCode(i);
15012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      Register reg = { r };
15112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if ((non_object_regs & (1 << r)) != 0) {
15212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        __ PopRegisterAsTwoSmis(reg, at);
15312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
15412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if ((object_regs & (1 << r)) != 0) {
15512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        __ pop(reg);
15612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
15712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      if (FLAG_debug_code &&
15812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          (((object_regs |non_object_regs) & (1 << r)) == 0)) {
15912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org        __ li(reg, kDebugZapValue);
16012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      }
16112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    }
16212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
16312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Don't bother removing padding bytes pushed on the stack
16412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // as the frame is going to be restored right away.
16512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
16612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    // Leave the internal frame.
16712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
16812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
16912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Now that the break point has been handled, resume normal execution by
17012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // jumping to the target address intended by the caller and that was
17112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // overwritten by the address of DebugBreakXXX.
17212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  ExternalReference after_break_target =
17312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ExternalReference::debug_after_break_target_address(masm->isolate());
17412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ li(t9, Operand(after_break_target));
17512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ ld(t9, MemOperand(t9));
17612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ Jump(t9);
17712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
17812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
17912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
18012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
18112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Register state for CallICStub
18212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ----------- S t a t e -------------
18312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a1 : function
18412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a3 : slot in feedback array (smi)
18512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // -----------------------------------
18612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit() | a3.bit(), 0);
18712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
18812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
18912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
19012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
1919aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register receiver = LoadDescriptor::ReceiverRegister();
1929aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register name = LoadDescriptor::NameRegister();
19312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
19412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
19512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
19612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
19712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
1989aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register receiver = StoreDescriptor::ReceiverRegister();
1999aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register name = StoreDescriptor::NameRegister();
2009aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register value = StoreDescriptor::ValueRegister();
20170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  Generate_DebugBreakCallHelper(
20270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      masm, receiver.bit() | name.bit() | value.bit(), 0);
20312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
20412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
20512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
20612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
20770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  // Calling convention for keyed IC load (from ic-mips64.cc).
20812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  GenerateLoadICDebugBreak(masm);
20912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
21012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
21112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
21212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
21370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  // Calling convention for IC keyed store call (from ic-mips64.cc).
2149aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register receiver = StoreDescriptor::ReceiverRegister();
2159aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register name = StoreDescriptor::NameRegister();
2169aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register value = StoreDescriptor::ValueRegister();
21770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  Generate_DebugBreakCallHelper(
21870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      masm, receiver.bit() | name.bit() | value.bit(), 0);
21912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
22012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
22112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
22212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
22312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Register state for CompareNil IC
22412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ----------- S t a t e -------------
22512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a0    : value
22612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // -----------------------------------
22712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, a0.bit(), 0);
22812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
22912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
23012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
23112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
23212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // In places other than IC call sites it is expected that v0 is TOS which
23312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // is an object - this is not generally the case so this should be used with
23412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // care.
23512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, v0.bit(), 0);
23612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
23712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
23812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
23912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
24012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Register state for CallFunctionStub (from code-stubs-mips.cc).
24112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ----------- S t a t e -------------
24212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a1 : function
24312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // -----------------------------------
24412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit(), 0);
24512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
24612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
24712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
24812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
24912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Calling convention for CallConstructStub (from code-stubs-mips.cc).
25012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ----------- S t a t e -------------
25112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a0     : number of arguments (not smi)
25212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a1     : constructor function
25312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // -----------------------------------
25412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit() , a0.bit());
25512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
25612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
25712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
25812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
25912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
26012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    MacroAssembler* masm) {
26112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Calling convention for CallConstructStub (from code-stubs-mips.cc).
26212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // ----------- S t a t e -------------
26312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a0     : number of arguments (not smi)
26412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a1     : constructor function
26512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a2     : feedback array
26612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  //  -- a3     : feedback slot (smi)
26712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // -----------------------------------
26812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit() | a2.bit() | a3.bit(), a0.bit());
26912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
27012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
27112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
27212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) {
27312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Generate enough nop's to make space for a call instruction. Avoid emitting
27412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // the trampoline pool in the debug break slot code.
27512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
27612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Label check_codesize;
27712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ bind(&check_codesize);
27812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ RecordDebugBreakSlot();
27912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
28012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
28112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  }
282e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
28312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org            masm->InstructionsGeneratedSince(&check_codesize));
28412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
28512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
28612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
28712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
28812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // In the places where a debug break slot is inserted no registers can contain
28912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // object pointers.
29012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, 0, 0);
29112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
29212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
29312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
29412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
29512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ Ret();
29612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
29712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
29812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
29912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
30012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  ExternalReference restarter_frame_function_slot =
30112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org      ExternalReference::debug_restarter_frame_function_pointer_address(
30212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org          masm->isolate());
30312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ li(at, Operand(restarter_frame_function_slot));
30412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ sw(zero_reg, MemOperand(at, 0));
30512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
30612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // We do not know our frame height, but set sp based on fp.
30712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ Dsubu(sp, fp, Operand(kPointerSize));
30812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
30912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ Pop(ra, fp, a1);  // Return address, Frame, Function.
31012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
31112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Load context from the function.
31212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ ld(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
31312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
31412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Get function code.
31512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ ld(at, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
31612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ ld(at, FieldMemOperand(at, SharedFunctionInfo::kCodeOffset));
31712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ Daddu(t9, at, Operand(Code::kHeaderSize - kHeapObjectTag));
31812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
31912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  // Re-run JSFunction, a1 is function, cp is context.
32012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org  __ Jump(t9);
32112e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org}
32212e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32312e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32412e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.orgconst bool LiveEdit::kFrameDropperSupported = true;
32512e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32612e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#undef __
32712e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
32812e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org} }  // namespace v8::internal
32912e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org
33012e05e8fde625d746b998a15049e8487c43a3b17machenbach@chromium.org#endif  // V8_TARGET_ARCH_MIPS64
331