1// Copyright 2021 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_BASELINE_RISCV64_BASELINE_COMPILER_RISCV64_INL_H_
6#define V8_BASELINE_RISCV64_BASELINE_COMPILER_RISCV64_INL_H_
7
8#include "src/baseline/baseline-compiler.h"
9
10namespace v8 {
11namespace internal {
12namespace baseline {
13
14#define __ basm_.
15
16void BaselineCompiler::Prologue() {
17  ASM_CODE_COMMENT(&masm_);
18  // Enter the frame here, since CallBuiltin will override lr.
19  __ masm()->EnterFrame(StackFrame::BASELINE);
20  DCHECK_EQ(kJSFunctionRegister, kJavaScriptCallTargetRegister);
21  int max_frame_size =
22      bytecode_->frame_size() + max_call_args_ * kSystemPointerSize;
23  CallBuiltin<Builtin::kBaselineOutOfLinePrologue>(
24      kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
25      max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
26  PrologueFillFrame();
27}
28
29void BaselineCompiler::PrologueFillFrame() {
30  ASM_CODE_COMMENT(&masm_);
31  // Inlined register frame fill
32  interpreter::Register new_target_or_generator_register =
33      bytecode_->incoming_new_target_or_generator_register();
34  __ LoadRoot(kInterpreterAccumulatorRegister, RootIndex::kUndefinedValue);
35  int register_count = bytecode_->register_count();
36  // Magic value
37  const int kLoopUnrollSize = 8;
38  const int new_target_index = new_target_or_generator_register.index();
39  const bool has_new_target = new_target_index != kMaxInt;
40  if (has_new_target) {
41    DCHECK_LE(new_target_index, register_count);
42    __ masm()->Add64(sp, sp, Operand(-(kPointerSize * new_target_index)));
43    for (int i = 0; i < new_target_index; i++) {
44      __ masm()->Sd(kInterpreterAccumulatorRegister, MemOperand(sp, i * 8));
45    }
46    // Push new_target_or_generator.
47    __ Push(kJavaScriptCallNewTargetRegister);
48    register_count -= new_target_index + 1;
49  }
50  if (register_count < 2 * kLoopUnrollSize) {
51    // If the frame is small enough, just unroll the frame fill completely.
52    __ masm()->Add64(sp, sp, Operand(-(kPointerSize * register_count)));
53    for (int i = 0; i < register_count; ++i) {
54      __ masm()->Sd(kInterpreterAccumulatorRegister, MemOperand(sp, i * 8));
55    }
56  } else {
57    __ masm()->Add64(sp, sp, Operand(-(kPointerSize * register_count)));
58    for (int i = 0; i < register_count; ++i) {
59      __ masm()->Sd(kInterpreterAccumulatorRegister, MemOperand(sp, i * 8));
60    }
61  }
62}
63
64void BaselineCompiler::VerifyFrameSize() {
65  ASM_CODE_COMMENT(&masm_);
66  __ masm()->Add64(kScratchReg, sp,
67                   Operand(InterpreterFrameConstants::kFixedFrameSizeFromFp +
68                           bytecode_->frame_size()));
69  __ masm()->Assert(eq, AbortReason::kUnexpectedStackPointer, kScratchReg,
70                    Operand(fp));
71}
72
73#undef __
74
75}  // namespace baseline
76}  // namespace internal
77}  // namespace v8
78
79#endif  // V8_BASELINE_RISCV64_BASELINE_COMPILER_RISCV64_INL_H_
80