1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_EXECUTION_ARM_FRAME_CONSTANTS_ARM_H_ 6 #define V8_EXECUTION_ARM_FRAME_CONSTANTS_ARM_H_ 7 8 #include "src/base/bits.h" 9 #include "src/base/macros.h" 10 #include "src/codegen/arm/register-arm.h" 11 #include "src/execution/frame-constants.h" 12 13 namespace v8 { 14 namespace internal { 15 16 // The layout of an EntryFrame is as follows: 17 // TOP OF THE STACK LOWEST ADDRESS 18 // +---------------------+----------------------- 19 // 0 | bad frame pointer | <-- frame ptr 20 // | (0xFFF.. FF) | 21 // |- - - - - - - - - - -| 22 // 1..2 | saved register d8 | 23 // ... | ... | 24 // 15..16 | saved register d15 | 25 // |- - - - - - - - - - -| 26 // 17 | saved register r4 | 27 // ... | ... | 28 // 23 | saved register r10 | 29 // |- - - - - - - - - - -| 30 // 24 | saved fp (r11) | 31 // |- - - - - - - - - - -| 32 // 25 | saved lr (r14) | 33 // -----+---------------------+----------------------- 34 // BOTTOM OF THE STACK HIGHEST ADDRESS 35 class EntryFrameConstants : public AllStatic { 36 public: 37 // This is the offset to where JSEntry pushes the current value of 38 // Isolate::c_entry_fp onto the stack. 39 static constexpr int kCallerFPOffset = -3 * kSystemPointerSize; 40 41 // Stack offsets for arguments passed to JSEntry. 42 static constexpr int kArgcOffset = +0 * kSystemPointerSize; 43 static constexpr int kArgvOffset = +1 * kSystemPointerSize; 44 45 // These offsets refer to the immediate caller (i.e a native frame). 46 static constexpr int kDirectCallerRRegistersOffset = 47 /* bad frame pointer (-1) */ 48 kPointerSize + 49 /* d8...d15 */ 50 kNumDoubleCalleeSaved * kDoubleSize; 51 static constexpr int kDirectCallerFPOffset = 52 kDirectCallerRRegistersOffset + 53 /* r4...r10 (i.e. callee saved without fp) */ 54 (kNumCalleeSaved - 1) * kPointerSize; 55 static constexpr int kDirectCallerPCOffset = 56 kDirectCallerFPOffset + 1 * kSystemPointerSize; 57 static constexpr int kDirectCallerSPOffset = 58 kDirectCallerPCOffset + 1 * kSystemPointerSize; 59 }; 60 61 class WasmCompileLazyFrameConstants : public TypedFrameConstants { 62 public: 63 static constexpr int kNumberOfSavedGpParamRegs = 4; 64 static constexpr int kNumberOfSavedFpParamRegs = 8; 65 66 // FP-relative. 67 static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0); 68 static constexpr int kFixedFrameSizeFromFp = 69 TypedFrameConstants::kFixedFrameSizeFromFp + 70 kNumberOfSavedGpParamRegs * kPointerSize + 71 kNumberOfSavedFpParamRegs * kDoubleSize; 72 }; 73 74 // Frame constructed by the {WasmDebugBreak} builtin. 75 // After pushing the frame type marker, the builtin pushes all Liftoff cache 76 // registers (see liftoff-assembler-defs.h). 77 class WasmDebugBreakFrameConstants : public TypedFrameConstants { 78 public: 79 // {r0, r1, r2, r3, r4, r5, r6, r8, r9} 80 static constexpr uint32_t kPushedGpRegs = 0b1101111111; 81 // {d0 .. d12} 82 static constexpr int kFirstPushedFpReg = 0; 83 static constexpr int kLastPushedFpReg = 12; 84 85 static constexpr int kNumPushedGpRegisters = 86 base::bits::CountPopulation(kPushedGpRegs); 87 static constexpr int kNumPushedFpRegisters = 88 kLastPushedFpReg - kFirstPushedFpReg + 1; 89 90 static constexpr int kLastPushedGpRegisterOffset = 91 -TypedFrameConstants::kFixedFrameSizeFromFp - 92 kSystemPointerSize * kNumPushedGpRegisters; 93 static constexpr int kLastPushedFpRegisterOffset = 94 kLastPushedGpRegisterOffset - kDoubleSize * kNumPushedFpRegisters; 95 96 // Offsets are fp-relative. GetPushedGpRegisterOffset(int reg_code)97 static int GetPushedGpRegisterOffset(int reg_code) { 98 DCHECK_NE(0, kPushedGpRegs & (1 << reg_code)); 99 uint32_t lower_regs = kPushedGpRegs & ((uint32_t{1} << reg_code) - 1); 100 return kLastPushedGpRegisterOffset + 101 base::bits::CountPopulation(lower_regs) * kSystemPointerSize; 102 } 103 GetPushedFpRegisterOffset(int reg_code)104 static int GetPushedFpRegisterOffset(int reg_code) { 105 DCHECK_LE(kFirstPushedFpReg, reg_code); 106 DCHECK_GE(kLastPushedFpReg, reg_code); 107 return kLastPushedFpRegisterOffset + 108 (reg_code - kFirstPushedFpReg) * kDoubleSize; 109 } 110 }; 111 112 } // namespace internal 113 } // namespace v8 114 115 #endif // V8_EXECUTION_ARM_FRAME_CONSTANTS_ARM_H_ 116