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_S390_BASELINE_COMPILER_S390_INL_H_ 6#define V8_BASELINE_S390_BASELINE_COMPILER_S390_INL_H_ 7 8#include "src/base/logging.h" 9#include "src/baseline/baseline-compiler.h" 10 11namespace v8 { 12namespace internal { 13namespace baseline { 14 15#define __ basm_. 16 17void BaselineCompiler::Prologue() { 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 27 PrologueFillFrame(); 28} 29 30void BaselineCompiler::PrologueFillFrame() { 31 ASM_CODE_COMMENT(&masm_); 32 // Inlined register frame fill 33 interpreter::Register new_target_or_generator_register = 34 bytecode_->incoming_new_target_or_generator_register(); 35 if (FLAG_debug_code) { 36 __ masm()->CompareRoot(kInterpreterAccumulatorRegister, 37 RootIndex::kUndefinedValue); 38 __ masm()->Assert(eq, AbortReason::kUnexpectedValue); 39 } 40 int register_count = bytecode_->register_count(); 41 // Magic value 42 const int kLoopUnrollSize = 8; 43 const int new_target_index = new_target_or_generator_register.index(); 44 const bool has_new_target = new_target_index != kMaxInt; 45 if (has_new_target) { 46 DCHECK_LE(new_target_index, register_count); 47 for (int i = 0; i < new_target_index; i++) { 48 __ Push(kInterpreterAccumulatorRegister); 49 } 50 // Push new_target_or_generator. 51 __ Push(kJavaScriptCallNewTargetRegister); 52 register_count -= new_target_index + 1; 53 } 54 if (register_count < 2 * kLoopUnrollSize) { 55 // If the frame is small enough, just unroll the frame fill completely. 56 for (int i = 0; i < register_count; ++i) { 57 __ Push(kInterpreterAccumulatorRegister); 58 } 59 60 } else { 61 // Extract the first few registers to round to the unroll size. 62 int first_registers = register_count % kLoopUnrollSize; 63 for (int i = 0; i < first_registers; ++i) { 64 __ Push(kInterpreterAccumulatorRegister); 65 } 66 BaselineAssembler::ScratchRegisterScope temps(&basm_); 67 Register scratch = temps.AcquireScratch(); 68 69 __ Move(scratch, register_count / kLoopUnrollSize); 70 // We enter the loop unconditionally, so make sure we need to loop at least 71 // once. 72 DCHECK_GT(register_count / kLoopUnrollSize, 0); 73 Label loop; 74 __ Bind(&loop); 75 for (int i = 0; i < kLoopUnrollSize; ++i) { 76 __ Push(kInterpreterAccumulatorRegister); 77 } 78 __ masm()->SubS64(scratch, Operand(1)); 79 __ masm()->b(gt, &loop); 80 } 81} 82 83void BaselineCompiler::VerifyFrameSize() { 84 BaselineAssembler::ScratchRegisterScope temps(&basm_); 85 Register scratch = temps.AcquireScratch(); 86 87 __ masm()->AddS64(scratch, sp, 88 Operand(InterpreterFrameConstants::kFixedFrameSizeFromFp + 89 bytecode_->frame_size())); 90 __ masm()->CmpU64(scratch, fp); 91 __ masm()->Assert(eq, AbortReason::kUnexpectedStackPointer); 92} 93 94} // namespace baseline 95} // namespace internal 96} // namespace v8 97 98#endif // V8_BASELINE_S390_BASELINE_COMPILER_S390_INL_H_ 99