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