Home | History | Annotate | Download | only in mips
      1 // Copyright 2011 the V8 project authors. All rights reserved.
      2 // Redistribution and use in source and binary forms, with or without
      3 // modification, are permitted provided that the following conditions are
      4 // met:
      5 //
      6 //     * Redistributions of source code must retain the above copyright
      7 //       notice, this list of conditions and the following disclaimer.
      8 //     * Redistributions in binary form must reproduce the above
      9 //       copyright notice, this list of conditions and the following
     10 //       disclaimer in the documentation and/or other materials provided
     11 //       with the distribution.
     12 //     * Neither the name of Google Inc. nor the names of its
     13 //       contributors may be used to endorse or promote products derived
     14 //       from this software without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 
     28 
     29 
     30 #ifndef V8_MIPS_FRAMES_MIPS_H_
     31 #define V8_MIPS_FRAMES_MIPS_H_
     32 
     33 namespace v8 {
     34 namespace internal {
     35 
     36 // Register lists.
     37 // Note that the bit values must match those used in actual instruction
     38 // encoding.
     39 const int kNumRegs = 32;
     40 
     41 const RegList kJSCallerSaved =
     42   1 << 2  |  // v0
     43   1 << 3  |  // v1
     44   1 << 4  |  // a0
     45   1 << 5  |  // a1
     46   1 << 6  |  // a2
     47   1 << 7  |  // a3
     48   1 << 8  |  // t0
     49   1 << 9  |  // t1
     50   1 << 10 |  // t2
     51   1 << 11 |  // t3
     52   1 << 12 |  // t4
     53   1 << 13 |  // t5
     54   1 << 14 |  // t6
     55   1 << 15;   // t7
     56 
     57 const int kNumJSCallerSaved = 14;
     58 
     59 
     60 // Return the code of the n-th caller-saved register available to JavaScript
     61 // e.g. JSCallerSavedReg(0) returns a0.code() == 4.
     62 int JSCallerSavedCode(int n);
     63 
     64 
     65 // Callee-saved registers preserved when switching from C to JavaScript.
     66 const RegList kCalleeSaved =
     67   1 << 16 |  // s0
     68   1 << 17 |  // s1
     69   1 << 18 |  // s2
     70   1 << 19 |  // s3
     71   1 << 20 |  // s4
     72   1 << 21 |  // s5
     73   1 << 22 |  // s6 (roots in Javascript code)
     74   1 << 23 |  // s7 (cp in Javascript code)
     75   1 << 30;   // fp/s8
     76 
     77 const int kNumCalleeSaved = 9;
     78 
     79 const RegList kCalleeSavedFPU =
     80   1 << 20 |  // f20
     81   1 << 22 |  // f22
     82   1 << 24 |  // f24
     83   1 << 26 |  // f26
     84   1 << 28 |  // f28
     85   1 << 30;   // f30
     86 
     87 const int kNumCalleeSavedFPU = 6;
     88 
     89 const RegList kCallerSavedFPU =
     90   1 << 0  |  // f0
     91   1 << 2  |  // f2
     92   1 << 4  |  // f4
     93   1 << 6  |  // f6
     94   1 << 8  |  // f8
     95   1 << 10 |  // f10
     96   1 << 12 |  // f12
     97   1 << 14 |  // f14
     98   1 << 16 |  // f16
     99   1 << 18;   // f18
    100 
    101 
    102 // Number of registers for which space is reserved in safepoints. Must be a
    103 // multiple of 8.
    104 const int kNumSafepointRegisters = 24;
    105 
    106 // Define the list of registers actually saved at safepoints.
    107 // Note that the number of saved registers may be smaller than the reserved
    108 // space, i.e. kNumSafepointSavedRegisters <= kNumSafepointRegisters.
    109 const RegList kSafepointSavedRegisters = kJSCallerSaved | kCalleeSaved;
    110 const int kNumSafepointSavedRegisters =
    111     kNumJSCallerSaved + kNumCalleeSaved;
    112 
    113 typedef Object* JSCallerSavedBuffer[kNumJSCallerSaved];
    114 
    115 const int kUndefIndex = -1;
    116 // Map with indexes on stack that corresponds to codes of saved registers.
    117 const int kSafepointRegisterStackIndexMap[kNumRegs] = {
    118   kUndefIndex,  // zero_reg
    119   kUndefIndex,  // at
    120   0,   // v0
    121   1,   // v1
    122   2,   // a0
    123   3,   // a1
    124   4,   // a2
    125   5,   // a3
    126   6,   // t0
    127   7,   // t1
    128   8,   // t2
    129   9,   // t3
    130   10,  // t4
    131   11,  // t5
    132   12,  // t6
    133   13,  // t7
    134   14,  // s0
    135   15,  // s1
    136   16,  // s2
    137   17,  // s3
    138   18,  // s4
    139   19,  // s5
    140   20,  // s6
    141   21,  // s7
    142   kUndefIndex,  // t8
    143   kUndefIndex,  // t9
    144   kUndefIndex,  // k0
    145   kUndefIndex,  // k1
    146   kUndefIndex,  // gp
    147   kUndefIndex,  // sp
    148   22,  // fp
    149   kUndefIndex
    150 };
    151 
    152 
    153 // ----------------------------------------------------
    154 
    155 class StackHandlerConstants : public AllStatic {
    156  public:
    157   static const int kNextOffset     = 0 * kPointerSize;
    158   static const int kCodeOffset     = 1 * kPointerSize;
    159   static const int kStateOffset    = 2 * kPointerSize;
    160   static const int kContextOffset  = 3 * kPointerSize;
    161   static const int kFPOffset       = 4 * kPointerSize;
    162 
    163   static const int kSize = kFPOffset + kPointerSize;
    164 };
    165 
    166 
    167 class EntryFrameConstants : public AllStatic {
    168  public:
    169   static const int kCallerFPOffset      = -3 * kPointerSize;
    170 };
    171 
    172 
    173 class ExitFrameConstants : public AllStatic {
    174  public:
    175   // See some explanation in MacroAssembler::EnterExitFrame.
    176   // This marks the top of the extra allocated stack space.
    177   static const int kStackSpaceOffset = -3 * kPointerSize;
    178 
    179   static const int kCodeOffset = -2 * kPointerSize;
    180 
    181   static const int kSPOffset = -1 * kPointerSize;
    182 
    183   // The caller fields are below the frame pointer on the stack.
    184   static const int kCallerFPOffset = +0 * kPointerSize;
    185   // The calling JS function is between FP and PC.
    186   static const int kCallerPCOffset = +1 * kPointerSize;
    187 
    188   // MIPS-specific: a pointer to the old sp to avoid unnecessary calculations.
    189   static const int kCallerSPOffset = +2 * kPointerSize;
    190 
    191   // FP-relative displacement of the caller's SP.
    192   static const int kCallerSPDisplacement = +2 * kPointerSize;
    193 };
    194 
    195 
    196 class StandardFrameConstants : public AllStatic {
    197  public:
    198   // Fixed part of the frame consists of return address, caller fp,
    199   // context and function.
    200   static const int kFixedFrameSize    =  4 * kPointerSize;
    201   static const int kExpressionsOffset = -3 * kPointerSize;
    202   static const int kMarkerOffset      = -2 * kPointerSize;
    203   static const int kContextOffset     = -1 * kPointerSize;
    204   static const int kCallerFPOffset    =  0 * kPointerSize;
    205   static const int kCallerPCOffset    = +1 * kPointerSize;
    206   static const int kCallerSPOffset    = +2 * kPointerSize;
    207 
    208   // Size of the MIPS 4 32-bit argument slots.
    209   // This is just an alias with a shorter name. Use it from now on.
    210   static const int kRArgsSlotsSize = 4 * kPointerSize;
    211   static const int kRegularArgsSlotsSize = kRArgsSlotsSize;
    212 
    213   // JS argument slots size.
    214   static const int kJSArgsSlotsSize = 0 * kPointerSize;
    215   // Assembly builtins argument slots size.
    216   static const int kBArgsSlotsSize = 0 * kPointerSize;
    217 };
    218 
    219 
    220 class JavaScriptFrameConstants : public AllStatic {
    221  public:
    222   // FP-relative.
    223   static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
    224   static const int kLastParameterOffset = +2 * kPointerSize;
    225   static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
    226 
    227   // Caller SP-relative.
    228   static const int kParam0Offset   = -2 * kPointerSize;
    229   static const int kReceiverOffset = -1 * kPointerSize;
    230 };
    231 
    232 
    233 class ArgumentsAdaptorFrameConstants : public AllStatic {
    234  public:
    235   static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
    236   static const int kFrameSize =
    237       StandardFrameConstants::kFixedFrameSize + kPointerSize;
    238 };
    239 
    240 
    241 class InternalFrameConstants : public AllStatic {
    242  public:
    243   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
    244 };
    245 
    246 
    247 inline Object* JavaScriptFrame::function_slot_object() const {
    248   const int offset = JavaScriptFrameConstants::kFunctionOffset;
    249   return Memory::Object_at(fp() + offset);
    250 }
    251 
    252 
    253 } }  // namespace v8::internal
    254 
    255 #endif
    256