1212d964d8f853ddb1fdf3a64037f3af294d55cf3jkummerow@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
45c838251403b0be9a882540f1922577abba4c872ager@chromium.org
55c838251403b0be9a882540f1922577abba4c872ager@chromium.org
65c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/v8.h"
85c838251403b0be9a882540f1922577abba4c872ager@chromium.org
993a47f4837f2137c8d8349250fd8e91da3108126jkummerow@chromium.org#if V8_TARGET_ARCH_MIPS
109dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/codegen.h"
12196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/debug.h"
135c838251403b0be9a882540f1922577abba4c872ager@chromium.org
145c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace v8 {
155c838251403b0be9a882540f1922577abba4c872ager@chromium.orgnamespace internal {
165c838251403b0be9a882540f1922577abba4c872ager@chromium.org
175c838251403b0be9a882540f1922577abba4c872ager@chromium.orgbool BreakLocationIterator::IsDebugBreakAtReturn() {
187304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  return Debug::IsDebugBreakAtReturn(rinfo());
195c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
205c838251403b0be9a882540f1922577abba4c872ager@chromium.org
215c838251403b0be9a882540f1922577abba4c872ager@chromium.org
225c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtReturn() {
237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Mips return sequence:
247304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // mov sp, fp
257304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // lw fp, sp(0)
267304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // lw ra, sp(4)
277304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // addiu sp, sp, 8
287304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // addiu sp, sp, N
297304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // jr ra
307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // nop (in branch delay slot)
317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Make sure this constant matches the number if instrucntions we emit.
33e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(Assembler::kJSReturnSequenceInstructions == 7);
347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  CodePatcher patcher(rinfo()->pc(), Assembler::kJSReturnSequenceInstructions);
357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // li and Call pseudo-instructions emit two instructions each.
36af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org  patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int32_t>(
37af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      debug_info_->GetIsolate()->builtins()->Return_DebugBreak()->entry())));
387304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  patcher.masm()->Call(v8::internal::t9);
397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  patcher.masm()->nop();
407304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  patcher.masm()->nop();
417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  patcher.masm()->nop();
427304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
437304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // TODO(mips): Open issue about using breakpoint instruction instead of nops.
447304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // patcher.masm()->bkpt(0);
455c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
465c838251403b0be9a882540f1922577abba4c872ager@chromium.org
475c838251403b0be9a882540f1922577abba4c872ager@chromium.org
485c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Restore the JS frame exit code.
495c838251403b0be9a882540f1922577abba4c872ager@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtReturn() {
507304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  rinfo()->PatchCode(original_rinfo()->pc(),
517304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                     Assembler::kJSReturnSequenceInstructions);
525c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
535c838251403b0be9a882540f1922577abba4c872ager@chromium.org
545c838251403b0be9a882540f1922577abba4c872ager@chromium.org
557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// A debug break in the exit code is identified by the JS frame exit code
567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// having been patched with li/call psuedo-instrunction (liu/ori/jalr).
575c838251403b0be9a882540f1922577abba4c872ager@chromium.orgbool Debug::IsDebugBreakAtReturn(RelocInfo* rinfo) {
58e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(RelocInfo::IsJSReturn(rinfo->rmode()));
597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  return rinfo->IsPatchedReturnSequence();
605c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
625c838251403b0be9a882540f1922577abba4c872ager@chromium.org
637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgbool BreakLocationIterator::IsDebugBreakAtSlot() {
64e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Check whether the debug break slot instructions have been patched.
667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  return rinfo()->IsPatchedDebugBreakSlotSequence();
677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
697516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid BreakLocationIterator::SetDebugBreakAtSlot() {
71e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Patch the code changing the debug break slot code from:
737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //   nop(DEBUG_BREAK_NOP) - nop(1) is sll(zero_reg, zero_reg, 1)
747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //   nop(DEBUG_BREAK_NOP)
757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //   nop(DEBUG_BREAK_NOP)
767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //   nop(DEBUG_BREAK_NOP)
777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // to a call to the debug break slot code.
787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //   li t9, address   (lui t9 / ori t9 instruction pair)
797304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  //   call t9          (jalr t9 / nop instruction pair)
807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  CodePatcher patcher(rinfo()->pc(), Assembler::kDebugBreakSlotInstructions);
817304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  patcher.masm()->li(v8::internal::t9, Operand(reinterpret_cast<int32_t>(
82af6f699b0be532b73bc2f6c9e1cf40a57fa7e234machenbach@chromium.org      debug_info_->GetIsolate()->builtins()->Slot_DebugBreak()->entry())));
837304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  patcher.masm()->Call(v8::internal::t9);
847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
857516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgvoid BreakLocationIterator::ClearDebugBreakAtSlot() {
88e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK(IsDebugBreakSlot());
897304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  rinfo()->PatchCode(original_rinfo()->pc(),
907304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                     Assembler::kDebugBreakSlotInstructions);
917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
925c838251403b0be9a882540f1922577abba4c872ager@chromium.org
935c838251403b0be9a882540f1922577abba4c872ager@chromium.org
947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define __ ACCESS_MASM(masm)
955c838251403b0be9a882540f1922577abba4c872ager@chromium.org
965c838251403b0be9a882540f1922577abba4c872ager@chromium.org
977304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
987304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.orgstatic void Generate_DebugBreakCallHelper(MacroAssembler* masm,
997304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                                          RegList object_regs,
1007304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org                                          RegList non_object_regs) {
101c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  {
102c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    FrameScope scope(masm, StackFrame::INTERNAL);
103c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1044b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    // Load padding words on stack.
1054b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingValue)));
1064b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    __ Subu(sp, sp,
1074b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org            Operand(kPointerSize * LiveEdit::kFramePaddingInitialSize));
1084b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    for (int i = LiveEdit::kFramePaddingInitialSize - 1; i >= 0; i--) {
1094b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      __ sw(at, MemOperand(sp, kPointerSize * i));
1104b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    }
1114b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    __ li(at, Operand(Smi::FromInt(LiveEdit::kFramePaddingInitialSize)));
1124b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    __ push(at);
1134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
114c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Store the registers containing live values on the expression stack to
115c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // make sure that these are correctly updated during GC. Non object values
116c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // are stored as a smi causing it to be untouched by GC.
117e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((object_regs & ~kJSCallerSaved) == 0);
118e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((non_object_regs & ~kJSCallerSaved) == 0);
119e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((object_regs & non_object_regs) == 0);
120c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((object_regs | non_object_regs) != 0) {
121c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      for (int i = 0; i < kNumJSCallerSaved; i++) {
122c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        int r = JSCallerSavedCode(i);
123c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Register reg = { r };
124c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if ((non_object_regs & (1 << r)) != 0) {
125c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          if (FLAG_debug_code) {
126c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            __ And(at, reg, 0xc0000000);
127594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org            __ Assert(eq, kUnableToEncodeValueAsSmi, at, Operand(zero_reg));
128c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          }
129c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          __ sll(reg, reg, kSmiTagSize);
1307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org        }
1317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      }
132c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ MultiPush(object_regs | non_object_regs);
1337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
1347304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1357304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#ifdef DEBUG
136c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ RecordComment("// Calling from debug break to runtime - come in - over");
1377304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org#endif
1386ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    __ PrepareCEntryArgs(0);  // No arguments.
1396ff651481ed0a881f176f6d55e26679ca359792bulan@chromium.org    __ PrepareCEntryFunction(ExternalReference::debug_break(masm->isolate()));
140c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
141f2f0489407bbb5e50d16ae791442df29513b53b5machenbach@chromium.org    CEntryStub ceb(masm->isolate(), 1);
142c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    __ CallStub(&ceb);
143c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
144c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Restore the register values from the expression stack.
145c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if ((object_regs | non_object_regs) != 0) {
146c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      __ MultiPop(object_regs | non_object_regs);
147c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      for (int i = 0; i < kNumJSCallerSaved; i++) {
148c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        int r = JSCallerSavedCode(i);
149c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        Register reg = { r };
150c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if ((non_object_regs & (1 << r)) != 0) {
151c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          __ srl(reg, reg, kSmiTagSize);
152c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
153c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        if (FLAG_debug_code &&
154c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com            (((object_regs |non_object_regs) & (1 << r)) == 0)) {
155c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          __ li(reg, kDebugZapValue);
156c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        }
1577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org      }
1587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    }
1597304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1604b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    // Don't bother removing padding bytes pushed on the stack
1614b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org    // as the frame is going to be restored right away.
1624b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
163c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // Leave the internal frame.
164c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
1657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Now that the break point has been handled, resume normal execution by
1677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // jumping to the target address intended by the caller and that was
1687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // overwritten by the address of DebugBreakXXX.
169fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  ExternalReference after_break_target =
170fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org      ExternalReference::debug_after_break_target_address(masm->isolate());
171fb547e07aef43e02715c5d6c1530e84bb3cbba02machenbach@chromium.org  __ li(t9, Operand(after_break_target));
1727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ lw(t9, MemOperand(t9));
1737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ Jump(t9);
1747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org}
1757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
1767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
177d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
17826ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com  // Register state for CallICStub
17926ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com  // ----------- S t a t e -------------
18026ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com  //  -- a1 : function
18126ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com  //  -- a3 : slot in feedback array (smi)
18226ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com  // -----------------------------------
18326ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com  Generate_DebugBreakCallHelper(masm, a1.bit() | a3.bit(), 0);
18426ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com}
18526ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com
18626ff407a06ed21bb3a1d7d147a6c0c092a2dff6dpalfia@homejinni.com
187d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
1889aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register receiver = LoadDescriptor::ReceiverRegister();
1899aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register name = LoadDescriptor::NameRegister();
190248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
1915c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
1925c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1935c838251403b0be9a882540f1922577abba4c872ager@chromium.org
194d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
1957304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Calling convention for IC store (from ic-mips.cc).
1969aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register receiver = StoreDescriptor::ReceiverRegister();
1979aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register name = StoreDescriptor::NameRegister();
1989aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register value = StoreDescriptor::ValueRegister();
19970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  Generate_DebugBreakCallHelper(
20070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      masm, receiver.bit() | name.bit() | value.bit(), 0);
2015c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2025c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2035c838251403b0be9a882540f1922577abba4c872ager@chromium.org
204d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
20570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  // Calling convention for keyed IC load (from ic-mips.cc).
206f6e8ed2294f2eccae83564eead8b79ea050b9f21yangguo@chromium.org  GenerateLoadICDebugBreak(masm);
2075c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2085c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2095c838251403b0be9a882540f1922577abba4c872ager@chromium.org
210d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateKeyedStoreICDebugBreak(MacroAssembler* masm) {
21170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  // Calling convention for IC keyed store call (from ic-mips.cc).
2129aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register receiver = StoreDescriptor::ReceiverRegister();
2139aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register name = StoreDescriptor::NameRegister();
2149aaa825cf89e1bcfece269a453300ebf4a26d64dmachenbach@chromium.org  Register value = StoreDescriptor::ValueRegister();
21570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  Generate_DebugBreakCallHelper(
21670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org      masm, receiver.bit() | name.bit() | value.bit(), 0);
2175c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2195c838251403b0be9a882540f1922577abba4c872ager@chromium.org
220d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCompareNilICDebugBreak(MacroAssembler* masm) {
22187a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com  // Register state for CompareNil IC
22287a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com  // ----------- S t a t e -------------
22387a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com  //  -- a0    : value
22487a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com  // -----------------------------------
22587a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com  Generate_DebugBreakCallHelper(masm, a0.bit(), 0);
22687a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com}
22787a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com
22887a74ee197718a2c3049986df903f3141ab00255palfia@homejinni.com
229d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateReturnDebugBreak(MacroAssembler* masm) {
2307304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // In places other than IC call sites it is expected that v0 is TOS which
2317304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // is an object - this is not generally the case so this should be used with
2327304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // care.
2337304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_DebugBreakCallHelper(masm, v0.bit(), 0);
2345c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2355c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2365c838251403b0be9a882540f1922577abba4c872ager@chromium.org
237d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallFunctionStubDebugBreak(MacroAssembler* masm) {
238fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Register state for CallFunctionStub (from code-stubs-mips.cc).
2397304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // ----------- S t a t e -------------
240c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  //  -- a1 : function
2417304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // -----------------------------------
242c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit(), 0);
2435c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
2445c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2455c838251403b0be9a882540f1922577abba4c872ager@chromium.org
246d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubDebugBreak(MacroAssembler* masm) {
247fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Calling convention for CallConstructStub (from code-stubs-mips.cc).
248fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // ----------- S t a t e -------------
249fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  //  -- a0     : number of arguments (not smi)
250fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  //  -- a1     : constructor function
251fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // -----------------------------------
252fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit() , a0.bit());
253fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
254fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
255fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
256d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateCallConstructStubRecordDebugBreak(
257d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    MacroAssembler* masm) {
258fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Calling convention for CallConstructStub (from code-stubs-mips.cc).
259fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // ----------- S t a t e -------------
260fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  //  -- a0     : number of arguments (not smi)
261fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  //  -- a1     : constructor function
262f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  //  -- a2     : feedback array
263f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  //  -- a3     : feedback slot (smi)
264fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // -----------------------------------
265f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Generate_DebugBreakCallHelper(masm, a1.bit() | a2.bit() | a3.bit(), a0.bit());
266fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org}
267fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
268fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
269d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateSlot(MacroAssembler* masm) {
2707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // Generate enough nop's to make space for a call instruction. Avoid emitting
2717304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // the trampoline pool in the debug break slot code.
2727304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm);
2737304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Label check_codesize;
2747304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ bind(&check_codesize);
2757304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  __ RecordDebugBreakSlot();
2767304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  for (int i = 0; i < Assembler::kDebugBreakSlotInstructions; i++) {
2777304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org    __ nop(MacroAssembler::DEBUG_BREAK_NOP);
2787304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  }
279e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org  DCHECK_EQ(Assembler::kDebugBreakSlotInstructions,
2807304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org            masm->InstructionsGeneratedSince(&check_codesize));
2817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
2827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
284d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateSlotDebugBreak(MacroAssembler* masm) {
2857304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // In the places where a debug break slot is inserted no registers can contain
2867304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  // object pointers.
2877304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Generate_DebugBreakCallHelper(masm, 0, 0);
2887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org}
2897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
291d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GeneratePlainReturnLiveEdit(MacroAssembler* masm) {
2924b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ Ret();
293357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
294357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
2957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
296d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.orgvoid DebugCodegen::GenerateFrameDropperLiveEdit(MacroAssembler* masm) {
2974b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  ExternalReference restarter_frame_function_slot =
2984b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org      ExternalReference::debug_restarter_frame_function_pointer_address(
2994b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org          masm->isolate());
3004b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ li(at, Operand(restarter_frame_function_slot));
3014b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ sw(zero_reg, MemOperand(at, 0));
3024b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
3034b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  // We do not know our frame height, but set sp based on fp.
3044b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ Subu(sp, fp, Operand(kPointerSize));
3054b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
3064b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ Pop(ra, fp, a1);  // Return address, Frame, Function.
3074b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
3084b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  // Load context from the function.
3094b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset));
3104b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
3114b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  // Get function code.
3124b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ lw(at, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset));
3134b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ lw(at, FieldMemOperand(at, SharedFunctionInfo::kCodeOffset));
3144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ Addu(t9, at, Operand(Code::kHeaderSize - kHeapObjectTag));
3154b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org
316975b940441085887fc02bebf8877d5ec97e1e06cmachenbach@chromium.org  // Re-run JSFunction, a1 is function, cp is context.
3174b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org  __ Jump(t9);
318357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org}
319357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
3205c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3214b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.orgconst bool LiveEdit::kFrameDropperSupported = true;
322357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
323ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org#undef __
324357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
3255c838251403b0be9a882540f1922577abba4c872ager@chromium.org} }  // namespace v8::internal
3265c838251403b0be9a882540f1922577abba4c872ager@chromium.org
3279dfbea4c7d423c7bc1db94425cb78e7f7cf41f78erik.corry@gmail.com#endif  // V8_TARGET_ARCH_MIPS
328