5 #ifndef INCLUDED_FROM_MACRO_ASSEMBLER_H 6 #error This header must be included via macro-assembler.h 9 #ifndef V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 10 #define V8_MIPS_MACRO_ASSEMBLER_MIPS_H_ 12 #include "src/assembler.h" 13 #include "src/contexts.h" 14 #include "src/globals.h" 15 #include "src/mips/assembler-mips.h" 21 constexpr Register kReturnRegister0 = v0;
22 constexpr Register kReturnRegister1 = v1;
23 constexpr Register kReturnRegister2 = a0;
24 constexpr Register kJSFunctionRegister = a1;
25 constexpr Register kContextRegister = s7;
26 constexpr Register kAllocateSizeRegister = a0;
27 constexpr Register kSpeculationPoisonRegister = t3;
28 constexpr Register kInterpreterAccumulatorRegister = v0;
29 constexpr Register kInterpreterBytecodeOffsetRegister = t4;
30 constexpr Register kInterpreterBytecodeArrayRegister = t5;
31 constexpr Register kInterpreterDispatchTableRegister = t6;
33 constexpr Register kJavaScriptCallArgCountRegister = a0;
34 constexpr Register kJavaScriptCallCodeStartRegister = a2;
35 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
36 constexpr Register kJavaScriptCallNewTargetRegister = a3;
37 constexpr Register kJavaScriptCallExtraArg1Register = a2;
39 constexpr Register kOffHeapTrampolineRegister = at;
40 constexpr Register kRuntimeCallFunctionRegister = a1;
41 constexpr Register kRuntimeCallArgCountRegister = a0;
42 constexpr Register kRuntimeCallArgvRegister = a2;
43 constexpr Register kWasmInstanceRegister = a0;
44 constexpr Register kWasmCompileLazyFuncIndexRegister = t0;
47 enum class AbortReason : uint8_t;
63 enum LeaveExitFrameMode {
65 NO_EMIT_RETURN =
false 79 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
80 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
81 enum RAStatus { kRAHasNotBeenSaved, kRAHasBeenSaved };
83 Register GetRegisterThatIsNotOneOf(Register reg1,
84 Register reg2 = no_reg,
85 Register reg3 = no_reg,
86 Register reg4 = no_reg,
87 Register reg5 = no_reg,
88 Register reg6 = no_reg);
93 inline MemOperand ContextMemOperand(Register context,
int index) {
94 return MemOperand(context, Context::SlotOffset(index));
98 inline MemOperand NativeContextMemOperand() {
99 return ContextMemOperand(cp, Context::NATIVE_CONTEXT_INDEX);
104 inline MemOperand FieldMemOperand(Register
object,
int offset) {
105 return MemOperand(
object, offset - kHeapObjectTag);
111 inline MemOperand CFunctionArgumentOperand(
int index) {
112 DCHECK_GT(index, kCArgSlotCount);
114 int offset = (index - 5) * kPointerSize + kCArgsSlotsSize;
115 return MemOperand(sp, offset);
118 class V8_EXPORT_PRIVATE TurboAssembler :
public TurboAssemblerBase {
120 TurboAssembler(
const AssemblerOptions& options,
void* buffer,
int buffer_size)
121 : TurboAssemblerBase(options, buffer, buffer_size) {}
123 TurboAssembler(Isolate* isolate,
const AssemblerOptions& options,
124 void* buffer,
int buffer_size,
125 CodeObjectRequired create_code_object)
126 : TurboAssemblerBase(isolate, options, buffer, buffer_size,
127 create_code_object) {}
130 void EnterFrame(StackFrame::Type type);
131 void EnterFrame(StackFrame::Type type,
bool load_constant_pool_pointer_reg) {
135 void LeaveFrame(StackFrame::Type type);
138 void StubPrologue(StackFrame::Type type);
141 void InitializeRootRegister() {
142 ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
143 li(kRootRegister, Operand(isolate_root));
151 void jmp(Label* L) { Branch(L); }
158 void Assert(Condition cc, AbortReason reason, Register rs, Operand rt);
161 void Check(Condition cc, AbortReason reason, Register rs, Operand rt);
164 void Abort(AbortReason msg);
166 inline bool AllowThisStubCall(CodeStub* stub);
169 #define COND_TYPED_ARGS Condition cond, Register r1, const Operand& r2 170 #define COND_ARGS cond, r1, r2 173 #define DECLARE_NORELOC_PROTOTYPE(Name, target_type) \ 174 void Name(target_type target, BranchDelaySlot bd = PROTECT); \ 175 inline void Name(BranchDelaySlot bd, target_type target) { \ 178 void Name(target_type target, \ 180 BranchDelaySlot bd = PROTECT); \ 181 inline void Name(BranchDelaySlot bd, \ 182 target_type target, \ 184 Name(target, COND_ARGS, bd); \ 187 #define DECLARE_BRANCH_PROTOTYPES(Name) \ 188 DECLARE_NORELOC_PROTOTYPE(Name, Label*) \ 189 DECLARE_NORELOC_PROTOTYPE(Name, int32_t) 191 DECLARE_BRANCH_PROTOTYPES(Branch)
192 DECLARE_BRANCH_PROTOTYPES(BranchAndLink)
193 DECLARE_BRANCH_PROTOTYPES(BranchShort)
195 #undef DECLARE_BRANCH_PROTOTYPES 196 #undef COND_TYPED_ARGS 200 void CompareF32(FPUCondition cc, FPURegister cmp1, FPURegister cmp2) {
201 CompareF(S, cc, cmp1, cmp2);
204 void CompareIsNanF32(FPURegister cmp1, FPURegister cmp2) {
205 CompareIsNanF(S, cmp1, cmp2);
208 void CompareF64(FPUCondition cc, FPURegister cmp1, FPURegister cmp2) {
209 CompareF(D, cc, cmp1, cmp2);
212 void CompareIsNanF64(FPURegister cmp1, FPURegister cmp2) {
213 CompareIsNanF(D, cmp1, cmp2);
216 void BranchTrueShortF(Label* target, BranchDelaySlot bd = PROTECT);
217 void BranchFalseShortF(Label* target, BranchDelaySlot bd = PROTECT);
219 void BranchTrueF(Label* target, BranchDelaySlot bd = PROTECT);
220 void BranchFalseF(Label* target, BranchDelaySlot bd = PROTECT);
223 void BranchMSA(Label* target, MSABranchDF df, MSABranchCondition cond,
224 MSARegister wt, BranchDelaySlot bd = PROTECT);
226 void Branch(Label* L, Condition cond, Register rs, RootIndex index,
227 BranchDelaySlot bdslot = PROTECT);
230 void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
231 inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) {
232 li(rd, Operand(j), mode);
234 void li(Register dst, Handle<HeapObject> value, LiFlags mode = OPTIMIZE_SIZE);
235 void li(Register dst, ExternalReference value, LiFlags mode = OPTIMIZE_SIZE);
236 void li(Register dst,
const StringConstantBase*
string,
237 LiFlags mode = OPTIMIZE_SIZE);
239 void LoadFromConstantsTable(Register destination,
240 int constant_index)
override;
241 void LoadRootRegisterOffset(Register destination, intptr_t offset)
override;
242 void LoadRootRelative(Register destination, int32_t offset)
override;
245 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \ 246 const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT 248 void Jump(Register target, int16_t offset = 0, COND_ARGS);
249 void Jump(Register target, Register base, int16_t offset = 0, COND_ARGS);
250 void Jump(Register target,
const Operand& offset, COND_ARGS);
251 void Jump(intptr_t target, RelocInfo::Mode rmode, COND_ARGS);
252 void Jump(Address target, RelocInfo::Mode rmode, COND_ARGS);
253 void Jump(Handle<Code> code, RelocInfo::Mode rmode, COND_ARGS);
254 void Call(Register target, int16_t offset = 0, COND_ARGS);
255 void Call(Register target, Register base, int16_t offset = 0, COND_ARGS);
256 void Call(Address target, RelocInfo::Mode rmode, COND_ARGS);
257 void Call(Handle<Code> code,
258 RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
260 void Call(Label* target);
262 void CallForDeoptimization(Address target,
int deopt_id,
263 RelocInfo::Mode rmode) {
269 inline void Ret(BranchDelaySlot bd, Condition cond = al,
270 Register rs = zero_reg,
const Operand& rt = Operand(zero_reg)) {
271 Ret(cond, rs, rt, bd);
277 Condition cond = cc_always,
278 Register reg = no_reg,
279 const Operand& op = Operand(no_reg));
283 void DropAndRet(
int drop);
285 void DropAndRet(
int drop,
290 void push(Register src) {
291 Addu(sp, sp, Operand(-kPointerSize));
292 sw(src, MemOperand(sp, 0));
295 void Push(Register src) { push(src); }
296 void Push(Handle<HeapObject> handle);
300 void Push(Register src1, Register src2) {
301 Subu(sp, sp, Operand(2 * kPointerSize));
302 sw(src1, MemOperand(sp, 1 * kPointerSize));
303 sw(src2, MemOperand(sp, 0 * kPointerSize));
307 void Push(Register src1, Register src2, Register src3) {
308 Subu(sp, sp, Operand(3 * kPointerSize));
309 sw(src1, MemOperand(sp, 2 * kPointerSize));
310 sw(src2, MemOperand(sp, 1 * kPointerSize));
311 sw(src3, MemOperand(sp, 0 * kPointerSize));
315 void Push(Register src1, Register src2, Register src3, Register src4) {
316 Subu(sp, sp, Operand(4 * kPointerSize));
317 sw(src1, MemOperand(sp, 3 * kPointerSize));
318 sw(src2, MemOperand(sp, 2 * kPointerSize));
319 sw(src3, MemOperand(sp, 1 * kPointerSize));
320 sw(src4, MemOperand(sp, 0 * kPointerSize));
324 void Push(Register src1, Register src2, Register src3, Register src4,
326 Subu(sp, sp, Operand(5 * kPointerSize));
327 sw(src1, MemOperand(sp, 4 * kPointerSize));
328 sw(src2, MemOperand(sp, 3 * kPointerSize));
329 sw(src3, MemOperand(sp, 2 * kPointerSize));
330 sw(src4, MemOperand(sp, 1 * kPointerSize));
331 sw(src5, MemOperand(sp, 0 * kPointerSize));
334 void Push(Register src, Condition cond, Register tst1, Register tst2) {
336 Branch(3, cond, tst1, Operand(tst2));
337 Subu(sp, sp, Operand(kPointerSize));
338 sw(src, MemOperand(sp, 0));
341 void SaveRegisters(RegList registers);
342 void RestoreRegisters(RegList registers);
344 void CallRecordWriteStub(Register
object, Register address,
345 RememberedSetAction remembered_set_action,
346 SaveFPRegsMode fp_mode);
347 void CallRecordWriteStub(Register
object, Register address,
348 RememberedSetAction remembered_set_action,
349 SaveFPRegsMode fp_mode, Address wasm_target);
354 void MultiPush(RegList regs);
355 void MultiPushFPU(RegList regs);
359 int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
360 Register exclusion1 = no_reg,
361 Register exclusion2 = no_reg,
362 Register exclusion3 = no_reg)
const;
366 int PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
367 Register exclusion2 = no_reg,
368 Register exclusion3 = no_reg);
371 int PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
372 Register exclusion2 = no_reg,
373 Register exclusion3 = no_reg);
375 void pop(Register dst) {
376 lw(dst, MemOperand(sp, 0));
377 Addu(sp, sp, Operand(kPointerSize));
380 void Pop(Register dst) { pop(dst); }
383 void Pop(Register src1, Register src2) {
384 DCHECK(src1 != src2);
385 lw(src2, MemOperand(sp, 0 * kPointerSize));
386 lw(src1, MemOperand(sp, 1 * kPointerSize));
387 Addu(sp, sp, 2 * kPointerSize);
391 void Pop(Register src1, Register src2, Register src3) {
392 lw(src3, MemOperand(sp, 0 * kPointerSize));
393 lw(src2, MemOperand(sp, 1 * kPointerSize));
394 lw(src1, MemOperand(sp, 2 * kPointerSize));
395 Addu(sp, sp, 3 * kPointerSize);
398 void Pop(
uint32_t count = 1) { Addu(sp, sp, Operand(count * kPointerSize)); }
402 void MultiPop(RegList regs);
403 void MultiPopFPU(RegList regs);
408 void Lsa(Register rd, Register rs, Register rt, uint8_t sa,
409 Register scratch = at);
411 #define DEFINE_INSTRUCTION(instr) \ 412 void instr(Register rd, Register rs, const Operand& rt); \ 413 void instr(Register rd, Register rs, Register rt) { \ 414 instr(rd, rs, Operand(rt)); \ 416 void instr(Register rs, Register rt, int32_t j) { instr(rs, rt, Operand(j)); } 418 #define DEFINE_INSTRUCTION2(instr) \ 419 void instr(Register rs, const Operand& rt); \ 420 void instr(Register rs, Register rt) { instr(rs, Operand(rt)); } \ 421 void instr(Register rs, int32_t j) { instr(rs, Operand(j)); } 423 #define DEFINE_INSTRUCTION3(instr) \ 424 void instr(Register rd_hi, Register rd_lo, Register rs, const Operand& rt); \ 425 void instr(Register rd_hi, Register rd_lo, Register rs, Register rt) { \ 426 instr(rd_hi, rd_lo, rs, Operand(rt)); \ 428 void instr(Register rd_hi, Register rd_lo, Register rs, int32_t j) { \ 429 instr(rd_hi, rd_lo, rs, Operand(j)); \ 432 DEFINE_INSTRUCTION(Addu);
433 DEFINE_INSTRUCTION(Subu);
434 DEFINE_INSTRUCTION(Mul);
435 DEFINE_INSTRUCTION(Div);
436 DEFINE_INSTRUCTION(Divu);
437 DEFINE_INSTRUCTION(Mod);
438 DEFINE_INSTRUCTION(Modu);
439 DEFINE_INSTRUCTION(Mulh);
440 DEFINE_INSTRUCTION2(Mult);
441 DEFINE_INSTRUCTION(Mulhu);
442 DEFINE_INSTRUCTION2(Multu);
443 DEFINE_INSTRUCTION2(Div);
444 DEFINE_INSTRUCTION2(Divu);
446 DEFINE_INSTRUCTION3(Div);
447 DEFINE_INSTRUCTION3(Mul);
448 DEFINE_INSTRUCTION3(Mulu);
450 DEFINE_INSTRUCTION(And);
451 DEFINE_INSTRUCTION(Or);
452 DEFINE_INSTRUCTION(Xor);
453 DEFINE_INSTRUCTION(Nor);
454 DEFINE_INSTRUCTION2(Neg);
456 DEFINE_INSTRUCTION(Slt);
457 DEFINE_INSTRUCTION(Sltu);
458 DEFINE_INSTRUCTION(Sle);
459 DEFINE_INSTRUCTION(Sleu);
460 DEFINE_INSTRUCTION(Sgt);
461 DEFINE_INSTRUCTION(Sgtu);
462 DEFINE_INSTRUCTION(Sge);
463 DEFINE_INSTRUCTION(Sgeu);
466 DEFINE_INSTRUCTION(Ror);
468 #undef DEFINE_INSTRUCTION 469 #undef DEFINE_INSTRUCTION2 470 #undef DEFINE_INSTRUCTION3 472 void SmiUntag(Register reg) { sra(reg, reg, kSmiTagSize); }
474 void SmiUntag(Register dst, Register src) { sra(dst, src, kSmiTagSize); }
481 void PrepareForTailCall(
const ParameterCount& callee_args_count,
482 Register caller_args_count_reg, Register scratch0,
485 int CalculateStackPassedWords(
int num_reg_arguments,
486 int num_double_arguments);
497 void PrepareCallCFunction(
int num_reg_arguments,
int num_double_registers,
499 void PrepareCallCFunction(
int num_reg_arguments, Register scratch);
510 void CallCFunction(ExternalReference
function,
int num_arguments);
511 void CallCFunction(Register
function,
int num_arguments);
512 void CallCFunction(ExternalReference
function,
int num_reg_arguments,
513 int num_double_arguments);
514 void CallCFunction(Register
function,
int num_reg_arguments,
515 int num_double_arguments);
516 void MovFromFloatResult(DoubleRegister dst);
517 void MovFromFloatParameter(DoubleRegister dst);
523 void MovToFloatParameter(DoubleRegister src);
524 void MovToFloatParameters(DoubleRegister src1, DoubleRegister src2);
525 void MovToFloatResult(DoubleRegister src);
528 inline void PrepareCEntryArgs(
int num_args) { li(a0, num_args); }
529 inline void PrepareCEntryFunction(
const ExternalReference& ref) {
533 void CheckPageFlag(Register
object, Register scratch,
int mask, Condition cc,
534 Label* condition_met);
539 void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
547 void TryInlineTruncateDoubleToI(Register result, DoubleRegister input,
553 void TruncateDoubleToI(Isolate* isolate, Zone* zone, Register result,
554 DoubleRegister double_input, StubCallMode stub_mode);
557 void Movz(Register rd, Register rs, Register rt);
558 void Movn(Register rd, Register rs, Register rt);
559 void Movt(Register rd, Register rs, uint16_t cc = 0);
560 void Movf(Register rd, Register rs, uint16_t cc = 0);
562 void LoadZeroIfFPUCondition(Register dest);
563 void LoadZeroIfNotFPUCondition(Register dest);
565 void LoadZeroIfConditionNotZero(Register dest, Register condition);
566 void LoadZeroIfConditionZero(Register dest, Register condition);
567 void LoadZeroOnCondition(Register rd, Register rs,
const Operand& rt,
570 void Clz(Register rd, Register rs);
571 void Ctz(Register rd, Register rs);
572 void Popcnt(Register rd, Register rs);
575 void AddPair(Register dst_low, Register dst_high, Register left_low,
576 Register left_high, Register right_low, Register right_high,
577 Register scratch1, Register scratch2);
579 void SubPair(Register dst_low, Register dst_high, Register left_low,
580 Register left_high, Register right_low, Register right_high,
581 Register scratch1, Register scratch2);
583 void AndPair(Register dst_low, Register dst_high, Register left_low,
584 Register left_high, Register right_low, Register right_high);
586 void OrPair(Register dst_low, Register dst_high, Register left_low,
587 Register left_high, Register right_low, Register right_high);
589 void XorPair(Register dst_low, Register dst_high, Register left_low,
590 Register left_high, Register right_low, Register right_high);
592 void MulPair(Register dst_low, Register dst_high, Register left_low,
593 Register left_high, Register right_low, Register right_high,
594 Register scratch1, Register scratch2);
596 void ShlPair(Register dst_low, Register dst_high, Register src_low,
597 Register src_high, Register shift, Register scratch1,
600 void ShlPair(Register dst_low, Register dst_high, Register src_low,
601 Register src_high,
uint32_t shift, Register scratch);
603 void ShrPair(Register dst_low, Register dst_high, Register src_low,
604 Register src_high, Register shift, Register scratch1,
607 void ShrPair(Register dst_low, Register dst_high, Register src_low,
608 Register src_high,
uint32_t shift, Register scratch);
610 void SarPair(Register dst_low, Register dst_high, Register src_low,
611 Register src_high, Register shift, Register scratch1,
614 void SarPair(Register dst_low, Register dst_high, Register src_low,
615 Register src_high,
uint32_t shift, Register scratch);
618 void Ins(Register rt, Register rs, uint16_t pos, uint16_t size);
619 void Ext(Register rt, Register rs, uint16_t pos, uint16_t size);
620 void ExtractBits(Register dest, Register source, Register pos,
int size,
621 bool sign_extend =
false);
622 void InsertBits(Register dest, Register source, Register pos,
int size);
624 void Seb(Register rd, Register rt);
625 void Seh(Register rd, Register rt);
626 void Neg_s(FPURegister fd, FPURegister fs);
627 void Neg_d(FPURegister fd, FPURegister fs);
630 void Bovc(Register rt, Register rs, Label* L);
631 void Bnvc(Register rt, Register rs, Label* L);
634 void Trunc_uw_s(FPURegister fd, FPURegister fs, FPURegister scratch);
635 void Trunc_uw_s(Register rd, FPURegister fs, FPURegister scratch);
637 void Trunc_w_d(FPURegister fd, FPURegister fs);
638 void Round_w_d(FPURegister fd, FPURegister fs);
639 void Floor_w_d(FPURegister fd, FPURegister fs);
640 void Ceil_w_d(FPURegister fd, FPURegister fs);
643 void Trunc_d_d(FPURegister fd, FPURegister fs);
644 void Round_d_d(FPURegister fd, FPURegister fs);
645 void Floor_d_d(FPURegister fd, FPURegister fs);
646 void Ceil_d_d(FPURegister fd, FPURegister fs);
649 void Trunc_s_s(FPURegister fd, FPURegister fs);
650 void Round_s_s(FPURegister fd, FPURegister fs);
651 void Floor_s_s(FPURegister fd, FPURegister fs);
652 void Ceil_s_s(FPURegister fd, FPURegister fs);
659 void Mthc1(Register rt, FPURegister fs);
665 void Mfhc1(Register rt, FPURegister fs);
667 void Madd_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
668 FPURegister scratch);
669 void Madd_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
670 FPURegister scratch);
671 void Msub_s(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
672 FPURegister scratch);
673 void Msub_d(FPURegister fd, FPURegister fr, FPURegister fs, FPURegister ft,
674 FPURegister scratch);
677 void ByteSwapSigned(Register dest, Register src,
int operand_size);
678 void ByteSwapUnsigned(Register dest, Register src,
int operand_size);
680 void Ulh(Register rd,
const MemOperand& rs);
681 void Ulhu(Register rd,
const MemOperand& rs);
682 void Ush(Register rd,
const MemOperand& rs, Register scratch);
684 void Ulw(Register rd,
const MemOperand& rs);
685 void Usw(Register rd,
const MemOperand& rs);
687 void Ulwc1(FPURegister fd,
const MemOperand& rs, Register scratch);
688 void Uswc1(FPURegister fd,
const MemOperand& rs, Register scratch);
690 void Uldc1(FPURegister fd,
const MemOperand& rs, Register scratch);
691 void Usdc1(FPURegister fd,
const MemOperand& rs, Register scratch);
693 void Ldc1(FPURegister fd,
const MemOperand& src);
694 void Sdc1(FPURegister fs,
const MemOperand& dst);
696 void Ll(Register rd,
const MemOperand& rs);
697 void Sc(Register rd,
const MemOperand& rs);
707 void Float32Max(FPURegister dst, FPURegister src1, FPURegister src2,
709 void Float32Min(FPURegister dst, FPURegister src1, FPURegister src2,
711 void Float64Max(DoubleRegister dst, DoubleRegister src1, DoubleRegister src2,
713 void Float64Min(DoubleRegister dst, DoubleRegister src1, DoubleRegister src2,
717 void Float32MaxOutOfLine(FPURegister dst, FPURegister src1, FPURegister src2);
718 void Float32MinOutOfLine(FPURegister dst, FPURegister src1, FPURegister src2);
719 void Float64MaxOutOfLine(DoubleRegister dst, DoubleRegister src1,
720 DoubleRegister src2);
721 void Float64MinOutOfLine(DoubleRegister dst, DoubleRegister src1,
722 DoubleRegister src2);
724 bool IsDoubleZeroRegSet() {
return has_double_zero_reg_set_; }
726 void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
728 inline void Move(Register dst, Handle<HeapObject> handle) { li(dst, handle); }
729 inline void Move(Register dst, Smi smi) { li(dst, Operand(smi)); }
731 inline void Move(Register dst, Register src) {
737 inline void Move_d(FPURegister dst, FPURegister src) {
743 inline void Move_s(FPURegister dst, FPURegister src) {
749 inline void Move(FPURegister dst, FPURegister src) { Move_d(dst, src); }
751 inline void Move(Register dst_low, Register dst_high, FPURegister src) {
753 Mfhc1(dst_high, src);
756 inline void FmoveHigh(Register dst_high, FPURegister src) {
757 Mfhc1(dst_high, src);
760 inline void FmoveHigh(FPURegister dst, Register src_high) {
761 Mthc1(src_high, dst);
764 inline void FmoveLow(Register dst_low, FPURegister src) {
768 void FmoveLow(FPURegister dst, Register src_low);
770 inline void Move(FPURegister dst, Register src_low, Register src_high) {
772 Mthc1(src_high, dst);
775 void Move(FPURegister dst,
float imm) { Move(dst, bit_cast<uint32_t>(imm)); }
776 void Move(FPURegister dst,
double imm) { Move(dst, bit_cast<uint64_t>(imm)); }
777 void Move(FPURegister dst,
uint32_t src);
778 void Move(FPURegister dst, uint64_t src);
785 void AddOverflow(Register dst, Register left,
const Operand& right,
789 void SubOverflow(Register dst, Register left,
const Operand& right,
792 void MulOverflow(Register dst, Register left,
const Operand& right,
796 #ifdef _MIPS_ARCH_MIPS32R6 797 static constexpr
int kSwitchTablePrologueSize = 5;
799 static constexpr
int kSwitchTablePrologueSize = 10;
803 template <
typename Func>
804 void GenerateSwitchTable(Register index,
size_t case_count,
805 Func GetLabelFunction);
808 void LoadRoot(Register destination, RootIndex index)
override;
809 void LoadRoot(Register destination, RootIndex index, Condition cond,
810 Register src1,
const Operand& src2);
813 void FPUCanonicalizeNaN(
const DoubleRegister dst,
const DoubleRegister src);
819 void Cvt_d_uw(FPURegister fd, Register rs, FPURegister scratch);
822 void Trunc_uw_d(FPURegister fd, FPURegister fs, FPURegister scratch);
823 void Trunc_uw_d(Register rd, FPURegister fs, FPURegister scratch);
826 void JumpIfSmi(Register value, Label* smi_label, Register scratch = at,
827 BranchDelaySlot bd = PROTECT);
829 void JumpIfEqual(Register a, int32_t b, Label* dest) {
830 li(kScratchReg, Operand(b));
831 Branch(dest, eq, a, Operand(kScratchReg));
834 void JumpIfLessThan(Register a, int32_t b, Label* dest) {
835 li(kScratchReg, Operand(b));
836 Branch(dest, lt, a, Operand(kScratchReg));
840 void PushStandardFrame(Register function_reg);
843 static int ActivationFrameAlignment();
847 void ComputeCodeStartAddress(Register dst);
849 void ResetSpeculationPoisonRegister();
852 void BranchLong(Label* L, BranchDelaySlot bdslot);
854 inline Register GetRtAsRegisterHelper(
const Operand& rt, Register scratch);
856 inline int32_t GetOffset(int32_t offset, Label* L, OffsetSize bits);
859 bool has_double_zero_reg_set_ =
false;
861 void CallCFunctionHelper(Register function_base, int16_t function_offset,
862 int num_reg_arguments,
int num_double_arguments);
864 void CompareF(SecondaryField sizeField, FPUCondition cc, FPURegister cmp1,
867 void CompareIsNanF(SecondaryField sizeField, FPURegister cmp1,
870 void BranchShortMSA(MSABranchDF df, Label* target, MSABranchCondition cond,
871 MSARegister wt, BranchDelaySlot bd = PROTECT);
873 bool CalculateOffset(Label* L, int32_t& offset, OffsetSize bits);
874 bool CalculateOffset(Label* L, int32_t& offset, OffsetSize bits,
875 Register& scratch,
const Operand& rt);
877 void BranchShortHelperR6(int32_t offset, Label* L);
878 void BranchShortHelper(int16_t offset, Label* L, BranchDelaySlot bdslot);
879 bool BranchShortHelperR6(int32_t offset, Label* L, Condition cond,
880 Register rs,
const Operand& rt);
881 bool BranchShortHelper(int16_t offset, Label* L, Condition cond, Register rs,
882 const Operand& rt, BranchDelaySlot bdslot);
883 bool BranchShortCheck(int32_t offset, Label* L, Condition cond, Register rs,
884 const Operand& rt, BranchDelaySlot bdslot);
886 void BranchAndLinkShortHelperR6(int32_t offset, Label* L);
887 void BranchAndLinkShortHelper(int16_t offset, Label* L,
888 BranchDelaySlot bdslot);
889 void BranchAndLinkShort(int32_t offset, BranchDelaySlot bdslot = PROTECT);
890 void BranchAndLinkShort(Label* L, BranchDelaySlot bdslot = PROTECT);
891 bool BranchAndLinkShortHelperR6(int32_t offset, Label* L, Condition cond,
892 Register rs,
const Operand& rt);
893 bool BranchAndLinkShortHelper(int16_t offset, Label* L, Condition cond,
894 Register rs,
const Operand& rt,
895 BranchDelaySlot bdslot);
896 bool BranchAndLinkShortCheck(int32_t offset, Label* L, Condition cond,
897 Register rs,
const Operand& rt,
898 BranchDelaySlot bdslot);
899 void BranchAndLinkLong(Label* L, BranchDelaySlot bdslot);
901 template <
typename RoundFunc>
902 void RoundDouble(FPURegister dst, FPURegister src, FPURoundingMode mode,
905 template <
typename RoundFunc>
906 void RoundFloat(FPURegister dst, FPURegister src, FPURoundingMode mode,
910 void PushCommonFrame(Register marker_reg = no_reg);
912 void CallRecordWriteStub(Register
object, Register address,
913 RememberedSetAction remembered_set_action,
914 SaveFPRegsMode fp_mode, Handle<Code> code_target,
915 Address wasm_target);
919 class MacroAssembler :
public TurboAssembler {
921 MacroAssembler(
const AssemblerOptions& options,
void* buffer,
int size)
922 : TurboAssembler(options, buffer, size) {}
924 MacroAssembler(Isolate* isolate,
void* buffer,
int size,
925 CodeObjectRequired create_code_object)
926 : MacroAssembler(isolate, AssemblerOptions::Default(isolate), buffer,
927 size, create_code_object) {}
929 MacroAssembler(Isolate* isolate,
const AssemblerOptions& options,
930 void* buffer,
int size, CodeObjectRequired create_code_object);
934 void Swap(Register reg1, Register reg2, Register scratch = no_reg);
936 void PushRoot(RootIndex index) {
937 UseScratchRegisterScope temps(
this);
938 Register scratch = temps.Acquire();
939 LoadRoot(scratch, index);
944 void JumpIfRoot(Register with, RootIndex index, Label* if_equal) {
945 UseScratchRegisterScope temps(
this);
946 Register scratch = temps.Acquire();
947 LoadRoot(scratch, index);
948 Branch(if_equal, eq, with, Operand(scratch));
952 void JumpIfNotRoot(Register with, RootIndex index, Label* if_not_equal) {
953 UseScratchRegisterScope temps(
this);
954 Register scratch = temps.Acquire();
955 LoadRoot(scratch, index);
956 Branch(if_not_equal, ne, with, Operand(scratch));
967 void RecordWriteField(
968 Register
object,
int offset, Register value, Register scratch,
969 RAStatus ra_status, SaveFPRegsMode save_fp,
970 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
971 SmiCheck smi_check = INLINE_SMI_CHECK);
977 Register
object, Register address, Register value, RAStatus ra_status,
978 SaveFPRegsMode save_fp,
979 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
980 SmiCheck smi_check = INLINE_SMI_CHECK);
982 void Pref(int32_t hint,
const MemOperand& rs);
986 void PushSafepointRegisters();
987 void PopSafepointRegisters();
994 void EmitFPUTruncate(
995 FPURoundingMode rounding_mode, Register result,
996 DoubleRegister double_input, Register scratch,
997 DoubleRegister double_scratch, Register except_flag,
998 CheckForInexactConversion check_inexact = kDontCheckForInexactConversion);
1004 void EnterExitFrame(
bool save_doubles,
int stack_space = 0,
1005 StackFrame::Type frame_type = StackFrame::EXIT);
1008 void LeaveExitFrame(
bool save_doubles, Register arg_count,
1009 bool do_return = NO_EMIT_RETURN,
1010 bool argument_count_is_length =
false);
1013 void AssertStackIsAligned();
1016 void LoadGlobalProxy(Register dst) {
1017 LoadNativeContextSlot(Context::GLOBAL_PROXY_INDEX, dst);
1020 void LoadNativeContextSlot(
int index, Register dst);
1026 void InvokeFunctionCode(Register
function, Register new_target,
1027 const ParameterCount& expected,
1028 const ParameterCount& actual, InvokeFlag flag);
1031 void CheckDebugHook(Register fun, Register new_target,
1032 const ParameterCount& expected,
1033 const ParameterCount& actual);
1037 void InvokeFunction(Register
function, Register new_target,
1038 const ParameterCount& actual, InvokeFlag flag);
1040 void InvokeFunction(Register
function,
const ParameterCount& expected,
1041 const ParameterCount& actual, InvokeFlag flag);
1044 void MaybeDropFrames();
1049 void PushStackHandler();
1053 void PopStackHandler();
1058 void GetObjectType(Register
function,
1065 #define COND_ARGS Condition cond = al, Register rs = zero_reg, \ 1066 const Operand& rt = Operand(zero_reg), BranchDelaySlot bd = PROTECT 1069 void CallStub(CodeStub* stub,
1073 void TailCallStub(CodeStub* stub, COND_ARGS);
1078 void CallRuntime(
const Runtime::Function* f,
int num_arguments,
1079 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
1082 void CallRuntime(Runtime::FunctionId fid,
1083 SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1084 const Runtime::Function*
function = Runtime::FunctionForId(fid);
1085 CallRuntime(
function, function->nargs, save_doubles);
1089 void CallRuntime(Runtime::FunctionId
id,
int num_arguments,
1090 SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1091 CallRuntime(Runtime::FunctionForId(
id), num_arguments, save_doubles);
1095 void TailCallRuntime(Runtime::FunctionId fid);
1098 void JumpToExternalReference(
const ExternalReference& builtin,
1099 BranchDelaySlot bd = PROTECT,
1100 bool builtin_exit_frame =
false);
1103 void JumpToInstructionStream(Address entry);
1107 void LoadWeakValue(Register out, Register in, Label* target_if_cleared);
1112 void IncrementCounter(StatsCounter* counter,
int value,
1113 Register scratch1, Register scratch2);
1114 void DecrementCounter(StatsCounter* counter,
int value,
1115 Register scratch1, Register scratch2);
1120 void SmiTag(Register reg) {
1121 Addu(reg, reg, reg);
1124 void SmiTag(Register dst, Register src) { Addu(dst, src, src); }
1127 inline void SmiTst(Register value, Register scratch) {
1128 And(scratch, value, Operand(kSmiTagMask));
1133 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1136 void JumpIfNotSmi(Register value,
1137 Label* not_smi_label,
1138 Register scratch = at,
1139 BranchDelaySlot bd = PROTECT);
1142 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
1145 void AssertNotSmi(Register
object);
1146 void AssertSmi(Register
object);
1149 void AssertConstructor(Register
object);
1152 void AssertFunction(Register
object);
1156 void AssertBoundFunction(Register
object);
1160 void AssertGeneratorObject(Register
object);
1164 void AssertUndefinedOrAllocationSite(Register
object, Register scratch);
1166 template<
typename Field>
1167 void DecodeField(Register dst, Register src) {
1168 Ext(dst, src, Field::kShift, Field::kSize);
1171 template<
typename Field>
1172 void DecodeField(Register reg) {
1173 DecodeField<Field>(reg, reg);
1178 void InvokePrologue(
const ParameterCount& expected,
1179 const ParameterCount& actual, Label* done,
1180 bool* definitely_mismatches, InvokeFlag flag);
1183 static int SafepointRegisterStackIndex(
int reg_code);
1187 friend class StandardFrame;
1190 template <
typename Func>
1191 void TurboAssembler::GenerateSwitchTable(Register index,
size_t case_count,
1192 Func GetLabelFunction) {
1194 BlockTrampolinePoolFor(case_count + kSwitchTablePrologueSize);
1195 UseScratchRegisterScope temps(
this);
1196 Register scratch = temps.Acquire();
1197 if (kArchVariant >= kMips32r6) {
1198 addiupc(scratch, 5);
1199 Lsa(scratch, scratch, index, kPointerSizeLog2);
1200 lw(scratch, MemOperand(scratch));
1204 sll(scratch, index, kPointerSizeLog2);
1206 addu(scratch, scratch, ra);
1208 lw(scratch, MemOperand(scratch, 6 * v8::internal::kInstrSize));
1212 for (
size_t index = 0; index < case_count; ++index) {
1213 dd(GetLabelFunction(index));
1217 #define ACCESS_MASM(masm) masm-> 1222 #endif // V8_MIPS_MACRO_ASSEMBLER_MIPS_H_