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_X64_FRAME_CONSTANTS_X64_H_
6#define V8_EXECUTION_X64_FRAME_CONSTANTS_X64_H_
7
8#include "src/base/bits.h"
9#include "src/base/macros.h"
10#include "src/codegen/register.h"
11#include "src/execution/frame-constants.h"
12
13namespace v8 {
14namespace internal {
15
16class EntryFrameConstants : public AllStatic {
17 public:
18#ifdef V8_TARGET_OS_WIN
19  static constexpr int kCalleeSaveXMMRegisters = 10;
20  static constexpr int kXMMRegisterSize = 16;
21  static constexpr int kXMMRegistersBlockSize =
22      kXMMRegisterSize * kCalleeSaveXMMRegisters;
23
24  // This is the offset to where JSEntry pushes the current value of
25  // Isolate::c_entry_fp onto the stack.
26  // On x64, there are 7 pushq() and 3 Push() calls between setting up rbp and
27  // pushing the c_entry_fp, plus we manually allocate kXMMRegistersBlockSize
28  // bytes on the stack.
29  static constexpr int kCallerFPOffset = -3 * kSystemPointerSize +
30                                         -7 * kSystemPointerSize -
31                                         kXMMRegistersBlockSize;
32
33  // Stack offsets for arguments passed to JSEntry.
34  static constexpr int kArgcOffset = 6 * kSystemPointerSize;
35  static constexpr int kArgvOffset = 7 * kSystemPointerSize;
36#else
37  // This is the offset to where JSEntry pushes the current value of
38  // Isolate::c_entry_fp onto the stack.
39  // On x64, there are 5 pushq() and 3 Push() calls between setting up rbp and
40  // pushing the c_entry_fp.
41  static constexpr int kCallerFPOffset =
42      -3 * kSystemPointerSize + -5 * kSystemPointerSize;
43#endif
44};
45
46class WasmCompileLazyFrameConstants : public TypedFrameConstants {
47 public:
48  static constexpr int kNumberOfSavedGpParamRegs = 6;
49  static constexpr int kNumberOfSavedFpParamRegs = 6;
50
51  // FP-relative.
52  static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
53  static constexpr int kFixedFrameSizeFromFp =
54      TypedFrameConstants::kFixedFrameSizeFromFp +
55      kNumberOfSavedGpParamRegs * kSystemPointerSize +
56      kNumberOfSavedFpParamRegs * kSimd128Size;
57};
58
59// Frame constructed by the {WasmDebugBreak} builtin.
60// After pushing the frame type marker, the builtin pushes all Liftoff cache
61// registers (see liftoff-assembler-defs.h).
62class WasmDebugBreakFrameConstants : public TypedFrameConstants {
63 public:
64  static constexpr RegList kPushedGpRegs = {rax, rcx, rdx, rbx, rsi, rdi, r9};
65
66  static constexpr DoubleRegList kPushedFpRegs = {xmm0, xmm1, xmm2, xmm3,
67                                                  xmm4, xmm5, xmm6, xmm7};
68
69  static constexpr int kNumPushedGpRegisters = kPushedGpRegs.Count();
70  static constexpr int kNumPushedFpRegisters = kPushedFpRegs.Count();
71
72  static constexpr int kLastPushedGpRegisterOffset =
73      -kFixedFrameSizeFromFp - kNumPushedGpRegisters * kSystemPointerSize;
74  static constexpr int kLastPushedFpRegisterOffset =
75      kLastPushedGpRegisterOffset - kNumPushedFpRegisters * kSimd128Size;
76
77  // Offsets are fp-relative.
78  static int GetPushedGpRegisterOffset(int reg_code) {
79    DCHECK_NE(0, kPushedGpRegs.bits() & (1 << reg_code));
80    uint32_t lower_regs =
81        kPushedGpRegs.bits() & ((uint32_t{1} << reg_code) - 1);
82    return kLastPushedGpRegisterOffset +
83           base::bits::CountPopulation(lower_regs) * kSystemPointerSize;
84  }
85
86  static int GetPushedFpRegisterOffset(int reg_code) {
87    DCHECK_NE(0, kPushedFpRegs.bits() & (1 << reg_code));
88    uint32_t lower_regs =
89        kPushedFpRegs.bits() & ((uint32_t{1} << reg_code) - 1);
90    return kLastPushedFpRegisterOffset +
91           base::bits::CountPopulation(lower_regs) * kSimd128Size;
92  }
93};
94
95}  // namespace internal
96}  // namespace v8
97
98#endif  // V8_EXECUTION_X64_FRAME_CONSTANTS_X64_H_
99