5#ifndef V8_BASELINE_ARM64_BASELINE_ASSEMBLER_ARM64_INL_H_
6#define V8_BASELINE_ARM64_BASELINE_ASSEMBLER_ARM64_INL_H_
17class BaselineAssembler::ScratchRegisterScope {
26 wrapped_scope_.Include(x14, x15);
27 wrapped_scope_.Include(x19);
54 interpreter::Register interpreter_register) {
58 interpreter::Register interpreter_register, Register rscratch) {
59 return __ Add(rscratch, fp,
100 JumpIf(
cc, left, Immediate(right), target, distance);
106 __ TestAndBranchIfAllClear(value,
mask, target);
108 __ TestAndBranchIfAnySet(value,
mask, target);
110 __ Tst(value, Immediate(
mask));
117 __ CompareAndBranch(lhs, rhs,
cc, target);
119#if V8_STATIC_ROOTS_BOOL
120void BaselineAssembler::JumpIfJSAnyIsPrimitive(Register heap_object,
123 __ AssertNotSmi(heap_object);
124 ScratchRegisterScope temps(
this);
125 Register scratch = temps.AcquireScratch();
126 __ JumpIfJSAnyIsPrimitive(heap_object, scratch, target, distance);
133 ScratchRegisterScope temps(
this);
134 Register scratch = temps.AcquireScratch();
136 __ IsObjectType(
object, scratch, scratch, instance_type);
144 Register map, Label* target,
146 ScratchRegisterScope temps(
this);
147 Register type = temps.AcquireScratch();
150 JumpIf(
cc, type, instance_type, target);
155 ScratchRegisterScope temps(
this);
156 Register type = temps.AcquireScratch();
158 __ AssertNotSmi(map);
159 __ CompareObjectType(map, type, type, MAP_TYPE);
163 JumpIf(
cc, type, instance_type, target);
168 ScratchRegisterScope temps(
this);
169 Register tmp = temps.AcquireScratch();
170 __ Ldr(tmp, operand);
176 __ CompareTaggedAndBranch(value, smi,
cc, target);
183 __ CompareTaggedAndBranch(lhs, rhs,
cc, target);
188 ScratchRegisterScope temps(
this);
189 Register tmp = temps.AcquireScratch();
190 __ Ldr(tmp, operand);
191 __ CompareTaggedAndBranch(value, tmp,
cc, target);
194 Register value, Label* target,
196 ScratchRegisterScope temps(
this);
197 Register tmp = temps.AcquireScratch();
198 __ Ldr(tmp, operand);
199 __ CompareTaggedAndBranch(tmp, value,
cc, target);
203 JumpIf(
cc, value, Immediate(
byte), target);
210 __ Mov(output, Immediate(value.ptr()));
213 __ Str(source, output);
216 __ Mov(output, Operand(reference));
219 __ Mov(output, Operand(value));
222 __ Mov(output, Immediate(value));
225 __ Mov(output, source);
228 __ Mov(output, source);
233template <
typename Arg>
235 BaselineAssembler::ScratchRegisterScope* scope,
238 basm->Move(
reg, arg);
242 BaselineAssembler::ScratchRegisterScope* scope,
247template <
typename... Args>
253template <
typename Arg,
typename... Args>
259template <
typename... Args>
266template <
typename... Args>
268template <
typename... Args>
272template <
typename... Args>
278struct PushAllHelper<> {
282template <
typename Arg>
283struct PushAllHelper<Arg> {
290template <
typename Arg1,
typename Arg2,
typename... Args>
314template <
typename Arg>
331struct PushAllHelper<interpreter::RegisterList> {
334 for (
int reg_index = 0; reg_index < list.
register_count(); reg_index += 2) {
335 PushAll(basm, list[reg_index], list[reg_index + 1]);
341 if (reg_index % 2 == 0) {
346 for (; reg_index >= 1; reg_index -= 2) {
352template <
typename... T>
355struct PopAllHelper<> {
364template <
typename... T>
375template <
typename... T>
379 int push_count = detail::CountPushHelper<T...>::Count(vals...);
380 if (push_count % 2 == 0) {
388template <
typename... T>
393template <
typename... T>
395 detail::PopAllHelper<T...>::Pop(
this,
registers...);
416 Register source,
int offset) {
428 ScratchRegisterScope temps(
this);
429 Register tmp = temps.AcquireScratch();
430 __ Mov(tmp, Operand(value));
450 Register feedback_vector,
455 feedback_vector, slot, on_result,
460 int32_t weight, Label* skip_interrupt_label) {
462 ScratchRegisterScope scratch_scope(
this);
463 Register feedback_cell = scratch_scope.AcquireScratch();
466 Register interrupt_budget = scratch_scope.AcquireScratch().W();
467 __ Ldr(interrupt_budget,
470 __ Adds(interrupt_budget, interrupt_budget, weight);
471 __ Str(interrupt_budget,
473 if (skip_interrupt_label) {
476 __ B(
ge, skip_interrupt_label);
481 Register weight, Label* skip_interrupt_label) {
483 ScratchRegisterScope scratch_scope(
this);
484 Register feedback_cell = scratch_scope.AcquireScratch();
487 Register interrupt_budget = scratch_scope.AcquireScratch().W();
488 __ Ldr(interrupt_budget,
491 __ Adds(interrupt_budget, interrupt_budget, weight.W());
492 __ Str(interrupt_budget,
494 if (skip_interrupt_label)
__ B(
ge, skip_interrupt_label);
499 CompressionMode compression_mode) {
500 for (; depth > 0; --depth) {
508 uint32_t index, uint32_t depth) {
509 for (; depth > 0; --depth) {
518 for (; depth > 0; --depth) {
522 if (cell_index > 0) {
523 LoadTaggedField(context, context, SourceTextModule::kRegularExportsOffset);
527 LoadTaggedField(context, context, SourceTextModule::kRegularImportsOffset);
529 cell_index = -cell_index - 1;
536 int cell_index, uint32_t depth) {
537 for (; depth > 0; --depth) {
541 LoadTaggedField(context, context, SourceTextModule::kRegularExportsOffset);
550 BaselineAssembler::ScratchRegisterScope temps(
this);
551 Register tmp = temps.AcquireScratch();
561 __ And(output, lhs, Immediate(rhs));
565 Label** labels,
int num_labels) {
568 if (case_value_base != 0) {
573 ScratchRegisterScope scope(
this);
574 Register temp = scope.AcquireScratch();
577 __ Adr(temp, &table);
578 int entry_size_log2 = 2;
579#ifdef V8_ENABLE_CONTROL_FLOW_INTEGRITY
581 constexpr int instructions_per_jump_target = 1;
583 constexpr int instructions_per_jump_target = 0;
585 constexpr int instructions_per_label = 1 + instructions_per_jump_target;
586 __ Add(temp, temp, Operand(
reg,
UXTW, entry_size_log2));
589 const int instruction_count =
590 num_labels * instructions_per_label + instructions_per_jump_target;
591 MacroAssembler::BlockPoolsScope block_pools(
masm_,
594 for (
int i = 0;
i < num_labels; ++
i) {
611 Register params_size = BaselineLeaveFrameDescriptor::ParamsSizeRegister();
616 Label skip_interrupt_label;
624 __ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Sparkplug, 1);
629 __ Bind(&skip_interrupt_label);
632 BaselineAssembler::ScratchRegisterScope temps(&basm);
633 Register actual_params_size = temps.AcquireScratch();
635 __ Move(actual_params_size,
640 __ masm()->
Cmp(params_size, actual_params_size);
#define Assert(condition)
static constexpr int kFeedbackCellFromFp
static constexpr Register WeightRegister()
static const int kExtensionOffset
static V8_INLINE constexpr int OffsetOfElementAt(int index)
static const int kPreviousOffset
void Cmp(const Register &rn, int imm)
void PushArgument(const Register &arg)
void SmiUntag(Register reg, SBit s=LeaveCC)
void Assert(Condition cond, AbortReason reason) NOOP_UNLESS_DEBUG_CODE
void SmiTag(Register reg, SBit s=LeaveCC)
void Ret(Condition cond=al)
int LeaveFrame(StackFrame::Type type)
void Csel(const Register &rd, const Register &rn, const Operand &operand, Condition cond)
void CmpTagged(const Register &r1, const Register &r2)
void DropArguments(Register count)
const Register & base() const
const Register & regoffset() const
static constexpr Tagged< Smi > FromInt(int value)
static constexpr int kArgCOffset
static constexpr int kFeedbackVectorFromFp
BaselineAssembler * assembler_
UseScratchRegisterScope wrapped_scope_
ScratchRegisterScope * prev_scope_
Register AcquireScratch()
ScratchRegisterScope(BaselineAssembler *assembler)
void JumpIfByte(Condition cc, Register value, int32_t byte, Label *target, Label::Distance distance=Label::kFar)
void PushReverse(T... vals)
void CallRuntime(Runtime::FunctionId function, int nargs)
void JumpIf(Condition cc, Register lhs, const Operand &rhs, Label *target, Label::Distance distance=Label::kFar)
void LoadFixedArrayElement(Register output, Register array, int32_t index)
static MemOperand RegisterFrameOperand(interpreter::Register interpreter_register)
void JumpIfNotRoot(Register value, RootIndex index, Label *target, Label ::Distance distance=Label::kFar)
void JumpIfPointer(Condition cc, Register value, MemOperand operand, Label *target, Label::Distance distance=Label::kFar)
void Move(Register output, Register source)
static void EmitReturn(MacroAssembler *masm)
void MoveSmi(Register output, Register source)
void TestAndBranch(Register value, int mask, Condition cc, Label *target, Label::Distance distance=Label::kFar)
void LoadWord8Field(Register output, Register source, int offset)
void LoadWord16FieldZeroExtend(Register output, Register source, int offset)
void LoadMap(Register output, Register value)
void AddToInterruptBudgetAndJumpIfNotExceeded(int32_t weight, Label *skip_interrupt_label)
void LdaContextSlot(Register context, uint32_t index, uint32_t depth, CompressionMode compression_mode=CompressionMode::kDefault)
void LoadTaggedField(Register output, Register source, int offset)
void SmiUntag(Register value)
void Jump(Label *target, Label::Distance distance=Label::kFar)
void Switch(Register reg, int case_value_base, Label **labels, int num_labels)
void StaModuleVariable(Register context, Register value, int cell_index, uint32_t depth)
void LoadContext(Register output)
void JumpIfObjectTypeFast(Condition cc, Register object, InstanceType instance_type, Label *target, Label::Distance distance=Label::kFar)
void MoveMaybeSmi(Register output, Register source)
MemOperand FeedbackCellOperand()
void StoreTaggedFieldNoWriteBarrier(Register target, int offset, Register value)
void TryLoadOptimizedOsrCode(Register scratch_and_result, Register feedback_vector, FeedbackSlot slot, Label *on_result, Label::Distance distance)
void LoadFeedbackCell(Register output)
void LoadTaggedSignedFieldAndUntag(Register output, Register source, int offset)
ScratchRegisterScope * scratch_register_scope_
void JumpIfInstanceType(Condition cc, Register map, InstanceType instance_type, Label *target, Label::Distance distance=Label::kFar)
void JumpIfImmediate(Condition cc, Register left, int right, Label *target, Label::Distance distance=Label::kFar)
void JumpIfRoot(Register value, RootIndex index, Label *target, Label::Distance distance=Label::kFar)
MemOperand FeedbackVectorOperand()
void JumpIfSmi(Register value, Label *target, Label::Distance distance=Label::kFar)
void JumpIfNotSmi(Register value, Label *target, Label::Distance distance=Label::kFar)
void JumpIfObjectType(Condition cc, Register object, InstanceType instance_type, Register map, Label *target, Label::Distance distance=Label::kFar)
void LdaModuleVariable(Register context, int cell_index, uint32_t depth)
void IncrementSmi(MemOperand lhs)
void StoreTaggedFieldWithWriteBarrier(Register target, int offset, Register value)
void LoadTaggedSignedField(Register output, Register source, int offset)
void RegisterFrameAddress(interpreter::Register interpreter_register, Register rscratch)
void Word32And(Register output, Register lhs, int rhs)
void StoreTaggedSignedField(Register target, int offset, Tagged< Smi > value)
void StaContextSlot(Register context, Register value, uint32_t index, uint32_t depth)
BaselineAssembler(MacroAssembler *masm)
void JumpIfTagged(Condition cc, Register value, MemOperand operand, Label *target, Label::Distance distance=Label::kFar)
void LoadFunction(Register output)
void AssertEqualToAccumulator(Register reg)
BaselineAssembler * assembler_
int register_count() const
const RegisterList PopLeft() const
#define ASM_CODE_COMMENT_STRING(asm,...)
#define ASM_CODE_COMMENT(asm)
base::Vector< const DirectHandle< Object > > args
RegListBase< RegisterT > registers
void Add(RWDigits Z, Digits X, Digits Y)
void PushAll(BaselineAssembler *basm, Args... args)
Register ToRegister(BaselineAssembler *basm, BaselineAssembler::ScratchRegisterScope *scope, Arg arg)
void PushAllReverse(BaselineAssembler *basm, Args... args)
void And(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
void Sub(LiftoffAssembler *lasm, Register dst, Register lhs, Register rhs)
@ kUnsignedGreaterThanEqual
constexpr Register kInterpreterAccumulatorRegister
MemOperand FieldMemOperand(Register object, int offset)
constexpr int kSystemPointerSize
constexpr bool SmiValuesAre31Bits()
constexpr Register kContextRegister
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr uint8_t kInstrSize
constexpr Register kJSFunctionRegister
constexpr Register padreg
#define DCHECK_LT(v1, v2)
#define DCHECK_EQ(v1, v2)
static int Count(Arg arg, Args... args)
static int Count(interpreter::RegisterList list, Args... args)
static void Pop(BaselineAssembler *basm, Register reg1, Register reg2, T... tail)
static void Pop(BaselineAssembler *basm, Register reg)
static void Pop(BaselineAssembler *basm)
static void PushReverse(BaselineAssembler *basm, Arg1 arg1, Arg2 arg2, Args... args)
static void Push(BaselineAssembler *basm, Arg1 arg1, Arg2 arg2, Args... args)
static void Push(BaselineAssembler *basm, Arg arg, interpreter::RegisterList list)
static void PushReverse(BaselineAssembler *basm, Arg arg, interpreter::RegisterList list)
static void PushReverse(BaselineAssembler *basm, Arg arg)
static void Push(BaselineAssembler *basm, Arg)
static void PushReverse(BaselineAssembler *basm, interpreter::RegisterList list)
static void Push(BaselineAssembler *basm, interpreter::RegisterList list)
static void Push(BaselineAssembler *basm)
static void PushReverse(BaselineAssembler *basm)