5 #ifndef INCLUDED_FROM_MACRO_ASSEMBLER_H 6 #error This header must be included via macro-assembler.h 9 #ifndef V8_MIPS64_MACRO_ASSEMBLER_MIPS64_H_ 10 #define V8_MIPS64_MACRO_ASSEMBLER_MIPS64_H_ 12 #include "src/assembler.h" 13 #include "src/globals.h" 14 #include "src/mips64/assembler-mips64.h" 20 constexpr Register kReturnRegister0 = v0;
21 constexpr Register kReturnRegister1 = v1;
22 constexpr Register kReturnRegister2 = a0;
23 constexpr Register kJSFunctionRegister = a1;
24 constexpr Register kContextRegister = s7;
25 constexpr Register kAllocateSizeRegister = a0;
26 constexpr Register kSpeculationPoisonRegister = a7;
27 constexpr Register kInterpreterAccumulatorRegister = v0;
28 constexpr Register kInterpreterBytecodeOffsetRegister = t0;
29 constexpr Register kInterpreterBytecodeArrayRegister = t1;
30 constexpr Register kInterpreterDispatchTableRegister = t2;
32 constexpr Register kJavaScriptCallArgCountRegister = a0;
33 constexpr Register kJavaScriptCallCodeStartRegister = a2;
34 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
35 constexpr Register kJavaScriptCallNewTargetRegister = a3;
36 constexpr Register kJavaScriptCallExtraArg1Register = a2;
38 constexpr Register kOffHeapTrampolineRegister = at;
39 constexpr Register kRuntimeCallFunctionRegister = a1;
40 constexpr Register kRuntimeCallArgCountRegister = a0;
41 constexpr Register kRuntimeCallArgvRegister = a2;
42 constexpr Register kWasmInstanceRegister = a0;
43 constexpr Register kWasmCompileLazyFuncIndexRegister = t0;
46 enum class AbortReason : uint8_t;
62 enum LeaveExitFrameMode {
64 NO_EMIT_RETURN =
false 68 enum BranchDelaySlot {
91 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
92 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
93 enum RAStatus { kRAHasNotBeenSaved, kRAHasBeenSaved };
95 Register GetRegisterThatIsNotOneOf(Register reg1,
96 Register reg2 = no_reg,
97 Register reg3 = no_reg,
98 Register reg4 = no_reg,
99 Register reg5 = no_reg,
100 Register reg6 = no_reg);
105 #if defined(V8_TARGET_LITTLE_ENDIAN) 106 #define SmiWordOffset(offset) (offset + kPointerSize / 2) 108 #define SmiWordOffset(offset) offset 112 inline MemOperand ContextMemOperand(Register context,
int index) {
113 return MemOperand(context, Context::SlotOffset(index));
117 inline MemOperand NativeContextMemOperand() {
118 return ContextMemOperand(cp, Context::NATIVE_CONTEXT_INDEX);
123 inline MemOperand FieldMemOperand(Register
object,
int offset) {
124 return MemOperand(
object, offset - kHeapObjectTag);
133 inline MemOperand CFunctionArgumentOperand(
int index) {
134 DCHECK_GT(index, kCArgSlotCount);
136 int offset = (index - 5) * kPointerSize + kCArgsSlotsSize;
137 return MemOperand(sp, offset);
140 class V8_EXPORT_PRIVATE TurboAssembler :
public TurboAssemblerBase {
142 TurboAssembler(
const AssemblerOptions& options,
void* buffer,
int buffer_size)
143 : TurboAssemblerBase(options, buffer, buffer_size) {}
145 TurboAssembler(Isolate* isolate,
const AssemblerOptions& options,
146 void* buffer,
int buffer_size,
147 CodeObjectRequired create_code_object)
148 : TurboAssemblerBase(isolate, options, buffer, buffer_size,
149 create_code_object) {}
152 void EnterFrame(StackFrame::Type type);
153 void EnterFrame(StackFrame::Type type,
bool load_constant_pool_pointer_reg) {
157 void LeaveFrame(StackFrame::Type type);
160 void StubPrologue(StackFrame::Type type);
163 void InitializeRootRegister() {
164 ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
165 li(kRootRegister, Operand(isolate_root));
173 void jmp(Label* L) { Branch(L); }
180 void Assert(Condition cc, AbortReason reason, Register rs, Operand rt);
183 void Check(Condition cc, AbortReason reason, Register rs, Operand rt);
186 void Abort(AbortReason msg);
188 inline bool AllowThisStubCall(CodeStub* stub);
191 #define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2 192 #define COND_ARGS cond, r1, r2 195 #define DECLARE_NORELOC_PROTOTYPE(Name, target_type) \ 196 void Name(target_type target, BranchDelaySlot bd = PROTECT); \ 197 inline void Name(BranchDelaySlot bd, target_type target) { \ 200 void Name(target_type target, \ 202 BranchDelaySlot bd = PROTECT); \ 203 inline void Name(BranchDelaySlot bd, \ 204 target_type target, \ 206 Name(target, COND_ARGS, bd); \ 209 #define DECLARE_BRANCH_PROTOTYPES(Name) \ 210 DECLARE_NORELOC_PROTOTYPE(Name, Label*) \ 211 DECLARE_NORELOC_PROTOTYPE(Name, int32_t) 213 DECLARE_BRANCH_PROTOTYPES(Branch)
214 DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
215 DECLARE_BRANCH_PROTOTYPES(BranchShort)
217 #undef DECLARE_BRANCH_PROTOTYPES 218 #undef COND_TYPED_ARGS 222 void CompareF32(FPUCondition cc, FPURegister cmp1, FPURegister cmp2) {
223 CompareF(S, cc, cmp1, cmp2);
226 void CompareIsNanF32(FPURegister cmp1, FPURegister cmp2) {
227 CompareIsNanF(S, cmp1, cmp2);
230 void CompareF64(FPUCondition cc, FPURegister cmp1, FPURegister cmp2) {
231 CompareF(D, cc, cmp1, cmp2);
234 void CompareIsNanF64(FPURegister cmp1, FPURegister cmp2) {
235 CompareIsNanF(D, cmp1, cmp2);
238 void BranchTrueShortF(Label* target, BranchDelaySlot bd = PROTECT);
239 void BranchFalseShortF(Label* target, BranchDelaySlot bd = PROTECT);
241 void BranchTrueF(Label* target, BranchDelaySlot bd = PROTECT);
242 void BranchFalseF(Label* target, BranchDelaySlot bd = PROTECT);
245 void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond,
246 MSARegister wt, BranchDelaySlot bd = PROTECT);
248 void Branch(Label* L, Condition cond, Register rs, RootIndex index,
249 BranchDelaySlot bdslot = PROTECT);
251 static int InstrCountForLi64Bit(
int64_t value);
252 inline void LiLower32BitHelper(Register rd, Operand j);
253 void li_optimized(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
255 void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
256 inline void li(Register rd,
int64_t j, LiFlags mode = OPTIMIZE_SIZE) {
257 li(rd, Operand(j), mode);
262 void li(Register dst, Handle<HeapObject> value, LiFlags mode = OPTIMIZE_SIZE);
263 void li(Register dst, ExternalReference value, LiFlags mode = OPTIMIZE_SIZE);
264 void li(Register dst,
const StringConstantBase*
string,
265 LiFlags mode = OPTIMIZE_SIZE);
267 void LoadFromConstantsTable(Register destination,
268 int constant_index)
override;
269 void LoadRootRegisterOffset(Register destination, intptr_t offset)
override;
270 void LoadRootRelative(Register destination, int32_t offset)
override;
273 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \ 274 const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT 276 void Jump(Register target, COND_ARGS);
277 void Jump(intptr_t target, RelocInfo::Mode rmode, COND_ARGS);
278 void Jump(Address target, RelocInfo::Mode rmode, COND_ARGS);
279 void Jump(Handle<Code> code, RelocInfo::Mode rmode, COND_ARGS);
280 void Call(Register target, COND_ARGS);
281 void Call(Address target, RelocInfo::Mode rmode, COND_ARGS);
282 void Call(Handle<Code> code,
283 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
285 void Call(Label* target);
287 void CallForDeoptimization(Address target,
int deopt_id,
288 RelocInfo::Mode rmode) {
294 inline void Ret(BranchDelaySlot bd, Condition cond = al,
295 Register rs = zero_reg,
const Operand& rt = Operand(zero_reg)) {
296 Ret(cond, rs, rt, bd);
302 Condition cond = cc_always,
303 Register reg = no_reg,
304 const Operand& op = Operand(no_reg));
308 void DropAndRet(
int drop);
310 void DropAndRet(
int drop,
315 void Ld(Register rd,
const MemOperand& rs);
316 void Sd(Register rd,
const MemOperand& rs);
318 void push(Register src) {
319 Daddu(sp, sp, Operand(-kPointerSize));
320 Sd(src, MemOperand(sp, 0));
322 void Push(Register src) { push(src); }
323 void Push(Handle<HeapObject> handle);
327 void Push(Register src1, Register src2) {
328 Dsubu(sp, sp, Operand(2 * kPointerSize));
329 Sd(src1, MemOperand(sp, 1 * kPointerSize));
330 Sd(src2, MemOperand(sp, 0 * kPointerSize));
334 void Push(Register src1, Register src2, Register src3) {
335 Dsubu(sp, sp, Operand(3 * kPointerSize));
336 Sd(src1, MemOperand(sp, 2 * kPointerSize));
337 Sd(src2, MemOperand(sp, 1 * kPointerSize));
338 Sd(src3, MemOperand(sp, 0 * kPointerSize));
342 void Push(Register src1, Register src2, Register src3, Register src4) {
343 Dsubu(sp, sp, Operand(4 * kPointerSize));
344 Sd(src1, MemOperand(sp, 3 * kPointerSize));
345 Sd(src2, MemOperand(sp, 2 * kPointerSize));
346 Sd(src3, MemOperand(sp, 1 * kPointerSize));
347 Sd(src4, MemOperand(sp, 0 * kPointerSize));
351 void Push(Register src1, Register src2, Register src3, Register src4,
353 Dsubu(sp, sp, Operand(5 * kPointerSize));
354 Sd(src1, MemOperand(sp, 4 * kPointerSize));
355 Sd(src2, MemOperand(sp, 3 * kPointerSize));
356 Sd(src3, MemOperand(sp, 2 * kPointerSize));
357 Sd(src4, MemOperand(sp, 1 * kPointerSize));
358 Sd(src5, MemOperand(sp, 0 * kPointerSize));
361 void Push(Register src, Condition cond, Register tst1, Register tst2) {
363 Branch(3, cond, tst1, Operand(tst2));
364 Dsubu(sp, sp, Operand(kPointerSize));
365 Sd(src, MemOperand(sp, 0));
368 void SaveRegisters(RegList registers);
369 void RestoreRegisters(RegList registers);
371 void CallRecordWriteStub(Register
object, Register address,
372 RememberedSetAction remembered_set_action,
373 SaveFPRegsMode fp_mode);
374 void CallRecordWriteStub(Register
object, Register address,
375 RememberedSetAction remembered_set_action,
376 SaveFPRegsMode fp_mode, Address wasm_target);
381 void MultiPush(RegList regs);
382 void MultiPushFPU(RegList regs);
386 int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
387 Register exclusion1 = no_reg,
388 Register exclusion2 = no_reg,
389 Register exclusion3 = no_reg)
const;
393 int PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
394 Register exclusion2 = no_reg,
395 Register exclusion3 = no_reg);
398 int PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
399 Register exclusion2 = no_reg,
400 Register exclusion3 = no_reg);
402 void pop(Register dst) {
403 Ld(dst, MemOperand(sp, 0));
404 Daddu(sp, sp, Operand(kPointerSize));
406 void Pop(Register dst) { pop(dst); }
409 void Pop(Register src1, Register src2) {
410 DCHECK(src1 != src2);
411 Ld(src2, MemOperand(sp, 0 * kPointerSize));
412 Ld(src1, MemOperand(sp, 1 * kPointerSize));
413 Daddu(sp, sp, 2 * kPointerSize);
417 void Pop(Register src1, Register src2, Register src3) {
418 Ld(src3, MemOperand(sp, 0 * kPointerSize));
419 Ld(src2, MemOperand(sp, 1 * kPointerSize));
420 Ld(src1, MemOperand(sp, 2 * kPointerSize));
421 Daddu(sp, sp, 3 * kPointerSize);
424 void Pop(
uint32_t count = 1) { Daddu(sp, sp, Operand(count * kPointerSize)); }
428 void MultiPop(RegList regs);
429 void MultiPopFPU(RegList regs);
431 #define DEFINE_INSTRUCTION(instr) \ 432 void instr(Register rd, Register rs, const Operand& rt); \ 433 void instr(Register rd, Register rs, Register rt) { \ 434 instr(rd, rs, Operand(rt)); \ 436 void instr(Register rs, Register rt, int32_t j) { instr(rs, rt, Operand(j)); } 438 #define DEFINE_INSTRUCTION2(instr) \ 439 void instr(Register rs, const Operand& rt); \ 440 void instr(Register rs, Register rt) { instr(rs, Operand(rt)); } \ 441 void instr(Register rs, int32_t j) { instr(rs, Operand(j)); } 443 DEFINE_INSTRUCTION(Addu);
444 DEFINE_INSTRUCTION(Daddu);
445 DEFINE_INSTRUCTION(Div);
446 DEFINE_INSTRUCTION(Divu);
447 DEFINE_INSTRUCTION(Ddivu);
448 DEFINE_INSTRUCTION(Mod);
449 DEFINE_INSTRUCTION(Modu);
450 DEFINE_INSTRUCTION(Ddiv);
451 DEFINE_INSTRUCTION(Subu);
452 DEFINE_INSTRUCTION(Dsubu);
453 DEFINE_INSTRUCTION(Dmod);
454 DEFINE_INSTRUCTION(Dmodu);
455 DEFINE_INSTRUCTION(Mul);
456 DEFINE_INSTRUCTION(Mulh);
457 DEFINE_INSTRUCTION(Mulhu);
458 DEFINE_INSTRUCTION(Dmul);
459 DEFINE_INSTRUCTION(Dmulh);
460 DEFINE_INSTRUCTION2(Mult);
461 DEFINE_INSTRUCTION2(Dmult);
462 DEFINE_INSTRUCTION2(Multu);
463 DEFINE_INSTRUCTION2(Dmultu);
464 DEFINE_INSTRUCTION2(Div);
465 DEFINE_INSTRUCTION2(Ddiv);
466 DEFINE_INSTRUCTION2(Divu);
467 DEFINE_INSTRUCTION2(Ddivu);
469 DEFINE_INSTRUCTION(And);
470 DEFINE_INSTRUCTION(Or);
471 DEFINE_INSTRUCTION(Xor);
472 DEFINE_INSTRUCTION(Nor);
473 DEFINE_INSTRUCTION2(Neg);
475 DEFINE_INSTRUCTION(Slt);
476 DEFINE_INSTRUCTION(Sltu);
477 DEFINE_INSTRUCTION(Sle);
478 DEFINE_INSTRUCTION(Sleu);
479 DEFINE_INSTRUCTION(Sgt);
480 DEFINE_INSTRUCTION(Sgtu);
481 DEFINE_INSTRUCTION(Sge);
482 DEFINE_INSTRUCTION(Sgeu);
485 DEFINE_INSTRUCTION(Ror);
486 DEFINE_INSTRUCTION(Dror);
488 #undef DEFINE_INSTRUCTION 489 #undef DEFINE_INSTRUCTION2 490 #undef DEFINE_INSTRUCTION3 492 void SmiUntag(Register dst,
const MemOperand& src);
493 void SmiUntag(Register dst, Register src) {
494 if (SmiValuesAre32Bits()) {
495 dsra32(dst, src, kSmiShift - 32);
497 DCHECK(SmiValuesAre31Bits());
498 sra(dst, src, kSmiShift);
502 void SmiUntag(Register reg) { SmiUntag(reg, reg); }
509 void PrepareForTailCall(
const ParameterCount& callee_args_count,
510 Register caller_args_count_reg, Register scratch0,
513 int CalculateStackPassedWords(
int num_reg_arguments,
514 int num_double_arguments);
525 void PrepareCallCFunction(
int num_reg_arguments,
int num_double_registers,
527 void PrepareCallCFunction(
int num_reg_arguments, Register scratch);
538 void CallCFunction(ExternalReference
function,
int num_arguments);
539 void CallCFunction(Register
function,
int num_arguments);
540 void CallCFunction(ExternalReference
function,
int num_reg_arguments,
541 int num_double_arguments);
542 void CallCFunction(Register
function,
int num_reg_arguments,
543 int num_double_arguments);
544 void MovFromFloatResult(DoubleRegister dst);
545 void MovFromFloatParameter(DoubleRegister dst);
551 void MovToFloatParameter(DoubleRegister src);
552 void MovToFloatParameters(DoubleRegister src1, DoubleRegister src2);
553 void MovToFloatResult(DoubleRegister src);
556 inline void PrepareCEntryArgs(
int num_args) { li(a0, num_args); }
557 inline void PrepareCEntryFunction(
const ExternalReference& ref) {
561 void CheckPageFlag(Register
object, Register scratch,
int mask, Condition cc,
562 Label* condition_met);
567 void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
575 void TryInlineTruncateDoubleToI(Register result, DoubleRegister input,
581 void TruncateDoubleToI(Isolate* isolate, Zone* zone, Register result,
582 DoubleRegister double_input, StubCallMode stub_mode);
585 void Movz(Register rd, Register rs, Register rt);
586 void Movn(Register rd, Register rs, Register rt);
587 void Movt(Register rd, Register rs, uint16_t cc = 0);
588 void Movf(Register rd, Register rs, uint16_t cc = 0);
590 void LoadZeroIfFPUCondition(Register dest);
591 void LoadZeroIfNotFPUCondition(Register dest);
593 void LoadZeroIfConditionNotZero(Register dest, Register condition);
594 void LoadZeroIfConditionZero(Register dest, Register condition);
595 void LoadZeroOnCondition(Register rd, Register rs,
const Operand& rt,
598 void Clz(Register rd, Register rs);
599 void Ctz(Register rd, Register rs);
600 void Dctz(Register rd, Register rs);
601 void Popcnt(Register rd, Register rs);
602 void Dpopcnt(Register rd, Register rs);
605 void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
606 void Dext(Register rt, Register rs, uint16_t pos, uint16_t size);
607 void Ins(Register rt, Register rs, uint16_t pos, uint16_t size);
608 void Dins(Register rt, Register rs, uint16_t pos, uint16_t size);
609 void ExtractBits(Register dest, Register source, Register pos,
int size,
610 bool sign_extend =
false);
611 void InsertBits(Register dest, Register source, Register pos,
int size);
612 void Neg_s(FPURegister fd, FPURegister fs);
613 void Neg_d(FPURegister fd, FPURegister fs);
616 void Bovc(Register rt, Register rs, Label* L);
617 void Bnvc(Register rt, Register rs, Label* L);
620 void Trunc_uw_s(FPURegister fd, FPURegister fs, FPURegister scratch);
621 void Trunc_uw_s(Register rd, FPURegister fs, FPURegister scratch);
624 void ByteSwapSigned(Register dest, Register src,
int operand_size);
625 void ByteSwapUnsigned(Register dest, Register src,
int operand_size);
627 void Ulh(Register rd,
const MemOperand& rs);
628 void Ulhu(Register rd,
const MemOperand& rs);
629 void Ush(Register rd,
const MemOperand& rs, Register scratch);
631 void Ulw(Register rd,
const MemOperand& rs);
632 void Ulwu(Register rd,
const MemOperand& rs);
633 void Usw(Register rd,
const MemOperand& rs);
635 void Uld(Register rd,
const MemOperand& rs);
636 void Usd(Register rd,
const MemOperand& rs);
638 void Ulwc1(FPURegister fd,
const MemOperand& rs, Register scratch);
639 void Uswc1(FPURegister fd,
const MemOperand& rs, Register scratch);
641 void Uldc1(FPURegister fd,
const MemOperand& rs, Register scratch);
642 void Usdc1(FPURegister fd,
const MemOperand& rs, Register scratch);
644 void Lb(Register rd,
const MemOperand& rs);
645 void Lbu(Register rd,
const MemOperand& rs);
646 void Sb(Register rd,
const MemOperand& rs);
648 void Lh(Register rd,
const MemOperand& rs);
649 void Lhu(Register rd,
const MemOperand& rs);
650 void Sh(Register rd,
const MemOperand& rs);
652 void Lw(Register rd,
const MemOperand& rs);
653 void Lwu(Register rd,
const MemOperand& rs);
654 void Sw(Register rd,
const MemOperand& rs);
656 void Lwc1(FPURegister fd,
const MemOperand& src);
657 void Swc1(FPURegister fs,
const MemOperand& dst);
659 void Ldc1(FPURegister fd,
const MemOperand& src);
660 void Sdc1(FPURegister fs,
const MemOperand& dst);
662 void Ll(Register rd,
const MemOperand& rs);
663 void Sc(Register rd,
const MemOperand& rs);
665 void Lld(Register rd,
const MemOperand& rs);
666 void Scd(Register rd,
const MemOperand& rs);
676 void Float32Max(FPURegister dst, FPURegister src1, FPURegister src2,
678 void Float32Min(FPURegister dst, FPURegister src1, FPURegister src2,
680 void Float64Max(FPURegister dst, FPURegister src1, FPURegister src2,
682 void Float64Min(FPURegister dst, FPURegister src1, FPURegister src2,
686 void Float32MaxOutOfLine(FPURegister dst, FPURegister src1, FPURegister src2);
687 void Float32MinOutOfLine(FPURegister dst, FPURegister src1, FPURegister src2);
688 void Float64MaxOutOfLine(FPURegister dst, FPURegister src1, FPURegister src2);
689 void Float64MinOutOfLine(FPURegister dst, FPURegister src1, FPURegister src2);
691 bool IsDoubleZeroRegSet() {
return has_double_zero_reg_set_; }
693 void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
695 inline void Move(Register dst, Handle<HeapObject> handle) { li(dst, handle); }
696 inline void Move(Register dst, Smi smi) { li(dst, Operand(smi)); }
698 inline void Move(Register dst, Register src) {
704 inline void Move(FPURegister dst, FPURegister src) { Move_d(dst, src); }
706 inline void Move(Register dst_low, Register dst_high, FPURegister src) {
708 mfhc1(dst_high, src);
711 inline void Move(Register dst, FPURegister src) { dmfc1(dst, src); }
713 inline void Move(FPURegister dst, Register src) { dmtc1(src, dst); }
715 inline void FmoveHigh(Register dst_high, FPURegister src) {
716 mfhc1(dst_high, src);
719 inline void FmoveHigh(FPURegister dst, Register src_high) {
720 mthc1(src_high, dst);
723 inline void FmoveLow(Register dst_low, FPURegister src) {
727 void FmoveLow(FPURegister dst, Register src_low);
729 inline void Move(FPURegister dst, Register src_low, Register src_high) {
731 mthc1(src_high, dst);
734 inline void Move_d(FPURegister dst, FPURegister src) {
740 inline void Move_s(FPURegister dst, FPURegister src) {
746 void Move(FPURegister dst,
float imm) { Move(dst, bit_cast<uint32_t>(imm)); }
747 void Move(FPURegister dst,
double imm) { Move(dst, bit_cast<uint64_t>(imm)); }
748 void Move(FPURegister dst,
uint32_t src);
749 void Move(FPURegister dst, uint64_t src);
753 void DaddOverflow(Register dst, Register left,
const Operand& right,
757 void DsubOverflow(Register dst, Register left,
const Operand& right,
760 void MulOverflow(Register dst, Register left,
const Operand& right,
764 #ifdef _MIPS_ARCH_MIPS64R6 765 static const int kSwitchTablePrologueSize = 6;
767 static const int kSwitchTablePrologueSize = 11;
772 template <
typename Func>
773 void GenerateSwitchTable(Register index,
size_t case_count,
774 Func GetLabelFunction);
777 void LoadRoot(Register destination, RootIndex index)
override;
778 void LoadRoot(Register destination, RootIndex index, Condition cond,
779 Register src1,
const Operand& src2);
782 void FPUCanonicalizeNaN(
const DoubleRegister dst,
const DoubleRegister src);
788 void Cvt_d_uw(FPURegister fd, FPURegister fs);
789 void Cvt_d_uw(FPURegister fd, Register rs);
792 void Cvt_d_ul(FPURegister fd, FPURegister fs);
793 void Cvt_d_ul(FPURegister fd, Register rs);
796 void Cvt_s_uw(FPURegister fd, FPURegister fs);
797 void Cvt_s_uw(FPURegister fd, Register rs);
800 void Cvt_s_ul(FPURegister fd, FPURegister fs);
801 void Cvt_s_ul(FPURegister fd, Register rs);
804 void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch);
805 void Trunc_uw_d(Register rd, FPURegister fs, FPURegister scratch);
808 void Trunc_ul_d(FPURegister fd, FPURegister fs, FPURegister scratch,
809 Register result = no_reg);
810 void Trunc_ul_d(Register rd, FPURegister fs, FPURegister scratch,
811 Register result = no_reg);
814 void Trunc_ul_s(FPURegister fd, FPURegister fs, FPURegister scratch,
815 Register result = no_reg);
816 void Trunc_ul_s(Register rd, FPURegister fs, FPURegister scratch,
817 Register result = no_reg);
820 void Trunc_d_d(FPURegister fd, FPURegister fs);
821 void Round_d_d(FPURegister fd, FPURegister fs);
822 void Floor_d_d(FPURegister fd, FPURegister fs);
823 void Ceil_d_d(FPURegister fd, FPURegister fs);
826 void Trunc_s_s(FPURegister fd, FPURegister fs);
827 void Round_s_s(FPURegister fd, FPURegister fs);
828 void Floor_s_s(FPURegister fd, FPURegister fs);
829 void Ceil_s_s(FPURegister fd, FPURegister fs);
832 void JumpIfSmi(Register value, Label* smi_label, Register scratch = at,
833 BranchDelaySlot bd = PROTECT);
835 void JumpIfEqual(Register a, int32_t b, Label* dest) {
836 li(kScratchReg, Operand(b));
837 Branch(dest, eq, a, Operand(kScratchReg));
840 void JumpIfLessThan(Register a, int32_t b, Label* dest) {
841 li(kScratchReg, Operand(b));
842 Branch(dest, lt, a, Operand(kScratchReg));
846 void PushStandardFrame(Register function_reg);
849 static int ActivationFrameAlignment();
854 void Lsa(Register rd, Register rs, Register rt, uint8_t sa,
855 Register scratch = at);
856 void Dlsa(Register rd, Register rs, Register rt, uint8_t sa,
857 Register scratch = at);
861 void ComputeCodeStartAddress(Register dst);
863 void ResetSpeculationPoisonRegister();
866 inline Register GetRtAsRegisterHelper(
const Operand& rt, Register scratch);
867 inline int32_t GetOffset(int32_t offset, Label* L, OffsetSize bits);
870 bool has_double_zero_reg_set_ =
false;
872 void CompareF(SecondaryField sizeField, FPUCondition cc, FPURegister cmp1,
875 void CompareIsNanF(SecondaryField sizeField, FPURegister cmp1,
878 void BranchShortMSA(MSABranchDF df, Label* target, MSABranchCondition cond,
879 MSARegister wt, BranchDelaySlot bd = PROTECT);
881 void CallCFunctionHelper(Register
function,
int num_reg_arguments,
882 int num_double_arguments);
884 bool CalculateOffset(Label* L, int32_t& offset, OffsetSize bits);
885 bool CalculateOffset(Label* L, int32_t& offset, OffsetSize bits,
886 Register& scratch,
const Operand& rt);
888 void BranchShortHelperR6(int32_t offset, Label* L);
889 void BranchShortHelper(int16_t offset, Label* L, BranchDelaySlot bdslot);
890 bool BranchShortHelperR6(int32_t offset, Label* L, Condition cond,
891 Register rs,
const Operand& rt);
892 bool BranchShortHelper(int16_t offset, Label* L, Condition cond, Register rs,
893 const Operand& rt, BranchDelaySlot bdslot);
894 bool BranchShortCheck(int32_t offset, Label* L, Condition cond, Register rs,
895 const Operand& rt, BranchDelaySlot bdslot);
897 void BranchAndLinkShortHelperR6(int32_t offset, Label* L);
898 void BranchAndLinkShortHelper(int16_t offset, Label* L,
899 BranchDelaySlot bdslot);
900 void BranchAndLinkShort(int32_t offset, BranchDelaySlot bdslot = PROTECT);
901 void BranchAndLinkShort(Label* L, BranchDelaySlot bdslot = PROTECT);
902 bool BranchAndLinkShortHelperR6(int32_t offset, Label* L, Condition cond,
903 Register rs,
const Operand& rt);
904 bool BranchAndLinkShortHelper(int16_t offset, Label* L, Condition cond,
905 Register rs,
const Operand& rt,
906 BranchDelaySlot bdslot);
907 bool BranchAndLinkShortCheck(int32_t offset, Label* L, Condition cond,
908 Register rs,
const Operand& rt,
909 BranchDelaySlot bdslot);
910 void BranchLong(Label* L, BranchDelaySlot bdslot);
911 void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot);
913 template <
typename RoundFunc>
914 void RoundDouble(FPURegister dst, FPURegister src, FPURoundingMode mode,
917 template <
typename RoundFunc>
918 void RoundFloat(FPURegister dst, FPURegister src, FPURoundingMode mode,
922 void PushCommonFrame(Register marker_reg = no_reg);
924 void CallRecordWriteStub(Register
object, Register address,
925 RememberedSetAction remembered_set_action,
926 SaveFPRegsMode fp_mode, Handle<Code> code_target,
927 Address wasm_target);
931 class MacroAssembler :
public TurboAssembler {
933 MacroAssembler(
const AssemblerOptions& options,
void* buffer,
int size)
934 : TurboAssembler(options, buffer, size) {}
936 MacroAssembler(Isolate* isolate,
void* buffer,
int size,
937 CodeObjectRequired create_code_object)
938 : MacroAssembler(isolate, AssemblerOptions::Default(isolate), buffer,
939 size, create_code_object) {}
941 MacroAssembler(Isolate* isolate,
const AssemblerOptions& options,
942 void* buffer,
int size, CodeObjectRequired create_code_object);
944 bool IsNear(Label* L, Condition cond,
int rs_reg);
948 void Swap(Register reg1, Register reg2, Register scratch = no_reg);
950 void PushRoot(RootIndex index) {
951 UseScratchRegisterScope temps(
this);
952 Register scratch = temps.Acquire();
953 LoadRoot(scratch, index);
958 void JumpIfRoot(Register with, RootIndex index, Label* if_equal) {
959 UseScratchRegisterScope temps(
this);
960 Register scratch = temps.Acquire();
961 LoadRoot(scratch, index);
962 Branch(if_equal, eq, with, Operand(scratch));
966 void JumpIfNotRoot(Register with, RootIndex index, Label* if_not_equal) {
967 UseScratchRegisterScope temps(
this);
968 Register scratch = temps.Acquire();
969 LoadRoot(scratch, index);
970 Branch(if_not_equal, ne, with, Operand(scratch));
981 void RecordWriteField(
982 Register
object,
int offset, Register value, Register scratch,
983 RAStatus ra_status, SaveFPRegsMode save_fp,
984 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
985 SmiCheck smi_check = INLINE_SMI_CHECK);
991 Register
object, Register address, Register value, RAStatus ra_status,
992 SaveFPRegsMode save_fp,
993 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
994 SmiCheck smi_check = INLINE_SMI_CHECK);
996 void Pref(int32_t hint,
const MemOperand& rs);
1001 void LoadWordPair(Register rd,
const MemOperand& rs, Register scratch = at);
1002 void StoreWordPair(Register rd,
const MemOperand& rs, Register scratch = at);
1006 void PushSafepointRegisters();
1007 void PopSafepointRegisters();
1010 void Trunc_l_ud(FPURegister fd, FPURegister fs, FPURegister scratch);
1012 void Trunc_l_d(FPURegister fd, FPURegister fs);
1013 void Round_l_d(FPURegister fd, FPURegister fs);
1014 void Floor_l_d(FPURegister fd, FPURegister fs);
1015 void Ceil_l_d(FPURegister fd, FPURegister fs);
1017 void Trunc_w_d(FPURegister fd, FPURegister fs);
1018 void Round_w_d(FPURegister fd, FPURegister fs);
1019 void Floor_w_d(FPURegister fd, FPURegister fs);
1020 void Ceil_w_d(FPURegister fd, FPURegister fs);
1022 void Madd_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
1023 FPURegister scratch);
1024 void Madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
1025 FPURegister scratch);
1026 void Msub_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
1027 FPURegister scratch);
1028 void Msub_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
1029 FPURegister scratch);
1031 void BranchShortMSA(MSABranchDF df, Label* target, MSABranchCondition cond,
1032 MSARegister wt, BranchDelaySlot bd = PROTECT);
1039 void EmitFPUTruncate(
1040 FPURoundingMode rounding_mode, Register result,
1041 DoubleRegister double_input, Register scratch,
1042 DoubleRegister double_scratch, Register except_flag,
1043 CheckForInexactConversion check_inexact = kDontCheckForInexactConversion);
1049 void EnterExitFrame(
bool save_doubles,
int stack_space = 0,
1050 StackFrame::Type frame_type = StackFrame::EXIT);
1053 void LeaveExitFrame(
bool save_doubles, Register arg_count,
1054 bool do_return = NO_EMIT_RETURN,
1055 bool argument_count_is_length =
false);
1058 void AssertStackIsAligned();
1061 void LoadGlobalProxy(Register dst) {
1062 LoadNativeContextSlot(Context::GLOBAL_PROXY_INDEX, dst);
1065 void LoadNativeContextSlot(
int index, Register dst);
1069 void LoadGlobalFunctionInitialMap(Register
function,
1077 void InvokeFunctionCode(Register
function, Register new_target,
1078 const ParameterCount& expected,
1079 const ParameterCount& actual, InvokeFlag flag);
1082 void CheckDebugHook(Register fun, Register new_target,
1083 const ParameterCount& expected,
1084 const ParameterCount& actual);
1088 void InvokeFunction(Register
function, Register new_target,
1089 const ParameterCount& actual, InvokeFlag flag);
1091 void InvokeFunction(Register
function,
const ParameterCount& expected,
1092 const ParameterCount& actual, InvokeFlag flag);
1095 void MaybeDropFrames();
1100 void PushStackHandler();
1104 void PopStackHandler();
1109 void GetObjectType(Register
function,
1116 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \ 1117 const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT 1120 void CallStub(CodeStub* stub, COND_ARGS);
1123 void TailCallStub(CodeStub* stub, COND_ARGS);
1128 void CallRuntime(
const Runtime::Function* f,
int num_arguments,
1129 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
1132 void CallRuntime(Runtime::FunctionId fid,
1133 SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1134 const Runtime::Function*
function = Runtime::FunctionForId(fid);
1135 CallRuntime(
function, function->nargs, save_doubles);
1139 void CallRuntime(Runtime::FunctionId fid,
int num_arguments,
1140 SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1141 CallRuntime(Runtime::FunctionForId(fid), num_arguments, save_doubles);
1145 void TailCallRuntime(Runtime::FunctionId fid);
1148 void JumpToExternalReference(
const ExternalReference& builtin,
1149 BranchDelaySlot bd = PROTECT,
1150 bool builtin_exit_frame =
false);
1153 void JumpToInstructionStream(Address entry);
1157 void LoadWeakValue(Register out, Register in, Label* target_if_cleared);
1162 void IncrementCounter(StatsCounter* counter,
int value,
1163 Register scratch1, Register scratch2);
1164 void DecrementCounter(StatsCounter* counter,
int value,
1165 Register scratch1, Register scratch2);
1170 void SmiTag(Register dst, Register src) {
1171 STATIC_ASSERT(kSmiTag == 0);
1172 if (SmiValuesAre32Bits()) {
1173 dsll32(dst, src, 0);
1175 DCHECK(SmiValuesAre31Bits());
1176 Addu(dst, src, src);
1180 void SmiTag(Register reg) {
1185 void SmiScale(Register dst, Register src,
int scale) {
1186 if (SmiValuesAre32Bits()) {
1188 dsra(dst, src, kSmiShift - scale);
1190 DCHECK(SmiValuesAre31Bits());
1191 DCHECK_GE(scale, kSmiTagSize);
1192 sll(dst, src, scale - kSmiTagSize);
1197 inline void SmiTst(Register value, Register scratch) {
1198 And(scratch, value, Operand(kSmiTagMask));
1202 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1205 void JumpIfNotSmi(Register value,
1206 Label* not_smi_label,
1207 Register scratch = at,
1208 BranchDelaySlot bd = PROTECT);
1211 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
1214 void AssertNotSmi(Register
object);
1215 void AssertSmi(Register
object);
1218 void AssertConstructor(Register
object);
1221 void AssertFunction(Register
object);
1225 void AssertBoundFunction(Register
object);
1229 void AssertGeneratorObject(Register
object);
1233 void AssertUndefinedOrAllocationSite(Register
object, Register scratch);
1235 template<
typename Field>
1236 void DecodeField(Register dst, Register src) {
1237 Ext(dst, src, Field::kShift, Field::kSize);
1240 template<
typename Field>
1241 void DecodeField(Register reg) {
1242 DecodeField<Field>(reg, reg);
1247 void InvokePrologue(
const ParameterCount& expected,
1248 const ParameterCount& actual, Label* done,
1249 bool* definitely_mismatches, InvokeFlag flag);
1252 static int SafepointRegisterStackIndex(
int reg_code);
1256 friend class StandardFrame;
1259 template <
typename Func>
1260 void TurboAssembler::GenerateSwitchTable(Register index,
size_t case_count,
1261 Func GetLabelFunction) {
1264 BlockTrampolinePoolFor(static_cast<int>(case_count) * 2 +
1265 kSwitchTablePrologueSize);
1266 UseScratchRegisterScope temps(
this);
1267 Register scratch = temps.Acquire();
1268 if (kArchVariant >= kMips64r6) {
1270 if ((pc_offset() & 7) == 0) {
1273 addiupc(scratch, 5);
1274 Dlsa(scratch, scratch, index, kPointerSizeLog2);
1275 Ld(scratch, MemOperand(scratch));
1281 dsll(scratch, index, kPointerSizeLog2);
1283 daddu(scratch, scratch, ra);
1285 Ld(scratch, MemOperand(scratch, 6 * v8::internal::kInstrSize));
1289 for (
size_t index = 0; index < case_count; ++index) {
1290 dd(GetLabelFunction(index));
1294 #define ACCESS_MASM(masm) masm-> 1299 #endif // V8_MIPS64_MACRO_ASSEMBLER_MIPS64_H_