1 // Copyright 2013 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_ARM64_FRAME_CONSTANTS_ARM64_H_ 6 #define V8_EXECUTION_ARM64_FRAME_CONSTANTS_ARM64_H_ 7 8 #include "src/base/bits.h" 9 #include "src/base/macros.h" 10 #include "src/common/globals.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 // 18 // BOTTOM OF THE STACK HIGHEST ADDRESS 19 // slot Entry frame 20 // +---------------------+----------------------- 21 // -20 | saved register d15 | 22 // ... | ... | 23 // -13 | saved register d8 | 24 // |- - - - - - - - - - -| 25 // -12 | saved lr (x30) | 26 // |- - - - - - - - - - -| 27 // -11 | saved fp (x29) | 28 // |- - - - - - - - - - -| 29 // -10 | saved register x28 | 30 // ... | ... | 31 // -1 | saved register x19 | 32 // |- - - - - - - - - - -| 33 // 0 | bad frame pointer | <-- frame ptr 34 // | (0xFFF.. FF) | 35 // |- - - - - - - - - - -| 36 // 1 | stack frame marker | 37 // | (ENTRY) | 38 // |- - - - - - - - - - -| 39 // 2 | stack frame marker | 40 // | (0) | 41 // |- - - - - - - - - - -| 42 // 3 | C entry FP | 43 // |- - - - - - - - - - -| 44 // 4 | JS entry frame | 45 // | marker | 46 // |- - - - - - - - - - -| 47 // 5 | padding | <-- stack ptr 48 // -----+---------------------+----------------------- 49 // TOP OF THE STACK LOWEST ADDRESS 50 // 51 class EntryFrameConstants : public AllStatic { 52 public: 53 // This is the offset to where JSEntry pushes the current value of 54 // Isolate::c_entry_fp onto the stack. 55 static constexpr int kCallerFPOffset = -3 * kSystemPointerSize; 56 static constexpr int kFixedFrameSize = 6 * kSystemPointerSize; 57 58 // The following constants are defined so we can static-assert their values 59 // near the relevant JSEntry assembly code, not because they're actually very 60 // useful. 61 static constexpr int kCalleeSavedRegisterBytesPushedBeforeFpLrPair = 62 8 * kSystemPointerSize; 63 static constexpr int kCalleeSavedRegisterBytesPushedAfterFpLrPair = 64 10 * kSystemPointerSize; 65 static constexpr int kOffsetToCalleeSavedRegisters = 1 * kSystemPointerSize; 66 67 // These offsets refer to the immediate caller (a native frame), not to the 68 // previous JS exit frame like kCallerFPOffset above. 69 static constexpr int kDirectCallerFPOffset = 70 kCalleeSavedRegisterBytesPushedAfterFpLrPair + 71 kOffsetToCalleeSavedRegisters; 72 static constexpr int kDirectCallerPCOffset = 73 kDirectCallerFPOffset + 1 * kSystemPointerSize; 74 static constexpr int kDirectCallerSPOffset = 75 kDirectCallerPCOffset + 1 * kSystemPointerSize + 76 kCalleeSavedRegisterBytesPushedBeforeFpLrPair; 77 }; 78 79 class WasmCompileLazyFrameConstants : public TypedFrameConstants { 80 public: 81 static constexpr int kNumberOfSavedGpParamRegs = 8; 82 static constexpr int kNumberOfSavedFpParamRegs = 8; 83 84 // FP-relative. 85 static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1); 86 static constexpr int kFixedFrameSizeFromFp = 87 // Header is padded to 16 byte (see {MacroAssembler::EnterFrame}). 88 RoundUp<16>(TypedFrameConstants::kFixedFrameSizeFromFp) + 89 kNumberOfSavedGpParamRegs * kSystemPointerSize + 90 kNumberOfSavedFpParamRegs * kDoubleSize; 91 }; 92 93 // Frame constructed by the {WasmDebugBreak} builtin. 94 // After pushing the frame type marker, the builtin pushes all Liftoff cache 95 // registers (see liftoff-assembler-defs.h). 96 class WasmDebugBreakFrameConstants : public TypedFrameConstants { 97 public: 98 // {x0 .. x28} \ {x16, x17, x18, x26, x27} 99 static constexpr uint32_t kPushedGpRegs = 100 (1 << 29) - 1 - (1 << 16) - (1 << 17) - (1 << 18) - (1 << 26) - (1 << 27); 101 // {d0 .. d29}; {d15} is not used, but we still keep it for alignment reasons 102 // (the frame size needs to be a multiple of 16). 103 static constexpr uint32_t kPushedFpRegs = (1 << 30) - 1; 104 105 static constexpr int kNumPushedGpRegisters = 106 base::bits::CountPopulation(kPushedGpRegs); 107 static constexpr int kNumPushedFpRegisters = 108 base::bits::CountPopulation(kPushedFpRegs); 109 110 static constexpr int kLastPushedGpRegisterOffset = 111 // Header is padded to 16 byte (see {MacroAssembler::EnterFrame}). 112 -RoundUp<16>(TypedFrameConstants::kFixedFrameSizeFromFp) - 113 kSystemPointerSize * kNumPushedGpRegisters; 114 static constexpr int kLastPushedFpRegisterOffset = 115 kLastPushedGpRegisterOffset - kSimd128Size * kNumPushedFpRegisters; 116 117 // Offsets are fp-relative. GetPushedGpRegisterOffset(int reg_code)118 static int GetPushedGpRegisterOffset(int reg_code) { 119 DCHECK_NE(0, kPushedGpRegs & (1 << reg_code)); 120 uint32_t lower_regs = kPushedGpRegs & ((uint32_t{1} << reg_code) - 1); 121 return kLastPushedGpRegisterOffset + 122 base::bits::CountPopulation(lower_regs) * kSystemPointerSize; 123 } 124 GetPushedFpRegisterOffset(int reg_code)125 static int GetPushedFpRegisterOffset(int reg_code) { 126 DCHECK_NE(0, kPushedFpRegs & (1 << reg_code)); 127 uint32_t lower_regs = kPushedFpRegs & ((uint32_t{1} << reg_code) - 1); 128 return kLastPushedFpRegisterOffset + 129 base::bits::CountPopulation(lower_regs) * kSimd128Size; 130 } 131 }; 132 133 } // namespace internal 134 } // namespace v8 135 136 #endif // V8_EXECUTION_ARM64_FRAME_CONSTANTS_ARM64_H_ 137