5 #ifndef INCLUDED_FROM_MACRO_ASSEMBLER_H 6 #error This header must be included via macro-assembler.h 9 #ifndef V8_S390_MACRO_ASSEMBLER_S390_H_ 10 #define V8_S390_MACRO_ASSEMBLER_S390_H_ 12 #include "src/bailout-reason.h" 13 #include "src/contexts.h" 14 #include "src/globals.h" 15 #include "src/s390/assembler-s390.h" 21 constexpr Register kReturnRegister0 = r2;
22 constexpr Register kReturnRegister1 = r3;
23 constexpr Register kReturnRegister2 = r4;
24 constexpr Register kJSFunctionRegister = r3;
25 constexpr Register kContextRegister = r13;
26 constexpr Register kAllocateSizeRegister = r3;
27 constexpr Register kSpeculationPoisonRegister = r9;
28 constexpr Register kInterpreterAccumulatorRegister = r2;
29 constexpr Register kInterpreterBytecodeOffsetRegister = r6;
30 constexpr Register kInterpreterBytecodeArrayRegister = r7;
31 constexpr Register kInterpreterDispatchTableRegister = r8;
33 constexpr Register kJavaScriptCallArgCountRegister = r2;
34 constexpr Register kJavaScriptCallCodeStartRegister = r4;
35 constexpr Register kJavaScriptCallTargetRegister = kJSFunctionRegister;
36 constexpr Register kJavaScriptCallNewTargetRegister = r5;
37 constexpr Register kJavaScriptCallExtraArg1Register = r4;
39 constexpr Register kOffHeapTrampolineRegister = ip;
40 constexpr Register kRuntimeCallFunctionRegister = r3;
41 constexpr Register kRuntimeCallArgCountRegister = r2;
42 constexpr Register kRuntimeCallArgvRegister = r4;
43 constexpr Register kWasmInstanceRegister = r6;
44 constexpr Register kWasmCompileLazyFuncIndexRegister = r7;
50 inline MemOperand FieldMemOperand(Register
object,
int offset) {
51 return MemOperand(
object, offset - kHeapObjectTag);
55 inline MemOperand FieldMemOperand(Register
object, Register index,
int offset) {
56 return MemOperand(
object, index, offset - kHeapObjectTag);
59 enum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
60 enum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
61 enum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
63 Register GetRegisterThatIsNotOneOf(Register reg1, Register reg2 = no_reg,
64 Register reg3 = no_reg,
65 Register reg4 = no_reg,
66 Register reg5 = no_reg,
67 Register reg6 = no_reg);
70 #if V8_TARGET_ARCH_S390X 86 #define LoadComplementRR lcgr 87 #define LoadNegativeRR lngr 91 #define AddPImm_RRI aghik 92 #define AddLogicalP_RRR algrk 94 #define SubLogicalP_RRR slgrk 101 #define LoadAndTestRR ltgr 102 #define LoadImmP lghi 106 #define CmpLogicalPW clgfi 109 #define ShiftLeftP sllg 110 #define ShiftRightP srlg 111 #define ShiftLeftArithP slag 112 #define ShiftRightArithP srag 123 #define LoadComplementRR lcr 124 #define LoadNegativeRR lnr 128 #define AddPImm_RRI ahik 129 #define AddLogicalP_RRR alrk 131 #define SubLogicalP_RRR slrk 138 #define LoadAndTestRR ltr 143 #define CmpLogicalPW clfi 146 #define ShiftLeftP ShiftLeft 147 #define ShiftRightP ShiftRight 148 #define ShiftLeftArithP ShiftLeftArith 149 #define ShiftRightArithP ShiftRightArith 153 class V8_EXPORT_PRIVATE TurboAssembler :
public TurboAssemblerBase {
155 TurboAssembler(
const AssemblerOptions& options,
void* buffer,
int buffer_size)
156 : TurboAssemblerBase(options, buffer, buffer_size) {}
158 TurboAssembler(Isolate* isolate,
const AssemblerOptions& options,
159 void* buffer,
int buffer_size,
160 CodeObjectRequired create_code_object)
161 : TurboAssemblerBase(isolate, options, buffer, buffer_size,
162 create_code_object) {}
164 void LoadFromConstantsTable(Register destination,
165 int constant_index)
override;
166 void LoadRootRegisterOffset(Register destination, intptr_t offset)
override;
167 void LoadRootRelative(Register destination, int32_t offset)
override;
170 void Jump(Register target, Condition cond = al);
171 void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al);
172 void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
174 inline void JumpIfSmi(Register value, Label* smi_label) {
178 void JumpIfEqual(Register x, int32_t y, Label* dest);
179 void JumpIfLessThan(Register x, int32_t y, Label* dest);
181 void Call(Register target);
182 void Call(Address target, RelocInfo::Mode rmode, Condition cond = al);
183 void Call(Handle<Code> code, RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
184 Condition cond = al);
185 void Ret() { b(r14); }
186 void Ret(Condition cond) { b(cond, r14); }
188 void CallForDeoptimization(Address target,
int deopt_id,
189 RelocInfo::Mode rmode) {
196 void Drop(
int count);
197 void Drop(Register count, Register scratch = r0);
204 void Call(Label* target);
207 void Move(Register dst, Smi smi) { LoadSmiLiteral(dst, smi); }
208 void Move(Register dst, Handle<HeapObject> value);
209 void Move(Register dst, ExternalReference reference);
210 void Move(Register dst, Register src, Condition cond = al);
211 void Move(DoubleRegister dst, DoubleRegister src);
213 void MoveChar(
const MemOperand& opnd1,
const MemOperand& opnd2,
214 const Operand& length);
216 void CompareLogicalChar(
const MemOperand& opnd1,
const MemOperand& opnd2,
217 const Operand& length);
219 void ExclusiveOrChar(
const MemOperand& opnd1,
const MemOperand& opnd2,
220 const Operand& length);
222 void RotateInsertSelectBits(Register dst, Register src,
223 const Operand& startBit,
const Operand& endBit,
224 const Operand& shiftAmt,
bool zeroBits);
226 void BranchRelativeOnIdxHighP(Register dst, Register inc, Label* L);
228 void SaveRegisters(RegList registers);
229 void RestoreRegisters(RegList registers);
231 void CallRecordWriteStub(Register
object, Register address,
232 RememberedSetAction remembered_set_action,
233 SaveFPRegsMode fp_mode);
234 void CallRecordWriteStub(Register
object, Register address,
235 RememberedSetAction remembered_set_action,
236 SaveFPRegsMode fp_mode, Address wasm_target);
238 void MultiPush(RegList regs, Register location = sp);
239 void MultiPop(RegList regs, Register location = sp);
241 void MultiPushDoubles(RegList dregs, Register location = sp);
242 void MultiPopDoubles(RegList dregs, Register location = sp);
246 int RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
247 Register exclusion1 = no_reg,
248 Register exclusion2 = no_reg,
249 Register exclusion3 = no_reg)
const;
253 int PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
254 Register exclusion2 = no_reg,
255 Register exclusion3 = no_reg);
258 int PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1 = no_reg,
259 Register exclusion2 = no_reg,
260 Register exclusion3 = no_reg);
263 void LoadRoot(Register destination, RootIndex index)
override {
264 LoadRoot(destination, index, al);
266 void LoadRoot(Register destination, RootIndex index, Condition cond);
274 void Add32(Register dst,
const Operand& imm);
275 void Add32_RI(Register dst,
const Operand& imm);
276 void AddP(Register dst,
const Operand& imm);
277 void Add32(Register dst, Register src,
const Operand& imm);
278 void Add32_RRI(Register dst, Register src,
const Operand& imm);
279 void AddP(Register dst, Register src,
const Operand& imm);
282 void Add32(Register dst, Register src);
283 void AddP(Register dst, Register src);
284 void AddP_ExtendSrc(Register dst, Register src);
285 void Add32(Register dst, Register src1, Register src2);
286 void AddP(Register dst, Register src1, Register src2);
287 void AddP_ExtendSrc(Register dst, Register src1, Register src2);
290 void Add32(Register dst,
const MemOperand& opnd);
291 void AddP(Register dst,
const MemOperand& opnd);
292 void AddP_ExtendSrc(Register dst,
const MemOperand& opnd);
295 void Add32(
const MemOperand& opnd,
const Operand& imm);
296 void AddP(
const MemOperand& opnd,
const Operand& imm);
299 void AddLogical32(Register dst, Register src1, Register src2);
302 void AddLogicalWithCarry32(Register dst, Register src1, Register src2);
305 void AddLogical(Register dst,
const Operand& imm);
306 void AddLogicalP(Register dst,
const Operand& imm);
309 void AddLogical(Register dst,
const MemOperand& opnd);
310 void AddLogicalP(Register dst,
const MemOperand& opnd);
313 void Sub32(Register dst,
const Operand& imm);
314 void Sub32_RI(Register dst,
const Operand& imm) { Sub32(dst, imm); }
315 void SubP(Register dst,
const Operand& imm);
316 void Sub32(Register dst, Register src,
const Operand& imm);
317 void Sub32_RRI(Register dst, Register src,
const Operand& imm) {
318 Sub32(dst, src, imm);
320 void SubP(Register dst, Register src,
const Operand& imm);
323 void Sub32(Register dst, Register src);
324 void SubP(Register dst, Register src);
325 void SubP_ExtendSrc(Register dst, Register src);
326 void Sub32(Register dst, Register src1, Register src2);
327 void SubP(Register dst, Register src1, Register src2);
328 void SubP_ExtendSrc(Register dst, Register src1, Register src2);
331 void Sub32(Register dst,
const MemOperand& opnd);
332 void SubP(Register dst,
const MemOperand& opnd);
333 void SubP_ExtendSrc(Register dst,
const MemOperand& opnd);
334 void LoadAndSub32(Register dst, Register src,
const MemOperand& opnd);
335 void LoadAndSub64(Register dst, Register src,
const MemOperand& opnd);
338 void SubLogical(Register dst,
const MemOperand& opnd);
339 void SubLogicalP(Register dst,
const MemOperand& opnd);
340 void SubLogicalP_ExtendSrc(Register dst,
const MemOperand& opnd);
342 void SubLogical32(Register dst, Register src1, Register src2);
344 void SubLogicalWithBorrow32(Register dst, Register src1, Register src2);
347 void MulP(Register dst,
const Operand& opnd);
348 void MulP(Register dst, Register src);
349 void MulP(Register dst,
const MemOperand& opnd);
350 void Mul(Register dst, Register src1, Register src2);
351 void Mul32(Register dst,
const MemOperand& src1);
352 void Mul32(Register dst, Register src1);
353 void Mul32(Register dst,
const Operand& src1);
354 void MulHigh32(Register dst, Register src1,
const MemOperand& src2);
355 void MulHigh32(Register dst, Register src1, Register src2);
356 void MulHigh32(Register dst, Register src1,
const Operand& src2);
357 void MulHighU32(Register dst, Register src1,
const MemOperand& src2);
358 void MulHighU32(Register dst, Register src1, Register src2);
359 void MulHighU32(Register dst, Register src1,
const Operand& src2);
360 void Mul32WithOverflowIfCCUnequal(Register dst, Register src1,
361 const MemOperand& src2);
362 void Mul32WithOverflowIfCCUnequal(Register dst, Register src1, Register src2);
363 void Mul32WithOverflowIfCCUnequal(Register dst, Register src1,
364 const Operand& src2);
365 void Mul64(Register dst,
const MemOperand& src1);
366 void Mul64(Register dst, Register src1);
367 void Mul64(Register dst,
const Operand& src1);
368 void MulPWithCondition(Register dst, Register src1, Register src2);
371 void DivP(Register dividend, Register divider);
372 void Div32(Register dst, Register src1,
const MemOperand& src2);
373 void Div32(Register dst, Register src1, Register src2);
374 void DivU32(Register dst, Register src1,
const MemOperand& src2);
375 void DivU32(Register dst, Register src1, Register src2);
376 void Div64(Register dst, Register src1,
const MemOperand& src2);
377 void Div64(Register dst, Register src1, Register src2);
378 void DivU64(Register dst, Register src1,
const MemOperand& src2);
379 void DivU64(Register dst, Register src1, Register src2);
382 void Mod32(Register dst, Register src1,
const MemOperand& src2);
383 void Mod32(Register dst, Register src1, Register src2);
384 void ModU32(Register dst, Register src1,
const MemOperand& src2);
385 void ModU32(Register dst, Register src1, Register src2);
386 void Mod64(Register dst, Register src1,
const MemOperand& src2);
387 void Mod64(Register dst, Register src1, Register src2);
388 void ModU64(Register dst, Register src1,
const MemOperand& src2);
389 void ModU64(Register dst, Register src1, Register src2);
392 void Sqrt(DoubleRegister result, DoubleRegister input);
393 void Sqrt(DoubleRegister result,
const MemOperand& input);
396 void Cmp32(Register src1, Register src2);
397 void CmpP(Register src1, Register src2);
398 void Cmp32(Register dst,
const Operand& opnd);
399 void CmpP(Register dst,
const Operand& opnd);
400 void Cmp32(Register dst,
const MemOperand& opnd);
401 void CmpP(Register dst,
const MemOperand& opnd);
402 void CmpAndSwap(Register old_val, Register new_val,
const MemOperand& opnd);
403 void CmpAndSwap64(Register old_val, Register new_val,
const MemOperand& opnd);
406 void CmpLogical32(Register src1, Register src2);
407 void CmpLogicalP(Register src1, Register src2);
408 void CmpLogical32(Register src1,
const Operand& opnd);
409 void CmpLogicalP(Register src1,
const Operand& opnd);
410 void CmpLogical32(Register dst,
const MemOperand& opnd);
411 void CmpLogicalP(Register dst,
const MemOperand& opnd);
414 void CmpLogicalByte(
const MemOperand& mem,
const Operand& imm);
417 void Load(Register dst,
const MemOperand& opnd);
418 void Load(Register dst,
const Operand& opnd);
419 void LoadW(Register dst,
const MemOperand& opnd, Register scratch = no_reg);
420 void LoadW(Register dst, Register src);
421 void LoadlW(Register dst,
const MemOperand& opnd, Register scratch = no_reg);
422 void LoadlW(Register dst, Register src);
423 void LoadLogicalHalfWordP(Register dst,
const MemOperand& opnd);
424 void LoadLogicalHalfWordP(Register dst, Register src);
425 void LoadB(Register dst,
const MemOperand& opnd);
426 void LoadB(Register dst, Register src);
427 void LoadlB(Register dst,
const MemOperand& opnd);
428 void LoadlB(Register dst, Register src);
430 void LoadLogicalReversedWordP(Register dst,
const MemOperand& opnd);
431 void LoadLogicalReversedHalfWordP(Register dst,
const MemOperand& opnd);
434 void LoadAndTest32(Register dst, Register src);
435 void LoadAndTestP_ExtendSrc(Register dst, Register src);
436 void LoadAndTestP(Register dst, Register src);
438 void LoadAndTest32(Register dst,
const MemOperand& opnd);
439 void LoadAndTestP(Register dst,
const MemOperand& opnd);
442 void LoadDouble(DoubleRegister dst,
const MemOperand& opnd);
443 void LoadFloat32(DoubleRegister dst,
const MemOperand& opnd);
444 void LoadFloat32ConvertToDouble(DoubleRegister dst,
const MemOperand& mem);
446 void AddFloat32(DoubleRegister dst,
const MemOperand& opnd,
447 DoubleRegister scratch);
448 void AddFloat64(DoubleRegister dst,
const MemOperand& opnd,
449 DoubleRegister scratch);
450 void SubFloat32(DoubleRegister dst,
const MemOperand& opnd,
451 DoubleRegister scratch);
452 void SubFloat64(DoubleRegister dst,
const MemOperand& opnd,
453 DoubleRegister scratch);
454 void MulFloat32(DoubleRegister dst,
const MemOperand& opnd,
455 DoubleRegister scratch);
456 void MulFloat64(DoubleRegister dst,
const MemOperand& opnd,
457 DoubleRegister scratch);
458 void DivFloat32(DoubleRegister dst,
const MemOperand& opnd,
459 DoubleRegister scratch);
460 void DivFloat64(DoubleRegister dst,
const MemOperand& opnd,
461 DoubleRegister scratch);
462 void LoadFloat32ToDouble(DoubleRegister dst,
const MemOperand& opnd,
463 DoubleRegister scratch);
466 void LoadOnConditionP(Condition cond, Register dst, Register src);
468 void LoadPositiveP(Register result, Register input);
469 void LoadPositive32(Register result, Register input);
472 void StoreDouble(DoubleRegister dst,
const MemOperand& opnd);
473 void StoreFloat32(DoubleRegister dst,
const MemOperand& opnd);
474 void StoreDoubleAsFloat32(DoubleRegister src,
const MemOperand& mem,
475 DoubleRegister scratch);
477 void Branch(Condition c,
const Operand& opnd);
478 void BranchOnCount(Register r1, Label* l);
481 void ShiftLeft(Register dst, Register src, Register val);
482 void ShiftLeft(Register dst, Register src,
const Operand& val);
483 void ShiftRight(Register dst, Register src, Register val);
484 void ShiftRight(Register dst, Register src,
const Operand& val);
485 void ShiftLeftArith(Register dst, Register src, Register shift);
486 void ShiftLeftArith(Register dst, Register src,
const Operand& val);
487 void ShiftRightArith(Register dst, Register src, Register shift);
488 void ShiftRightArith(Register dst, Register src,
const Operand& val);
490 void ClearRightImm(Register dst, Register src,
const Operand& val);
493 void And(Register dst, Register src);
494 void AndP(Register dst, Register src);
495 void And(Register dst, Register src1, Register src2);
496 void AndP(Register dst, Register src1, Register src2);
497 void And(Register dst,
const MemOperand& opnd);
498 void AndP(Register dst,
const MemOperand& opnd);
499 void And(Register dst,
const Operand& opnd);
500 void AndP(Register dst,
const Operand& opnd);
501 void And(Register dst, Register src,
const Operand& opnd);
502 void AndP(Register dst, Register src,
const Operand& opnd);
503 void Or(Register dst, Register src);
504 void OrP(Register dst, Register src);
505 void Or(Register dst, Register src1, Register src2);
506 void OrP(Register dst, Register src1, Register src2);
507 void Or(Register dst,
const MemOperand& opnd);
508 void OrP(Register dst,
const MemOperand& opnd);
509 void Or(Register dst,
const Operand& opnd);
510 void OrP(Register dst,
const Operand& opnd);
511 void Or(Register dst, Register src,
const Operand& opnd);
512 void OrP(Register dst, Register src,
const Operand& opnd);
513 void Xor(Register dst, Register src);
514 void XorP(Register dst, Register src);
515 void Xor(Register dst, Register src1, Register src2);
516 void XorP(Register dst, Register src1, Register src2);
517 void Xor(Register dst,
const MemOperand& opnd);
518 void XorP(Register dst,
const MemOperand& opnd);
519 void Xor(Register dst,
const Operand& opnd);
520 void XorP(Register dst,
const Operand& opnd);
521 void Xor(Register dst, Register src,
const Operand& opnd);
522 void XorP(Register dst, Register src,
const Operand& opnd);
523 void Popcnt32(Register dst, Register src);
524 void Not32(Register dst, Register src = no_reg);
525 void Not64(Register dst, Register src = no_reg);
526 void NotP(Register dst, Register src = no_reg);
528 #ifdef V8_TARGET_ARCH_S390X 529 void Popcnt64(Register dst, Register src);
532 void mov(Register dst,
const Operand& src);
534 void CleanUInt32(Register x) {
535 #ifdef V8_TARGET_ARCH_S390X 541 void push(Register src) {
542 lay(sp, MemOperand(sp, -kPointerSize));
543 StoreP(src, MemOperand(sp));
546 void pop(Register dst) {
547 LoadP(dst, MemOperand(sp));
548 la(sp, MemOperand(sp, kPointerSize));
551 void pop() { la(sp, MemOperand(sp, kPointerSize)); }
553 void Push(Register src) { push(src); }
556 void Push(Handle<HeapObject> handle);
560 void Push(Register src1, Register src2) {
561 lay(sp, MemOperand(sp, -kPointerSize * 2));
562 StoreP(src1, MemOperand(sp, kPointerSize));
563 StoreP(src2, MemOperand(sp, 0));
567 void Push(Register src1, Register src2, Register src3) {
568 lay(sp, MemOperand(sp, -kPointerSize * 3));
569 StoreP(src1, MemOperand(sp, kPointerSize * 2));
570 StoreP(src2, MemOperand(sp, kPointerSize));
571 StoreP(src3, MemOperand(sp, 0));
575 void Push(Register src1, Register src2, Register src3, Register src4) {
576 lay(sp, MemOperand(sp, -kPointerSize * 4));
577 StoreP(src1, MemOperand(sp, kPointerSize * 3));
578 StoreP(src2, MemOperand(sp, kPointerSize * 2));
579 StoreP(src3, MemOperand(sp, kPointerSize));
580 StoreP(src4, MemOperand(sp, 0));
584 void Push(Register src1, Register src2, Register src3, Register src4,
586 DCHECK(src1 != src2);
587 DCHECK(src1 != src3);
588 DCHECK(src2 != src3);
589 DCHECK(src1 != src4);
590 DCHECK(src2 != src4);
591 DCHECK(src3 != src4);
592 DCHECK(src1 != src5);
593 DCHECK(src2 != src5);
594 DCHECK(src3 != src5);
595 DCHECK(src4 != src5);
597 lay(sp, MemOperand(sp, -kPointerSize * 5));
598 StoreP(src1, MemOperand(sp, kPointerSize * 4));
599 StoreP(src2, MemOperand(sp, kPointerSize * 3));
600 StoreP(src3, MemOperand(sp, kPointerSize * 2));
601 StoreP(src4, MemOperand(sp, kPointerSize));
602 StoreP(src5, MemOperand(sp, 0));
605 void Pop(Register dst) { pop(dst); }
608 void Pop(Register src1, Register src2) {
609 LoadP(src2, MemOperand(sp, 0));
610 LoadP(src1, MemOperand(sp, kPointerSize));
611 la(sp, MemOperand(sp, 2 * kPointerSize));
615 void Pop(Register src1, Register src2, Register src3) {
616 LoadP(src3, MemOperand(sp, 0));
617 LoadP(src2, MemOperand(sp, kPointerSize));
618 LoadP(src1, MemOperand(sp, 2 * kPointerSize));
619 la(sp, MemOperand(sp, 3 * kPointerSize));
623 void Pop(Register src1, Register src2, Register src3, Register src4) {
624 LoadP(src4, MemOperand(sp, 0));
625 LoadP(src3, MemOperand(sp, kPointerSize));
626 LoadP(src2, MemOperand(sp, 2 * kPointerSize));
627 LoadP(src1, MemOperand(sp, 3 * kPointerSize));
628 la(sp, MemOperand(sp, 4 * kPointerSize));
632 void Pop(Register src1, Register src2, Register src3, Register src4,
634 LoadP(src5, MemOperand(sp, 0));
635 LoadP(src4, MemOperand(sp, kPointerSize));
636 LoadP(src3, MemOperand(sp, 2 * kPointerSize));
637 LoadP(src2, MemOperand(sp, 3 * kPointerSize));
638 LoadP(src1, MemOperand(sp, 4 * kPointerSize));
639 la(sp, MemOperand(sp, 5 * kPointerSize));
643 void PushCommonFrame(Register marker_reg = no_reg);
647 void PushStandardFrame(Register function_reg);
649 void PopCommonFrame(Register marker_reg = no_reg);
653 void RestoreFrameStateForTailCall();
655 void InitializeRootRegister() {
656 ExternalReference isolate_root = ExternalReference::isolate_root(isolate());
657 mov(kRootRegister, Operand(isolate_root));
661 void CanonicalizeNaN(
const DoubleRegister dst,
const DoubleRegister src);
662 void CanonicalizeNaN(
const DoubleRegister value) {
663 CanonicalizeNaN(value, value);
668 void ConvertIntToDouble(DoubleRegister dst, Register src);
672 void ConvertUnsignedIntToDouble(DoubleRegister dst, Register src);
676 void ConvertIntToFloat(DoubleRegister dst, Register src);
680 void ConvertUnsignedIntToFloat(DoubleRegister dst, Register src);
682 void ConvertInt64ToFloat(DoubleRegister double_dst, Register src);
683 void ConvertInt64ToDouble(DoubleRegister double_dst, Register src);
684 void ConvertUnsignedInt64ToFloat(DoubleRegister double_dst, Register src);
685 void ConvertUnsignedInt64ToDouble(DoubleRegister double_dst, Register src);
687 void MovIntToFloat(DoubleRegister dst, Register src);
688 void MovFloatToInt(Register dst, DoubleRegister src);
689 void MovDoubleToInt64(Register dst, DoubleRegister src);
690 void MovInt64ToDouble(DoubleRegister dst, Register src);
693 void ConvertFloat32ToInt64(
const Register dst,
694 const DoubleRegister double_input,
695 FPRoundingMode rounding_mode = kRoundToZero);
699 void ConvertDoubleToInt64(
const Register dst,
700 const DoubleRegister double_input,
701 FPRoundingMode rounding_mode = kRoundToZero);
702 void ConvertDoubleToInt32(
const Register dst,
703 const DoubleRegister double_input,
704 FPRoundingMode rounding_mode = kRoundToZero);
706 void ConvertFloat32ToInt32(
const Register result,
707 const DoubleRegister double_input,
708 FPRoundingMode rounding_mode);
709 void ConvertFloat32ToUnsignedInt32(
710 const Register result,
const DoubleRegister double_input,
711 FPRoundingMode rounding_mode = kRoundToZero);
714 void ConvertDoubleToUnsignedInt64(
715 const Register dst,
const DoubleRegister double_input,
716 FPRoundingMode rounding_mode = kRoundToZero);
717 void ConvertDoubleToUnsignedInt32(
718 const Register dst,
const DoubleRegister double_input,
719 FPRoundingMode rounding_mode = kRoundToZero);
720 void ConvertFloat32ToUnsignedInt64(
721 const Register result,
const DoubleRegister double_input,
722 FPRoundingMode rounding_mode = kRoundToZero);
724 #if !V8_TARGET_ARCH_S390X 725 void ShiftLeftPair(Register dst_low, Register dst_high, Register src_low,
726 Register src_high, Register scratch, Register shift);
727 void ShiftLeftPair(Register dst_low, Register dst_high, Register src_low,
729 void ShiftRightPair(Register dst_low, Register dst_high, Register src_low,
730 Register src_high, Register scratch, Register shift);
731 void ShiftRightPair(Register dst_low, Register dst_high, Register src_low,
733 void ShiftRightArithPair(Register dst_low, Register dst_high,
734 Register src_low, Register src_high,
735 Register scratch, Register shift);
736 void ShiftRightArithPair(Register dst_low, Register dst_high,
737 Register src_low, Register src_high,
uint32_t shift);
741 void StubPrologue(StackFrame::Type type, Register base = no_reg,
742 int prologue_offset = 0);
743 void Prologue(Register base,
int prologue_offset = 0);
746 static int ActivationFrameAlignment();
752 void LoadIntLiteral(Register dst,
int value);
755 void LoadSmiLiteral(Register dst, Smi smi);
758 void LoadDoubleLiteral(DoubleRegister result,
double value, Register scratch);
759 void LoadDoubleLiteral(DoubleRegister result, uint64_t value,
762 void LoadFloat32Literal(DoubleRegister result,
float value, Register scratch);
764 void StoreW(Register src,
const MemOperand& mem, Register scratch = no_reg);
766 void LoadHalfWordP(Register dst, Register src);
768 void LoadHalfWordP(Register dst,
const MemOperand& mem,
769 Register scratch = no_reg);
771 void StoreHalfWord(Register src,
const MemOperand& mem,
772 Register scratch = r0);
773 void StoreByte(Register src,
const MemOperand& mem, Register scratch = r0);
774 void CmpSmiLiteral(Register src1, Smi smi, Register scratch);
777 void SetRoundingMode(FPRoundingMode RN);
780 void ResetRoundingMode();
783 void LoadP(Register dst,
const MemOperand& mem, Register scratch = no_reg);
784 void StoreP(Register src,
const MemOperand& mem, Register scratch = no_reg);
785 void StoreP(
const MemOperand& mem,
const Operand& opnd,
786 Register scratch = no_reg);
787 void LoadMultipleP(Register dst1, Register dst2,
const MemOperand& mem);
788 void StoreMultipleP(Register dst1, Register dst2,
const MemOperand& mem);
789 void LoadMultipleW(Register dst1, Register dst2,
const MemOperand& mem);
790 void StoreMultipleW(Register dst1, Register dst2,
const MemOperand& mem);
792 void SwapP(Register src, Register dst, Register scratch);
793 void SwapP(Register src, MemOperand dst, Register scratch);
794 void SwapP(MemOperand src, MemOperand dst, Register scratch_0,
796 void SwapFloat32(DoubleRegister src, DoubleRegister dst,
797 DoubleRegister scratch);
798 void SwapFloat32(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
799 void SwapFloat32(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
800 DoubleRegister scratch_1);
801 void SwapDouble(DoubleRegister src, DoubleRegister dst,
802 DoubleRegister scratch);
803 void SwapDouble(DoubleRegister src, MemOperand dst, DoubleRegister scratch);
804 void SwapDouble(MemOperand src, MemOperand dst, DoubleRegister scratch_0,
805 DoubleRegister scratch_1);
809 void CleanseP(Register src) {
810 #if (V8_HOST_ARCH_S390 && !(V8_TARGET_ARCH_S390X)) 811 nilh(src, Operand(0x7FFF));
815 void PrepareForTailCall(
const ParameterCount& callee_args_count,
816 Register caller_args_count_reg, Register scratch0,
824 void CallRuntimeWithCEntry(Runtime::FunctionId fid, Register centry);
836 void PrepareCallCFunction(
int num_reg_arguments,
int num_double_registers,
838 void PrepareCallCFunction(
int num_reg_arguments, Register scratch);
844 void MovToFloatParameter(DoubleRegister src);
845 void MovToFloatParameters(DoubleRegister src1, DoubleRegister src2);
846 void MovToFloatResult(DoubleRegister src);
853 void CallCFunction(ExternalReference
function,
int num_arguments);
854 void CallCFunction(Register
function,
int num_arguments);
855 void CallCFunction(ExternalReference
function,
int num_reg_arguments,
856 int num_double_arguments);
857 void CallCFunction(Register
function,
int num_reg_arguments,
858 int num_double_arguments);
860 void MovFromFloatParameter(DoubleRegister dst);
861 void MovFromFloatResult(DoubleRegister dst);
865 void TruncateDoubleToI(Isolate* isolate, Zone* zone, Register result,
866 DoubleRegister double_input, StubCallMode stub_mode);
867 void TryInlineTruncateDoubleToI(Register result, DoubleRegister double_input,
875 void Assert(Condition cond, AbortReason reason, CRegister cr = cr7);
878 void Check(Condition cond, AbortReason reason, CRegister cr = cr7);
881 void Abort(AbortReason reason);
883 inline bool AllowThisStubCall(CodeStub* stub);
893 inline void ExtractBitRange(Register dst, Register src,
int rangeStart,
895 DCHECK(rangeStart >= rangeEnd && rangeStart < kBitsPerSystemPointer);
898 if (CpuFeatures::IsSupported(GENERAL_INSTR_EXT)) {
899 int shiftAmount = (64 - rangeEnd) % 64;
901 int startBit = 63 - rangeStart + rangeEnd;
902 RotateInsertSelectBits(dst, src, Operand(startBit), Operand(endBit),
903 Operand(shiftAmount),
true);
906 ShiftRightP(dst, src, Operand(rangeEnd));
909 int width = rangeStart - rangeEnd + 1;
910 #if V8_TARGET_ARCH_S390X 911 uint64_t mask = (
static_cast<uint64_t
>(1) << width) - 1;
912 nihf(dst, Operand(mask >> 32));
913 nilf(dst, Operand(mask & 0xFFFFFFFF));
917 AndP(dst, Operand(mask));
922 inline void ExtractBit(Register dst, Register src,
uint32_t bitNumber) {
923 ExtractBitRange(dst, src, bitNumber, bitNumber);
928 inline void ExtractBitMask(Register dst, Register src,
uintptr_t mask,
929 RCBit rc = LeaveRC) {
930 int start = kBitsPerSystemPointer - 1;
934 while (bit && (mask & bit) == 0) {
941 while (bit && (mask & bit)) {
947 DCHECK(bit == 0 || (mask & ((bit << 1) - 1)) == 0);
949 ExtractBitRange(dst, src, start, end);
953 inline void TestBit(Register value,
int bitNumber, Register scratch = r0) {
954 ExtractBitRange(scratch, value, bitNumber, bitNumber);
959 inline void TestBitRange(Register value,
int rangeStart,
int rangeEnd,
960 Register scratch = r0) {
961 ExtractBitRange(scratch, value, rangeStart, rangeEnd);
965 inline void TestBitMask(Register value,
uintptr_t mask,
966 Register scratch = r0) {
967 ExtractBitMask(scratch, value, mask, SetRC);
969 inline void TestIfSmi(Register value) { tmll(value, Operand(1)); }
971 inline void TestIfSmi(MemOperand value) {
972 if (is_uint12(value.offset())) {
973 tm(value, Operand(1));
974 }
else if (is_int20(value.offset())) {
975 tmy(value, Operand(1));
978 tmll(r0, Operand(1));
982 inline void TestIfInt32(Register value) {
986 void SmiUntag(Register reg,
int scale = 0) { SmiUntag(reg, reg, scale); }
988 void SmiUntag(Register dst, Register src,
int scale = 0) {
989 if (scale > kSmiShift) {
990 ShiftLeftP(dst, src, Operand(scale - kSmiShift));
991 }
else if (scale < kSmiShift) {
992 ShiftRightArithP(dst, src, Operand(kSmiShift - scale));
999 void EnterFrame(StackFrame::Type type,
1000 bool load_constant_pool_pointer_reg =
false);
1002 int LeaveFrame(StackFrame::Type type,
int stack_adjustment = 0);
1004 void CheckPageFlag(Register
object, Register scratch,
int mask, Condition cc,
1005 Label* condition_met);
1007 void ResetSpeculationPoisonRegister();
1008 void ComputeCodeStartAddress(Register dst);
1011 static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
1013 void CallCFunctionHelper(Register
function,
int num_reg_arguments,
1014 int num_double_arguments);
1016 void CallRecordWriteStub(Register
object, Register address,
1017 RememberedSetAction remembered_set_action,
1018 SaveFPRegsMode fp_mode, Handle<Code> code_target,
1019 Address wasm_target);
1021 void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
1022 int CalculateStackPassedWords(
int num_reg_arguments,
1023 int num_double_arguments);
1027 class MacroAssembler :
public TurboAssembler {
1029 MacroAssembler(
const AssemblerOptions& options,
void* buffer,
int size)
1030 : TurboAssembler(options, buffer, size) {}
1032 MacroAssembler(Isolate* isolate,
void* buffer,
int size,
1033 CodeObjectRequired create_code_object)
1034 : MacroAssembler(isolate, AssemblerOptions::Default(isolate), buffer,
1035 size, create_code_object) {}
1037 MacroAssembler(Isolate* isolate,
const AssemblerOptions& options,
1038 void* buffer,
int size, CodeObjectRequired create_code_object);
1041 void TailCallStub(CodeStub* stub, Condition cond = al);
1043 void CallStub(CodeStub* stub, Condition cond = al);
1044 void CallRuntime(
const Runtime::Function* f,
int num_arguments,
1045 SaveFPRegsMode save_doubles = kDontSaveFPRegs);
1046 void CallRuntimeSaveDoubles(Runtime::FunctionId fid) {
1047 const Runtime::Function*
function = Runtime::FunctionForId(fid);
1048 CallRuntime(
function, function->nargs, kSaveFPRegs);
1052 void CallRuntime(Runtime::FunctionId fid,
1053 SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1054 const Runtime::Function*
function = Runtime::FunctionForId(fid);
1055 CallRuntime(
function, function->nargs, save_doubles);
1059 void CallRuntime(Runtime::FunctionId fid,
int num_arguments,
1060 SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1061 CallRuntime(Runtime::FunctionForId(fid), num_arguments, save_doubles);
1065 void TailCallRuntime(Runtime::FunctionId fid);
1078 void CompareObjectType(Register heap_object, Register map, Register type_reg,
1084 void CompareInstanceType(Register map, Register type_reg, InstanceType type);
1088 void CompareRoot(Register obj, RootIndex index);
1089 void PushRoot(RootIndex index) {
1090 LoadRoot(r0, index);
1095 void JumpToExternalReference(
const ExternalReference& builtin,
1096 bool builtin_exit_frame =
false);
1099 void JumpToInstructionStream(Address entry);
1102 void JumpIfRoot(Register with, RootIndex index, Label* if_equal) {
1103 CompareRoot(with, index);
1108 void JumpIfNotRoot(Register with, RootIndex index, Label* if_not_equal) {
1109 CompareRoot(with, index);
1115 void TryDoubleToInt32Exact(Register result, DoubleRegister double_input,
1116 Register scratch, DoubleRegister double_scratch);
1120 void LoadWeakValue(Register out, Register in, Label* target_if_cleared);
1125 void IncrementCounter(StatsCounter* counter,
int value, Register scratch1,
1127 void DecrementCounter(StatsCounter* counter,
int value, Register scratch1,
1144 void InvokeFunctionCode(Register
function, Register new_target,
1145 const ParameterCount& expected,
1146 const ParameterCount& actual, InvokeFlag flag);
1149 void CheckDebugHook(Register fun, Register new_target,
1150 const ParameterCount& expected,
1151 const ParameterCount& actual);
1155 void InvokeFunction(Register
function, Register new_target,
1156 const ParameterCount& actual, InvokeFlag flag);
1158 void InvokeFunction(Register
function,
const ParameterCount& expected,
1159 const ParameterCount& actual, InvokeFlag flag);
1162 void MaybeDropFrames();
1167 void PushStackHandler();
1171 void PopStackHandler();
1176 void EnterExitFrame(
bool save_doubles,
int stack_space = 1,
1177 StackFrame::Type frame_type = StackFrame::EXIT);
1182 void LeaveExitFrame(
bool save_doubles, Register argument_count,
1183 bool argument_count_is_length =
false);
1186 void LoadGlobalProxy(Register dst) {
1187 LoadNativeContextSlot(Context::GLOBAL_PROXY_INDEX, dst);
1190 void LoadNativeContextSlot(
int index, Register dst);
1196 void SmiTag(Register reg) { SmiTag(reg, reg); }
1197 void SmiTag(Register dst, Register src) {
1198 ShiftLeftP(dst, src, Operand(kSmiShift));
1201 void SmiToPtrArrayOffset(Register dst, Register src) {
1202 #if V8_TARGET_ARCH_S390X 1203 STATIC_ASSERT(kSmiTag == 0 && kSmiShift > kPointerSizeLog2);
1204 ShiftRightArithP(dst, src, Operand(kSmiShift - kPointerSizeLog2));
1206 STATIC_ASSERT(kSmiTag == 0 && kSmiShift < kPointerSizeLog2);
1207 ShiftLeftP(dst, src, Operand(kPointerSizeLog2 - kSmiShift));
1213 void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1216 inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
1218 bne(not_smi_label );
1221 void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
1224 void AssertNotSmi(Register
object);
1225 void AssertSmi(Register
object);
1227 #if V8_TARGET_ARCH_S390X 1230 STATIC_ASSERT(kSmiTag == 0);
1231 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
1233 #if V8_TARGET_LITTLE_ENDIAN 1234 #define SmiWordOffset(offset) (offset + kPointerSize / 2) 1236 #define SmiWordOffset(offset) offset 1240 void AssertConstructor(Register
object, Register scratch);
1243 void AssertFunction(Register
object);
1247 void AssertBoundFunction(Register
object);
1251 void AssertGeneratorObject(Register
object);
1255 void AssertUndefinedOrAllocationSite(Register
object, Register scratch);
1257 template <
typename Field>
1258 void DecodeField(Register dst, Register src) {
1259 ExtractBitRange(dst, src, Field::kShift + Field::kSize - 1, Field::kShift);
1262 template <
typename Field>
1263 void DecodeField(Register reg) {
1264 DecodeField<Field>(reg, reg);
1270 void IncrementalMarkingRecordWriteHelper(Register
object, Register value,
1273 void CallJSEntry(Register target);
1274 static int CallSizeNotPredictableCodeSize(Address target,
1275 RelocInfo::Mode rmode,
1276 Condition cond = al);
1277 void JumpToJSEntry(Register target);
1284 void RecordWriteField(
1285 Register
object,
int offset, Register value, Register scratch,
1286 LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
1287 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
1288 SmiCheck smi_check = INLINE_SMI_CHECK);
1294 Register
object, Register address, Register value,
1295 LinkRegisterStatus lr_status, SaveFPRegsMode save_fp,
1296 RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
1297 SmiCheck smi_check = INLINE_SMI_CHECK);
1301 void PushSafepointRegisters();
1302 void PopSafepointRegisters();
1304 void LoadRepresentation(Register dst,
const MemOperand& mem, Representation r,
1305 Register scratch = no_reg);
1306 void StoreRepresentation(Register src,
const MemOperand& mem,
1307 Representation r, Register scratch = no_reg);
1310 static const int kSmiShift = kSmiTagSize + kSmiShiftSize;
1312 void InvokePrologue(
const ParameterCount& expected,
1313 const ParameterCount& actual, Label* done,
1314 bool* definitely_mismatches, InvokeFlag flag);
1317 static int SafepointRegisterStackIndex(
int reg_code);
1321 friend class StandardFrame;
1327 inline MemOperand ContextMemOperand(Register context,
int index = 0) {
1328 return MemOperand(context, Context::SlotOffset(index));
1331 inline MemOperand NativeContextMemOperand() {
1332 return ContextMemOperand(cp, Context::NATIVE_CONTEXT_INDEX);
1335 #define ACCESS_MASM(masm) masm-> 1340 #endif // V8_S390_MACRO_ASSEMBLER_S390_H_