// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.



#ifndef V8_MIPS_FRAMES_MIPS_H_
#define V8_MIPS_FRAMES_MIPS_H_

namespace v8 {
namespace internal {

// Register lists.
// Note that the bit values must match those used in actual instruction
// encoding.
static const int kNumRegs = 32;

static const RegList kJSCallerSaved =
  1 << 2  |  // v0
  1 << 3  |  // v1
  1 << 4  |  // a0
  1 << 5  |  // a1
  1 << 6  |  // a2
  1 << 7  |  // a3
  1 << 8  |  // t0
  1 << 9  |  // t1
  1 << 10 |  // t2
  1 << 11 |  // t3
  1 << 12 |  // t4
  1 << 13 |  // t5
  1 << 14 |  // t6
  1 << 15;   // t7

static const int kNumJSCallerSaved = 14;


// Return the code of the n-th caller-saved register available to JavaScript
// e.g. JSCallerSavedReg(0) returns a0.code() == 4.
int JSCallerSavedCode(int n);


// Callee-saved registers preserved when switching from C to JavaScript.
static const RegList kCalleeSaved =
  1 << 16 |  // s0
  1 << 17 |  // s1
  1 << 18 |  // s2
  1 << 19 |  // s3
  1 << 20 |  // s4
  1 << 21 |  // s5
  1 << 22 |  // s6 (roots in Javascript code)
  1 << 23 |  // s7 (cp in Javascript code)
  1 << 30;   // fp/s8

static const int kNumCalleeSaved = 9;

static const RegList kCalleeSavedFPU =
  1 << 20 |  // f20
  1 << 22 |  // f22
  1 << 24 |  // f24
  1 << 26 |  // f26
  1 << 28 |  // f28
  1 << 30;   // f30

static const int kNumCalleeSavedFPU = 6;
// Number of registers for which space is reserved in safepoints. Must be a
// multiple of 8.
static const int kNumSafepointRegisters = 24;

// Define the list of registers actually saved at safepoints.
// Note that the number of saved registers may be smaller than the reserved
// space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
static const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
static const int kNumSafepointSavedRegisters =
    kNumJSCallerSaved + kNumCalleeSaved;

typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved];

static const int kUndefIndex = -1;
// Map with indexes on stack that corresponds to codes of saved registers.
static const int kSafepointRegisterStackIndexMap[kNumRegs] = {
  kUndefIndex,  // zero_reg
  kUndefIndex,  // at
  0,   // v0
  1,   // v1
  2,   // a0
  3,   // a1
  4,   // a2
  5,   // a3
  6,   // t0
  7,   // t1
  8,   // t2
  9,   // t3
  10,  // t4
  11,  // t5
  12,  // t6
  13,  // t7
  14,  // s0
  15,  // s1
  16,  // s2
  17,  // s3
  18,  // s4
  19,  // s5
  20,  // s6
  21,  // s7
  kUndefIndex,  // t8
  kUndefIndex,  // t9
  kUndefIndex,  // k0
  kUndefIndex,  // k1
  kUndefIndex,  // gp
  kUndefIndex,  // sp
  22,  // fp
  kUndefIndex
};


// ----------------------------------------------------

class StackHandlerConstants : public AllStatic {
 public:
  static const int kNextOffset    = 0 * kPointerSize;
  static const int kStateOffset   = 1 * kPointerSize;
  static const int kContextOffset = 2 * kPointerSize;
  static const int kFPOffset      = 3 * kPointerSize;
  static const int kPCOffset      = 4 * kPointerSize;

  static const int kSize = kPCOffset + kPointerSize;
};


class EntryFrameConstants : public AllStatic {
 public:
  static const int kCallerFPOffset      = -3 * kPointerSize;
};


class ExitFrameConstants : public AllStatic {
 public:
  // See some explanation in MacroAssembler::EnterExitFrame.
  // This marks the top of the extra allocated stack space.
  static const int kStackSpaceOffset = -3 * kPointerSize;

  static const int kCodeOffset = -2 * kPointerSize;

  static const int kSPOffset = -1 * kPointerSize;

  // The caller fields are below the frame pointer on the stack.
  static const int kCallerFPOffset = +0 * kPointerSize;
  // The calling JS function is between FP and PC.
  static const int kCallerPCOffset = +1 * kPointerSize;

  // MIPS-specific: a pointer to the old sp to avoid unnecessary calculations.
  static const int kCallerSPOffset = +2 * kPointerSize;

  // FP-relative displacement of the caller's SP.
  static const int kCallerSPDisplacement = +2 * kPointerSize;
};


class StandardFrameConstants : public AllStatic {
 public:
  static const int kExpressionsOffset = -3 * kPointerSize;
  static const int kMarkerOffset      = -2 * kPointerSize;
  static const int kContextOffset     = -1 * kPointerSize;
  static const int kCallerFPOffset    =  0 * kPointerSize;
  static const int kCallerPCOffset    = +1 * kPointerSize;
  static const int kCallerSPOffset    = +2 * kPointerSize;

  // Size of the MIPS 4 32-bit argument slots.
  // This is just an alias with a shorter name. Use it from now on.
  static const int kRArgsSlotsSize = 4 * kPointerSize;
  static const int kRegularArgsSlotsSize = kRArgsSlotsSize;

  // JS argument slots size.
  static const int kJSArgsSlotsSize = 0 * kPointerSize;
  // Assembly builtins argument slots size.
  static const int kBArgsSlotsSize = 0 * kPointerSize;
};


class JavaScriptFrameConstants : public AllStatic {
 public:
  // FP-relative.
  static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
  static const int kLastParameterOffset = +2 * kPointerSize;
  static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;

  // Caller SP-relative.
  static const int kParam0Offset   = -2 * kPointerSize;
  static const int kReceiverOffset = -1 * kPointerSize;
};


class ArgumentsAdaptorFrameConstants : public AllStatic {
 public:
  static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
};


class InternalFrameConstants : public AllStatic {
 public:
  static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
};


inline Object* JavaScriptFrame::function_slot_object() const {
  const int offset = JavaScriptFrameConstants::kFunctionOffset;
  return Memory::Object_at(fp() + offset);
}


} }  // namespace v8::internal

#endif
