5#ifndef V8_CODEGEN_ARM_MACRO_ASSEMBLER_ARM_H_
6#define V8_CODEGEN_ARM_MACRO_ASSEMBLER_ARM_H_
8#ifndef INCLUDED_FROM_MACRO_ASSEMBLER_H
9#error This header must be included via macro-assembler.h
51 using MacroAssemblerBase::MacroAssemblerBase;
55 bool load_constant_pool_pointer_reg =
false);
65 void AllocateStackSpace(
Register bytes_scratch);
66 void AllocateStackSpace(
int bytes);
71 if (bytes == 0)
return;
77 void PushCommonFrame(
Register marker_reg = no_reg);
87 void PushStandardFrame(
Register function_reg);
89 void InitializeRootRegister();
100 stm(
db_w, sp, {src1, src2}, cond);
111 stm(
db_w, sp, {src1, src2, src3}, cond);
113 stm(
db_w, sp, {src1, src2}, cond);
118 Push(src2, src3, cond);
128 stm(
db_w, sp, {src1, src2, src3, src4}, cond);
130 stm(
db_w, sp, {src1, src2, src3}, cond);
134 stm(
db_w, sp, {src1, src2}, cond);
135 Push(src3, src4, cond);
139 Push(src2, src3, src4, cond);
150 stm(
db_w, sp, {src1, src2, src3, src4, src5}, cond);
152 stm(
db_w, sp, {src1, src2, src3, src4}, cond);
156 stm(
db_w, sp, {src1, src2, src3}, cond);
157 Push(src4, src5, cond);
160 stm(
db_w, sp, {src1, src2}, cond);
161 Push(src3, src4, src5, cond);
165 Push(src2, src3, src4, src5, cond);
181 ldm(
ia_w, sp, {src1, src2}, cond);
193 ldm(
ia_w, sp, {src1, src2, src3}, cond);
196 ldm(
ia_w, sp, {src1, src2}, cond);
199 Pop(src2, src3, cond);
211 ldm(
ia_w, sp, {src1, src2, src3, src4}, cond);
214 ldm(
ia_w, sp, {src1, src2, src3}, cond);
217 Pop(src3, src4, cond);
218 ldm(
ia_w, sp, {src1, src2}, cond);
221 Pop(src2, src3, src4, cond);
236 void PrepareCallCFunction(
int num_reg_arguments,
int num_double_registers = 0,
255 Label* return_label =
nullptr);
257 Register function,
int num_arguments,
259 Label* return_label =
nullptr);
262 int num_double_arguments,
264 Label* return_label =
nullptr);
266 Register function,
int num_reg_arguments,
int num_double_arguments,
268 Label* return_label =
nullptr);
317 return ExternalReferenceAsOperand(ExternalReference::Create(
id),
no_reg);
324 bool check_constant_pool =
true);
328 bool check_constant_pool =
true);
339#ifdef V8_ENABLE_LEAPTIERING
346 void LoadCodeInstructionStart(
354 void CallJSFunction(
Register function_object, uint16_t argument_count);
355 void JumpJSFunction(
Register function_object,
357#ifdef V8_ENABLE_LEAPTIERING
359 uint16_t argument_count);
361#ifdef V8_ENABLE_WEBASSEMBLY
362 void ResolveWasmCodePointer(
Register target);
363 void CallWasmCodePointer(
Register target,
370 void StoreReturnAddressAndCall(
Register target);
377 void BailoutIfDeoptimized();
378 void CallForDeoptimization(
Builtin target,
int deopt_id,
Label* exit,
380 Label* jump_deoptimization_entry_label);
406 VFPCanonicalizeNaN(value, value, cond);
415 Label* condition_met);
417 Label* condition_met) {
418 CheckPageFlag(
object,
mask,
cc, condition_met);
431 void CallRecordWriteStubSaveRegisters(
434 void CallRecordWriteStub(
467 Register exclusion3 = no_reg)
const;
537 if (!src.IsRegister() || src.rm() != dst || sbit !=
LeaveCC) {
538 mov(dst, src, sbit, cond);
562 static int ActivationFrameAlignment();
567 mov(
reg, Operand::SmiUntag(
reg), s);
570 mov(dst, Operand::SmiUntag(src), s);
675 LoadTaggedField(dst, src);
681 str(value, dst_field_operand);
687 StoreTaggedField(value, dst_field_operand);
691 Label** labels,
int num_labels);
694 Label* if_marked_for_deoptimization);
697 Label* if_turbofanned);
701 void TryLoadOptimizedOsrCode(
Register scratch_and_result,
726 return base::OS::ArmUsingHardFloat();
727#elif USE_EABI_HARDFLOAT
736 void ComputeCodeStartAddress(
Register dst);
791 void EnterExitFrame(
Register scratch,
int stack_space,
795 void LeaveExitFrame(
Register scratch);
800 void LoadNativeContextSlot(
Register dst,
int index);
827 void PushStackHandler();
831 void PopStackHandler();
875 LoadRoot(scratch, index);
881 CompareRoot(with, index);
887 CompareRoot(with, index);
895 unsigned higher_limit);
897 unsigned higher_limit,
Label* on_in_range);
907 void ReplaceClosureCodeWithOptimizedCode(
Register optimized_code,
912 void LoadFeedbackVectorFlagsAndJumpIfNeedsProcessing(
914 Label* flags_need_processing);
915 void OptimizeCodeOrTailCallOptimizedCodeSlot(
Register flags,
932 CallRuntime(Runtime::FunctionForId(fid), num_arguments);
940 bool builtin_exit_frame =
false);
951 if (!
v8_flags.native_code_counters)
return;
952 EmitIncrementCounter(counter, value, scratch1, scratch2);
958 if (!
v8_flags.native_code_counters)
return;
959 EmitDecrementCounter(counter, value, scratch1, scratch2);
968 Label* stack_overflow);
986 AbortReason reason = AbortReason::kOperandIsNotASmi)
1009 void AssertUndefinedOrAllocationSite(
Register object,
1015 template <
typename Field>
1017 Ubfx(dst, src, Field::kShift, Field::kSize);
1020 template <
typename Field>
1022 DecodeField<Field>(
reg,
reg);
1030 void InvokePrologue(
Register expected_parameter_count,
1054 template <
typename T>
1056 template <
typename T>
1058 template <
typename T>
1060 template <
typename T>
1064 int num_double_arguments);
1075 std::optional<UseScratchRegisterScope>
temps;
1103 Register function_address,
1104 ExternalReference thunk_ref, Register thunk_arg,
1105 int slots_to_drop_on_return,
1109#define ACCESS_MASM(masm) masm->
static constexpr int kFixedSlotCountAboveFp
void JumpIfRoot(Register with, RootIndex index, Label *if_equal)
void PushAll(RegList registers)
void SmiUntag(Register dst, Register src, SBit s=LeaveCC)
void Call(Register target, Condition cond=al)
void DecompressTagged(const Register &destination, const Register &source)
void VmovExtended(const MemOperand &dst, int src_code)
void VmovHigh(DwVfpRegister dst, Register src)
void VFPCanonicalizeNaN(const DwVfpRegister value, const Condition cond=al)
void TestCodeIsMarkedForDeoptimization(Register code, Register scratch)
void FloatMinOutOfLine(DwVfpRegister result, DwVfpRegister left, DwVfpRegister right)
void Cmp(const Register &rn, int imm)
void AssertMap(Register object) NOOP_UNLESS_DEBUG_CODE
void DecodeField(Register reg)
void JumpIfIsInRange(Register value, Register scratch, unsigned lower_limit, unsigned higher_limit, Label *on_in_range)
void Drop(int count, Condition cond=al)
void CompareInstanceType(Register map, Register type_reg, InstanceType type)
void CallRuntime(Runtime::FunctionId fid)
int CalculateStackPassedWords(int num_reg_arguments, int num_double_arguments)
void MovFromFloatResult(DwVfpRegister dst)
void Pop(Register src1, Register src2, Register src3, Condition cond=al)
void VFPCompareAndLoadFlags(const SwVfpRegister src1, const float src2, const Register fpscr_flags, const Condition cond=al)
void Push(Register src1, Register src2, Register src3, Condition cond=al)
void Push(Register src1, Register src2, Condition cond=al)
void Move(Register dst, Register src, Condition cond=al)
void Pop(Register src1, Register src2, Condition cond=al)
void I64x2GtS(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2)
void SmiUntag(Register reg, SBit s=LeaveCC)
void DecodeField(Register dst, Register src)
void JumpIfNotRoot(Register with, RootIndex index, Label *if_not_equal)
void Move(DwVfpRegister dst, DwVfpRegister src, Condition cond=al)
void I64x2Eq(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2)
void I64x2AllTrue(Register dst, QwNeonRegister src)
void CompareRoot(Register obj, RootIndex index)
void VFPCompareAndSetFlags(const DwVfpRegister src1, const DwVfpRegister src2, const Condition cond=al)
void MovFromFloatParameter(DwVfpRegister dst)
void LoadLane(NeonSize sz, NeonListOperand dst_list, uint8_t lane, NeonMemOperand src)
void CompareObjectType(Register heap_object, Register map, Register type_reg, InstanceType type)
void Move(Register dst, Tagged< Smi > smi)
void SmiTst(Register value)
void Assert(Condition cond, AbortReason reason) NOOP_UNLESS_DEBUG_CODE
void Move(Register dst, const MemOperand &src)
void Push(Register src1, Register src2, Register src3, Register src4, Condition cond=al)
void FloatMaxOutOfLineHelper(T result, T left, T right)
void I64x2Ne(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2)
void StackOverflowCheck(Register num_args, Register scratch, Label *stack_overflow)
void ReplaceLane(QwNeonRegister dst, QwNeonRegister src, Register src_lane, NeonDataType dt, int lane)
void AssertFeedbackVector(Register object, Register scratch) NOOP_UNLESS_DEBUG_CODE
void JumpIfSmi(Register value, Label *smi_label)
void LoadRoot(Register destination, RootIndex index, Condition cond)
void SmiTag(Register dst, Register src, SBit s=LeaveCC)
void SaveFPRegsToHeap(Register location, Register scratch)
void Drop(Register count, Condition cond=al)
void CallCodeObject(Register code_object)
void AssertUnreachable(AbortReason reason) NOOP_UNLESS_DEBUG_CODE
void RestoreFPRegs(Register location, Register scratch)
void VFPCompareAndSetFlags(const SwVfpRegister src1, const float src2, const Condition cond=al)
void PopAll(DoubleRegList registers, int stack_slot_size=kDoubleSize)
bool use_eabi_hardfloat()
void LsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, Register shift)
void VFPCompareAndLoadFlags(const DwVfpRegister src1, const DwVfpRegister src2, const Register fpscr_flags, const Condition cond=al)
void F64x2PromoteLowF32x4(QwNeonRegister dst, QwNeonRegister src)
void FloatMaxOutOfLine(DwVfpRegister result, DwVfpRegister left, DwVfpRegister right)
void VFPCompareAndSetFlags(const SwVfpRegister src1, const SwVfpRegister src2, const Condition cond=al)
void RestoreFPRegsFromHeap(Register location, Register scratch)
void AsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, Register shift)
void AsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, uint32_t shift)
void CompareTaggedRoot(Register with, RootIndex index)
MemOperand ExternalReferenceAsOperand(IsolateFieldId id)
void Move(QwNeonRegister dst, QwNeonRegister src)
void Call(Handle< Code > code, RelocInfo::Mode rmode=RelocInfo::CODE_TARGET, Condition cond=al, TargetAddressStorageMode mode=CAN_INLINE_TARGET_ADDRESS, bool check_constant_pool=true)
void StoreTaggedField(const MemOperand &dst_field_operand, const Register &value)
void EnforceStackAlignment()
void SmiTag(Register reg, SBit s=LeaveCC)
void VmovLow(Register dst, DwVfpRegister src)
void FloatMin(SwVfpRegister result, SwVfpRegister left, SwVfpRegister right, Label *out_of_line)
void PushAll(DoubleRegList registers, int stack_slot_size=kDoubleSize)
void FloatMin(DwVfpRegister result, DwVfpRegister left, DwVfpRegister right, Label *out_of_line)
void PushArray(Register array, Register size, Register scratch, PushArrayOrder order=PushArrayOrder::kNormal)
void LsrPair(Register dst_low, Register dst_high, Register src_low, Register src_high, uint32_t shift)
void Zero(const MemOperand &dest1, const MemOperand &dest2)
void MovToFloatResult(DwVfpRegister src)
void Bfc(Register dst, Register src, int lsb, int width, Condition cond=al)
void RecordWriteField(Register object, int offset, Register value, LinkRegisterStatus lr_status, SaveFPRegsMode save_fp, SmiCheck smi_check=SmiCheck::kInline)
void VFPCompareAndSetFlags(const DwVfpRegister src1, const double src2, const Condition cond=al)
void Zero(const MemOperand &dest)
void IncrementCounter(StatsCounter *counter, int value, Register scratch1, Register scratch2)
void MovToFloatParameter(DwVfpRegister src)
void Ret(Condition cond=al)
void GetLabelAddress(Register dst, Label *target)
void LslPair(Register dst_low, Register dst_high, Register src_low, Register src_high, Register shift)
void LoadGlobalProxy(Register dst)
void And(Register dst, Register src1, const Operand &src2, Condition cond=al)
void FloatMinOutOfLine(SwVfpRegister result, SwVfpRegister left, SwVfpRegister right)
void I64x2GeS(QwNeonRegister dst, QwNeonRegister src1, QwNeonRegister src2)
void Jump(Register target, Condition cond=al)
void BindExceptionHandler(Label *label)
void LoadRoot(Register destination, RootIndex index) final
void VFPCompareAndLoadFlags(const DwVfpRegister src1, const double src2, const Register fpscr_flags, const Condition cond=al)
void RecordWrite(Register object, Operand offset, Register value, LinkRegisterStatus lr_status, SaveFPRegsMode save_fp, SmiCheck smi_check=SmiCheck::kInline)
void Pop(Register src1, Register src2, Register src3, Register src4, Condition cond=al)
void PushRoot(RootIndex index)
void StoreTaggedField(const Register &value, const MemOperand &dst_field_operand)
void EnterFrame(StackFrame::Type type, bool load_constant_pool_pointer_reg=false)
void Move(Register dst, Handle< HeapObject > value)
void F64x2ConvertLowI32x4U(QwNeonRegister dst, QwNeonRegister src)
void LoadTaggedField(const Register &destination, const MemOperand &field_operand)
void CompareRange(Register value, Register scratch, unsigned lower_limit, unsigned higher_limit)
void JumpCodeObject(Register code_object, JumpMode jump_mode=JumpMode::kJump)
void DecrementCounter(StatsCounter *counter, int value, Register scratch1, Register scratch2)
void JumpIfCodeIsTurbofanned(Register code, Register scratch, Label *if_turbofanned)
void FloatMinHelper(T result, T left, T right, Label *out_of_line)
void StoreLane(NeonSize sz, NeonListOperand src_list, uint8_t lane, NeonMemOperand dst)
void CompareObjectTypeRange(Register heap_object, Register map, Register type_reg, Register scratch, InstanceType lower_limit, InstanceType higher_limit)
void Sbfx(Register dst, Register src, int lsb, int width, Condition cond=al)
void AllocateStackSpace(int bytes)
void CheckFor32DRegs(Register scratch)
void LoadTaggedRoot(Register destination, RootIndex index)
DISALLOW_IMPLICIT_CONSTRUCTORS(MacroAssembler)
void Call(Address target, RelocInfo::Mode rmode, Condition cond=al, TargetAddressStorageMode mode=CAN_INLINE_TARGET_ADDRESS, bool check_constant_pool=true)
void VmovExtended(int dst_code, const MemOperand &src)
void VFPCanonicalizeNaN(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond=al)
void SmiToInt32(Register smi)
void MovePair(Register dst0, Register src0, Register dst1, Register src1)
void VmovHigh(Register dst, DwVfpRegister src)
void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond=al)
void I64x2BitMask(Register dst, QwNeonRegister src)
void ExtractLane(SwVfpRegister dst, QwNeonRegister src, int lane)
Condition LoadFeedbackVectorFlagsAndCheckIfNeedsProcessing(Register flags, Register feedback_vector, CodeKind current_code_kind)
void CallBuiltin(Builtin builtin, Condition cond=al)
void ExtractLane(Register dst, QwNeonRegister src, NeonDataType dt, int lane)
void I64x2Abs(QwNeonRegister dst, QwNeonRegister src)
void F64x2ConvertLowI32x4S(QwNeonRegister dst, QwNeonRegister src)
void Ubfx(Register dst, Register src, int lsb, int width, Condition cond=al)
void Swap(DwVfpRegister srcdst0, DwVfpRegister srcdst1)
void TruncateDoubleToI(Isolate *isolate, Zone *zone, Register result, DwVfpRegister double_input, StubCallMode stub_mode)
void ReplaceLane(QwNeonRegister dst, QwNeonRegister src, DwVfpRegister src_lane, int lane)
void CmpTagged(const Register &r1, const Register &r2)
void Move(Register dst, const Operand &src, SBit sbit=LeaveCC, Condition cond=al)
void Check(Condition cond, AbortReason reason)
void AssertFeedbackCell(Register object, Register scratch) NOOP_UNLESS_DEBUG_CODE
void FloatMaxOutOfLine(SwVfpRegister result, SwVfpRegister left, SwVfpRegister right)
void FloatMaxHelper(T result, T left, T right, Label *out_of_line)
void ReplaceLane(QwNeonRegister dst, QwNeonRegister src, SwVfpRegister src_lane, int lane)
void AllocateStackSpace(Register bytes)
void VmovExtended(int dst_code, Register src)
void AssertZeroExtended(Register int32_register)
void FloatMinOutOfLineHelper(T result, T left, T right)
void VmovExtended(Register dst, int src_code)
void VmovLow(DwVfpRegister dst, Register src)
void VFPCompareAndLoadFlags(const SwVfpRegister src1, const SwVfpRegister src2, const Register fpscr_flags, const Condition cond=al)
void SaveFPRegs(Register location, Register scratch)
void Move(SwVfpRegister dst, SwVfpRegister src, Condition cond=al)
void ExtractLane(Register dst, DwVfpRegister src, NeonDataType dt, int lane)
void Push(Register src1, Register src2, Register src3, Register src4, Register src5, Condition cond=al)
void LslPair(Register dst_low, Register dst_high, Register src_low, Register src_high, uint32_t shift)
void Mls(Register dst, Register src1, Register src2, Register srcA, Condition cond=al)
void CompareInstanceTypeRange(Register map, Register type_reg, Register scratch, InstanceType lower_limit, InstanceType higher_limit)
void LoadIsolateField(Register dst, IsolateFieldId id)
void TryInlineTruncateDoubleToI(Register result, DwVfpRegister input, Label *done)
void VmovExtended(int dst_code, int src_code)
void Jump(Address target, RelocInfo::Mode rmode, Condition cond=al)
void Jump(Handle< Code > code, RelocInfo::Mode rmode, Condition cond=al)
void Move(Register dst, ExternalReference reference)
void SmiUntagField(Register dst, const MemOperand &src)
void PopAll(RegList registers)
void MovToFloatParameters(DwVfpRegister src1, DwVfpRegister src2)
void DecompressTagged(const Register &destination, const MemOperand &field_operand)
Condition CheckSmi(Register src)
void SmiToInt32(Register dst, Register smi)
void Swap(QwNeonRegister srcdst0, QwNeonRegister srcdst1)
MemOperand ReceiverOperand()
void FloatMax(DwVfpRegister result, DwVfpRegister left, DwVfpRegister right, Label *out_of_line)
void Swap(Register srcdst0, Register srcdst1)
void CallRuntime(Runtime::FunctionId fid, int num_arguments)
void ExtractLane(DwVfpRegister dst, QwNeonRegister src, int lane)
void FloatMax(SwVfpRegister result, SwVfpRegister left, SwVfpRegister right, Label *out_of_line)
void LoadTaggedFieldWithoutDecompressing(const Register &destination, const MemOperand &field_operand)
void TailCallBuiltin(Builtin builtin, Condition cond=al)
void CheckPageFlag(Register object, Register scratch, int mask, Condition cc, Label *condition_met)
constexpr int8_t code() const
#define NOOP_UNLESS_DEBUG_CODE
#define ASM_CODE_COMMENT(asm)
DirectHandle< Object > new_target
ZoneVector< RpoNumber > & result
RegListBase< RegisterT > registers
InstructionOperand destination
constexpr Register no_reg
MemOperand ExitFrameCallerStackSlotOperand(int index)
constexpr BlockAddrMode ia_w
constexpr AddrMode NegPreIndex
constexpr int kPointerSize
constexpr BlockAddrMode db_w
MemOperand FieldMemOperand(Register object, int offset)
constexpr int kSystemPointerSize
@ CAN_INLINE_TARGET_ADDRESS
@ NEVER_INLINE_TARGET_ADDRESS
V8_EXPORT_PRIVATE bool AreAliased(const CPURegister ®1, const CPURegister ®2, const CPURegister ®3=NoReg, const CPURegister ®4=NoReg, const CPURegister ®5=NoReg, const CPURegister ®6=NoReg, const CPURegister ®7=NoReg, const CPURegister ®8=NoReg)
Tagged< ClearedWeakValue > ClearedValue(PtrComprCageBase cage_base)
V8_EXPORT_PRIVATE FlagValues v8_flags
constexpr AddrMode PostIndex
void CallApiFunctionAndReturn(MacroAssembler *masm, bool with_profiling, Register function_address, ExternalReference thunk_ref, Register thunk_arg, int slots_to_drop_on_return, MemOperand *argc_operand, MemOperand return_value_operand)
Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2=no_reg, Register reg3=no_reg, Register reg4=no_reg, Register reg5=no_reg, Register reg6=no_reg)
MemOperand ExitFrameStackSlotOperand(int offset)
#define DCHECK_GE(v1, v2)
#define DCHECK(condition)
#define V8_EXPORT_PRIVATE
VfpRegList scratch_v_reglist
std::optional< UseScratchRegisterScope > temps