• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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