[vm] Switch FAR_TMP to X7 for compatibility with Zicfilp.
When enabled, indirect calls and jumps must set X7 to a label value that matches the label in a so-called landing pad at the call target. This check does not apply if the indirect call is made through X1/RA, X5/RA2 or X7/T2, with the expectation that the compiler will limit use of these registers for logically direct calls like an AUPIC+JALR pair, or for software guarded branches like a bounds-checked jump table. We use FAR_TMP for logically direct jumps that exceed J-type range, and blocking it from register allocation limits the availablity of gadgets that set X7. Compare x64's IBT and arm64's BTI. TEST=ci Change-Id: Ic00195eb3c04cc10379f9965e05ef84052e02933 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494861 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
5a97aee690
commit
af43c1a3d4
@@ -174,7 +174,7 @@ void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
Label loop, done;
|
||||
__ lx(T0, Address(SP, 3 * target::kWordSize)); // src_digits
|
||||
__ lx(T1, Address(SP, 2 * target::kWordSize)); // src_used
|
||||
__ lx(T2, Address(SP, 1 * target::kWordSize)); // shift_amount
|
||||
__ lx(S8, Address(SP, 1 * target::kWordSize)); // shift_amount
|
||||
__ lx(T3, Address(SP, 0 * target::kWordSize)); // result_digits
|
||||
|
||||
#if XLEN == 32
|
||||
@@ -185,10 +185,10 @@ void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
__ addi(T1, T1, target::ToRawSmi(1)); // Round up to even
|
||||
__ srai(T1, T1, kSmiTagSize + 1);
|
||||
#endif
|
||||
__ SmiUntag(T2);
|
||||
__ SmiUntag(S8);
|
||||
|
||||
__ srai(T4, T2, target::kBitsPerWordLog2); // T4 = word shift
|
||||
__ andi(T5, T2, target::kBitsPerWord - 1); // T5 = bit shift
|
||||
__ srai(T4, S8, target::kBitsPerWordLog2); // T4 = word shift
|
||||
__ andi(T5, S8, target::kBitsPerWord - 1); // T5 = bit shift
|
||||
__ li(T6, target::kBitsPerWord);
|
||||
__ sub(T6, T6, T5); // T6 = carry bit shift
|
||||
|
||||
@@ -200,22 +200,22 @@ void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
__ slli(TMP, TMP, target::kWordSizeLog2);
|
||||
__ add(T3, T3, TMP); // T3 = &dst_digits[src_used + word_shift]
|
||||
|
||||
__ li(T2, 0); // carry
|
||||
__ li(S8, 0); // carry
|
||||
|
||||
__ Bind(&loop);
|
||||
__ beqz(T1, &done, Assembler::kNearJump);
|
||||
__ lx(TMP, FieldAddress(T0, target::TypedData::payload_offset()));
|
||||
__ srl(TMP2, TMP, T6);
|
||||
__ or_(TMP2, TMP2, T2);
|
||||
__ or_(TMP2, TMP2, S8);
|
||||
__ sx(TMP2, FieldAddress(T3, target::TypedData::payload_offset()));
|
||||
__ sll(T2, TMP, T5);
|
||||
__ sll(S8, TMP, T5);
|
||||
__ subi(T0, T0, target::kWordSize);
|
||||
__ subi(T3, T3, target::kWordSize);
|
||||
__ subi(T1, T1, 1);
|
||||
__ j(&loop);
|
||||
|
||||
__ Bind(&done);
|
||||
__ sx(T2, FieldAddress(T3, target::TypedData::payload_offset()));
|
||||
__ sx(S8, FieldAddress(T3, target::TypedData::payload_offset()));
|
||||
__ LoadObject(A0, NullObject());
|
||||
__ ret();
|
||||
}
|
||||
@@ -228,7 +228,7 @@ void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
Label loop, done;
|
||||
__ lx(T0, Address(SP, 3 * target::kWordSize)); // src_digits
|
||||
__ lx(T1, Address(SP, 2 * target::kWordSize)); // src_used
|
||||
__ lx(T2, Address(SP, 1 * target::kWordSize)); // shift_amount
|
||||
__ lx(S8, Address(SP, 1 * target::kWordSize)); // shift_amount
|
||||
__ lx(T3, Address(SP, 0 * target::kWordSize)); // result_digits
|
||||
|
||||
#if XLEN == 32
|
||||
@@ -239,10 +239,10 @@ void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
__ addi(T1, T1, target::ToRawSmi(1)); // Round up to even
|
||||
__ srai(T1, T1, kSmiTagSize + 1);
|
||||
#endif
|
||||
__ SmiUntag(T2);
|
||||
__ SmiUntag(S8);
|
||||
|
||||
__ srai(T4, T2, target::kBitsPerWordLog2); // T4 = word shift
|
||||
__ andi(T5, T2, target::kBitsPerWord - 1); // T5 = bit shift
|
||||
__ srai(T4, S8, target::kBitsPerWordLog2); // T4 = word shift
|
||||
__ andi(T5, S8, target::kBitsPerWord - 1); // T5 = bit shift
|
||||
__ li(T6, target::kBitsPerWord);
|
||||
__ sub(T6, T6, T5); // T6 = carry bit shift
|
||||
__ sub(T1, T1, T4); // T1 = words to process
|
||||
@@ -250,9 +250,9 @@ void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
__ slli(TMP, T4, target::kWordSizeLog2);
|
||||
__ add(T0, T0, TMP); // T0 = &src_digits[word_shift]
|
||||
|
||||
// T2 = carry
|
||||
__ lx(T2, FieldAddress(T0, target::TypedData::payload_offset()));
|
||||
__ srl(T2, T2, T5);
|
||||
// S8 = carry
|
||||
__ lx(S8, FieldAddress(T0, target::TypedData::payload_offset()));
|
||||
__ srl(S8, S8, T5);
|
||||
__ addi(T0, T0, target::kWordSize);
|
||||
__ subi(T1, T1, 1);
|
||||
|
||||
@@ -260,16 +260,16 @@ void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
|
||||
__ beqz(T1, &done, Assembler::kNearJump);
|
||||
__ lx(TMP, FieldAddress(T0, target::TypedData::payload_offset()));
|
||||
__ sll(TMP2, TMP, T6);
|
||||
__ or_(TMP2, TMP2, T2);
|
||||
__ or_(TMP2, TMP2, S8);
|
||||
__ sx(TMP2, FieldAddress(T3, target::TypedData::payload_offset()));
|
||||
__ srl(T2, TMP, T5);
|
||||
__ srl(S8, TMP, T5);
|
||||
__ addi(T0, T0, target::kWordSize);
|
||||
__ addi(T3, T3, target::kWordSize);
|
||||
__ subi(T1, T1, 1);
|
||||
__ j(&loop);
|
||||
|
||||
__ Bind(&done);
|
||||
__ sx(T2, FieldAddress(T3, target::TypedData::payload_offset()));
|
||||
__ sx(S8, FieldAddress(T3, target::TypedData::payload_offset()));
|
||||
__ LoadObject(A0, NullObject());
|
||||
__ ret();
|
||||
}
|
||||
@@ -283,7 +283,7 @@ void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
|
||||
Label first_loop, second_loop, last_carry, done;
|
||||
__ lx(T0, Address(SP, 4 * target::kWordSize)); // longer_digits
|
||||
__ lx(T1, Address(SP, 3 * target::kWordSize)); // longer_used
|
||||
__ lx(T2, Address(SP, 2 * target::kWordSize)); // shorter_digits
|
||||
__ lx(S8, Address(SP, 2 * target::kWordSize)); // shorter_digits
|
||||
__ lx(T3, Address(SP, 1 * target::kWordSize)); // shorter_used
|
||||
__ lx(T4, Address(SP, 0 * target::kWordSize)); // result_digits
|
||||
|
||||
@@ -303,7 +303,7 @@ void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
|
||||
__ Bind(&first_loop);
|
||||
__ beqz(T3, &second_loop);
|
||||
__ lx(A0, FieldAddress(T0, target::TypedData::payload_offset()));
|
||||
__ lx(A1, FieldAddress(T2, target::TypedData::payload_offset()));
|
||||
__ lx(A1, FieldAddress(S8, target::TypedData::payload_offset()));
|
||||
__ add(A0, A0, A1);
|
||||
__ sltu(TMP, A0, A1); // Carry
|
||||
__ add(A0, A0, T5);
|
||||
@@ -311,7 +311,7 @@ void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
|
||||
__ add(T5, TMP, TMP2);
|
||||
__ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
|
||||
__ addi(T0, T0, target::kWordSize);
|
||||
__ addi(T2, T2, target::kWordSize);
|
||||
__ addi(S8, S8, target::kWordSize);
|
||||
__ addi(T4, T4, target::kWordSize);
|
||||
__ subi(T1, T1, 1);
|
||||
__ subi(T3, T3, 1);
|
||||
@@ -345,7 +345,7 @@ void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
|
||||
Label first_loop, second_loop, last_borrow, done;
|
||||
__ lx(T0, Address(SP, 4 * target::kWordSize)); // longer_digits
|
||||
__ lx(T1, Address(SP, 3 * target::kWordSize)); // longer_used
|
||||
__ lx(T2, Address(SP, 2 * target::kWordSize)); // shorter_digits
|
||||
__ lx(S8, Address(SP, 2 * target::kWordSize)); // shorter_digits
|
||||
__ lx(T3, Address(SP, 1 * target::kWordSize)); // shorter_used
|
||||
__ lx(T4, Address(SP, 0 * target::kWordSize)); // result_digits
|
||||
|
||||
@@ -365,7 +365,7 @@ void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
|
||||
__ Bind(&first_loop);
|
||||
__ beqz(T3, &second_loop);
|
||||
__ lx(A0, FieldAddress(T0, target::TypedData::payload_offset()));
|
||||
__ lx(A1, FieldAddress(T2, target::TypedData::payload_offset()));
|
||||
__ lx(A1, FieldAddress(S8, target::TypedData::payload_offset()));
|
||||
__ sltu(TMP, A0, A1); // Borrow
|
||||
__ sub(A0, A0, A1);
|
||||
__ sltu(TMP2, A0, T5); // Borrow
|
||||
@@ -373,7 +373,7 @@ void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
|
||||
__ add(T5, TMP, TMP2);
|
||||
__ sx(A0, FieldAddress(T4, target::TypedData::payload_offset()));
|
||||
__ addi(T0, T0, target::kWordSize);
|
||||
__ addi(T2, T2, target::kWordSize);
|
||||
__ addi(S8, S8, target::kWordSize);
|
||||
__ addi(T4, T4, target::kWordSize);
|
||||
__ subi(T1, T1, 1);
|
||||
__ subi(T3, T3, 1);
|
||||
@@ -434,7 +434,7 @@ void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
|
||||
Label done;
|
||||
__ lx(T0, Address(SP, 6 * target::kWordSize)); // x_digits
|
||||
__ lx(T1, Address(SP, 5 * target::kWordSize)); // xi
|
||||
__ lx(T2, Address(SP, 4 * target::kWordSize)); // m_digits
|
||||
__ lx(S8, Address(SP, 4 * target::kWordSize)); // m_digits
|
||||
__ lx(T3, Address(SP, 3 * target::kWordSize)); // i
|
||||
__ lx(T4, Address(SP, 2 * target::kWordSize)); // a_digits
|
||||
__ lx(T5, Address(SP, 1 * target::kWordSize)); // j
|
||||
@@ -461,7 +461,7 @@ void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
|
||||
// R4 = mip = &m_digits[i >> 1]
|
||||
// R0 = i as Smi, R1 = m_digits.
|
||||
__ slli(T3, T3, 1);
|
||||
__ add(T2, T2, T3);
|
||||
__ add(S8, S8, T3);
|
||||
|
||||
// R5 = ajp = &a_digits[j >> 1]
|
||||
// R0 = j as Smi, R1 = a_digits.
|
||||
@@ -474,15 +474,15 @@ void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
|
||||
Label muladd_loop;
|
||||
__ Bind(&muladd_loop);
|
||||
// x: T0
|
||||
// mip: T2
|
||||
// mip: S8
|
||||
// ajp: T4
|
||||
// c: T1
|
||||
// n: T6
|
||||
// t: A7:A6 (not live at loop entry)
|
||||
|
||||
// uint64_t mi = *mip++
|
||||
__ lx(A0, FieldAddress(T2, target::TypedData::payload_offset()));
|
||||
__ addi(T2, T2, target::kWordSize);
|
||||
__ lx(A0, FieldAddress(S8, target::TypedData::payload_offset()));
|
||||
__ addi(S8, S8, target::kWordSize);
|
||||
|
||||
// uint64_t aj = *ajp
|
||||
__ lx(A1, FieldAddress(T4, target::TypedData::payload_offset()));
|
||||
@@ -564,18 +564,18 @@ void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
|
||||
// return 2;
|
||||
// }
|
||||
|
||||
// T2 = xip = &x_digits[i >> 1]
|
||||
// S8 = xip = &x_digits[i >> 1]
|
||||
// T0 = i as Smi, T1 = x_digits
|
||||
__ lx(T0, Address(SP, 2 * target::kWordSize));
|
||||
__ lx(T1, Address(SP, 3 * target::kWordSize));
|
||||
__ slli(TMP, T0, 1);
|
||||
__ add(T1, T1, TMP);
|
||||
__ addi(T2, T1, target::TypedData::payload_offset() - kHeapObjectTag);
|
||||
__ addi(S8, T1, target::TypedData::payload_offset() - kHeapObjectTag);
|
||||
|
||||
// T1 = x = *xip++, return if x == 0
|
||||
Label x_zero;
|
||||
__ lx(T1, Address(T2, 0));
|
||||
__ addi(T2, T2, target::kWordSize);
|
||||
__ lx(T1, Address(S8, 0));
|
||||
__ addi(S8, S8, target::kWordSize);
|
||||
__ beqz(T1, &x_zero);
|
||||
|
||||
// T3 = ajp = &a_digits[i]
|
||||
@@ -616,15 +616,15 @@ void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
|
||||
|
||||
__ Bind(&loop);
|
||||
// x: T1
|
||||
// xip: T2
|
||||
// xip: S8
|
||||
// ajp: T3
|
||||
// c: T5:T4
|
||||
// t: T0:A1:A0 (not live at loop entry)
|
||||
// n: T6
|
||||
|
||||
// uint64_t xi = *xip++
|
||||
__ lx(T0, Address(T2, 0));
|
||||
__ addi(T2, T2, target::kWordSize);
|
||||
__ lx(T0, Address(S8, 0));
|
||||
__ addi(S8, S8, target::kWordSize);
|
||||
|
||||
// uint192_t t = T0:A1:A0 = 2*x*xi + aj + c
|
||||
__ mul(A0, T0, T1); // A0 = low64(T0*T1) = low64(x*xi).
|
||||
@@ -747,10 +747,10 @@ void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
|
||||
__ add(T1, T1, TMP);
|
||||
#if XLEN == 32
|
||||
// EBX = dp = &digits[i >> 1]
|
||||
__ lx(T2, FieldAddress(T1, target::TypedData::payload_offset()));
|
||||
__ lx(S8, FieldAddress(T1, target::TypedData::payload_offset()));
|
||||
#else
|
||||
// T2 = dh = digits[(i >> 1) - 1 .. i >> 1]
|
||||
__ lx(T2, FieldAddress(T1, target::TypedData::payload_offset() -
|
||||
// S8 = dh = digits[(i >> 1) - 1 .. i >> 1]
|
||||
__ lx(S8, FieldAddress(T1, target::TypedData::payload_offset() -
|
||||
kBytesPerBigIntDigit));
|
||||
#endif
|
||||
|
||||
@@ -759,7 +759,7 @@ void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
|
||||
|
||||
// Return qd if dh == yt
|
||||
Label return_qd;
|
||||
__ beq(T2, T3, &return_qd);
|
||||
__ beq(S8, T3, &return_qd);
|
||||
|
||||
#if XLEN == 32
|
||||
// EAX = dl = dp[-1]
|
||||
@@ -775,19 +775,19 @@ void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
|
||||
__ srli(T5, T3, target::kWordSize * 4);
|
||||
|
||||
// T6 = qh = dh / yth
|
||||
__ divu(T6, T2, T5);
|
||||
__ divu(T6, S8, T5);
|
||||
|
||||
// A6:A1 = ph:pl = yt*qh
|
||||
__ mulhu(A6, T3, T6);
|
||||
__ mul(A1, T3, T6);
|
||||
|
||||
// A7 = tl = (dh << 32)|(dl >> 32)
|
||||
__ slli(A7, T2, target::kWordSize * 4);
|
||||
__ slli(A7, S8, target::kWordSize * 4);
|
||||
__ srli(TMP, T1, target::kWordSize * 4);
|
||||
__ or_(A7, A7, TMP);
|
||||
|
||||
// S3 = th = dh >> 32
|
||||
__ srli(S3, T2, target::kWordSize * 4);
|
||||
__ srli(S3, S8, target::kWordSize * 4);
|
||||
|
||||
// while ((ph > th) || ((ph == th) && (pl > tl)))
|
||||
Label qh_adj_loop, qh_adj, qh_ok;
|
||||
@@ -830,10 +830,10 @@ void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
|
||||
__ sub(T1, T1, A7);
|
||||
|
||||
// dh -= th
|
||||
__ sub(T2, T2, S3);
|
||||
__ sub(S8, S8, S3);
|
||||
|
||||
// T6 = ql = ((dh << 32)|(dl >> 32)) / yth
|
||||
__ slli(T6, T2, target::kWordSize * 4);
|
||||
__ slli(T6, S8, target::kWordSize * 4);
|
||||
__ srli(TMP, T1, target::kWordSize * 4);
|
||||
__ or_(T6, T6, TMP);
|
||||
__ divu(T6, T6, T5);
|
||||
@@ -845,8 +845,8 @@ void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
|
||||
// while ((ph > dh) || ((ph == dh) && (pl > dl))) {
|
||||
Label ql_adj_loop, ql_adj, ql_ok;
|
||||
__ Bind(&ql_adj_loop);
|
||||
__ bgtu(A6, T2, &ql_adj);
|
||||
__ bne(A6, T2, &ql_ok);
|
||||
__ bgtu(A6, S8, &ql_adj);
|
||||
__ bne(A6, S8, &ql_ok);
|
||||
__ bleu(A1, T1, &ql_ok);
|
||||
|
||||
__ Bind(&ql_adj);
|
||||
@@ -890,15 +890,15 @@ void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
|
||||
|
||||
__ lx(T0, Address(SP, 2 * target::kWordSize)); // args
|
||||
__ lx(T1, Address(SP, 1 * target::kWordSize)); // digits
|
||||
__ lx(T2, Address(SP, 0 * target::kWordSize)); // i as Smi
|
||||
__ lx(S8, Address(SP, 0 * target::kWordSize)); // i as Smi
|
||||
|
||||
// T3 = rho = args[2..3]
|
||||
__ lx(T3, FieldAddress(T0, target::TypedData::payload_offset() +
|
||||
2 * kBytesPerBigIntDigit));
|
||||
|
||||
// T4 = digits[i >> 1 .. (i >> 1) + 1]
|
||||
__ slli(T2, T2, 1);
|
||||
__ add(T1, T1, T2);
|
||||
__ slli(S8, S8, 1);
|
||||
__ add(T1, T1, S8);
|
||||
__ lx(T4, FieldAddress(T1, target::TypedData::payload_offset()));
|
||||
|
||||
// T5 = rho*d mod DIGIT_BASE
|
||||
@@ -1243,12 +1243,12 @@ void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
|
||||
__ ret();
|
||||
|
||||
__ Bind(&use_declaration_type);
|
||||
__ LoadClassById(T2, A1);
|
||||
__ lh(T3, FieldAddress(T2, target::Class::num_type_arguments_offset()));
|
||||
__ LoadClassById(S8, A1);
|
||||
__ lh(T3, FieldAddress(S8, target::Class::num_type_arguments_offset()));
|
||||
__ bnez(T3, normal_ir_body, Assembler::kNearJump);
|
||||
|
||||
__ LoadCompressed(A0,
|
||||
FieldAddress(T2, target::Class::declaration_type_offset()));
|
||||
FieldAddress(S8, target::Class::declaration_type_offset()));
|
||||
__ beq(A0, NULL_REG, normal_ir_body, Assembler::kNearJump);
|
||||
__ ret();
|
||||
|
||||
@@ -1335,12 +1335,12 @@ void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
|
||||
Label* normal_ir_body) {
|
||||
__ lx(A0, Address(SP, 1 * target::kWordSize));
|
||||
__ lx(A1, Address(SP, 0 * target::kWordSize));
|
||||
__ LoadClassIdMayBeSmi(T2, A1);
|
||||
__ LoadClassIdMayBeSmi(S8, A1);
|
||||
__ LoadClassIdMayBeSmi(A1, A0);
|
||||
|
||||
Label equal_may_be_generic, equal, not_equal;
|
||||
EquivalentClassIds(assembler, normal_ir_body, &equal_may_be_generic, &equal,
|
||||
¬_equal, A1, T2, TMP,
|
||||
¬_equal, A1, S8, TMP,
|
||||
/* testing_instance_cids = */ true);
|
||||
|
||||
__ Bind(&equal_may_be_generic);
|
||||
@@ -1486,10 +1486,10 @@ void AsmIntrinsifier::Object_getHash(Assembler* assembler,
|
||||
|
||||
__ Bind(¬_yet_computed);
|
||||
__ LoadFromOffset(A1, THR, target::Thread::random_offset());
|
||||
__ AndImmediate(T2, A1, 0xffffffff); // state_lo
|
||||
__ AndImmediate(S8, A1, 0xffffffff); // state_lo
|
||||
__ srli(T3, A1, 32); // state_hi
|
||||
__ LoadImmediate(A1, 0xffffda61); // A
|
||||
__ mul(A1, A1, T2);
|
||||
__ mul(A1, A1, S8);
|
||||
__ add(A1, A1, T3); // new_state = (A * state_lo) + state_hi
|
||||
__ StoreToOffset(A1, THR, target::Thread::random_offset());
|
||||
__ AndImmediate(A1, A1, 0x3fffffff);
|
||||
@@ -1501,11 +1501,11 @@ void AsmIntrinsifier::Object_getHash(Assembler* assembler,
|
||||
|
||||
Label retry, already_set_in_r4;
|
||||
__ Bind(&retry);
|
||||
__ lrx(T2, Address(A0, 0));
|
||||
__ srli(T4, T2, target::UntaggedObject::kHashTagPos);
|
||||
__ lrx(S8, Address(A0, 0));
|
||||
__ srli(T4, S8, target::UntaggedObject::kHashTagPos);
|
||||
__ bnez(T4, &already_set_in_r4);
|
||||
__ or_(T2, T2, T3);
|
||||
__ scx(T4, T2, Address(A0, 0));
|
||||
__ or_(S8, S8, T3);
|
||||
__ scx(T4, S8, Address(A0, 0));
|
||||
__ bnez(T4, &retry);
|
||||
// Fall-through with A1 containing new hash value (untagged).
|
||||
__ SmiTag(A0, A1);
|
||||
@@ -1526,17 +1526,17 @@ void GenerateSubstringMatchesSpecialization(Assembler* assembler,
|
||||
T1, FieldAddress(A0, target::String::length_offset())); // this.length
|
||||
__ SmiUntag(T1);
|
||||
__ LoadCompressedSmi(
|
||||
T2, FieldAddress(A1, target::String::length_offset())); // other.length
|
||||
__ SmiUntag(T2);
|
||||
S8, FieldAddress(A1, target::String::length_offset())); // other.length
|
||||
__ SmiUntag(S8);
|
||||
|
||||
// if (other.length == 0) return true;
|
||||
__ beqz(T2, return_true);
|
||||
__ beqz(S8, return_true);
|
||||
|
||||
// if (start < 0) return false;
|
||||
__ bltz(T0, return_false);
|
||||
|
||||
// if (start + other.length > this.length) return false;
|
||||
__ add(T3, T0, T2);
|
||||
__ add(T3, T0, S8);
|
||||
__ bgt(T3, T1, return_false);
|
||||
|
||||
if (receiver_cid == kOneByteStringCid) {
|
||||
@@ -1572,7 +1572,7 @@ void GenerateSubstringMatchesSpecialization(Assembler* assembler,
|
||||
__ addi(T3, T3, 1);
|
||||
__ addi(A0, A0, receiver_cid == kOneByteStringCid ? 1 : 2);
|
||||
__ addi(A1, A1, other_cid == kOneByteStringCid ? 1 : 2);
|
||||
__ blt(T3, T2, &loop);
|
||||
__ blt(T3, S8, &loop);
|
||||
|
||||
__ j(return_true);
|
||||
}
|
||||
@@ -1695,12 +1695,12 @@ void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
|
||||
__ SmiUntag(T0);
|
||||
|
||||
__ mv(T1, ZR);
|
||||
__ addi(T2, A1, target::OneByteString::data_offset() - kHeapObjectTag);
|
||||
__ addi(S8, A1, target::OneByteString::data_offset() - kHeapObjectTag);
|
||||
|
||||
// A1: Instance of OneByteString.
|
||||
// T0: String length, untagged integer.
|
||||
// T1: Loop counter, untagged integer.
|
||||
// T2: String data.
|
||||
// S8: String data.
|
||||
// A0: Hash code, untagged integer.
|
||||
|
||||
Label loop, done;
|
||||
@@ -1708,8 +1708,8 @@ void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
|
||||
__ beq(T1, T0, &done);
|
||||
// Add to hash code: (hash_ is uint32)
|
||||
// Get one characters (ch).
|
||||
__ lbu(T3, Address(T2, 0));
|
||||
__ addi(T2, T2, 1);
|
||||
__ lbu(T3, Address(S8, 0));
|
||||
__ addi(S8, S8, 1);
|
||||
// T3: ch.
|
||||
__ addi(T1, T1, 1);
|
||||
__ CombineHashes(A0, T3);
|
||||
@@ -1854,32 +1854,32 @@ void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
|
||||
// A0: new string as tagged pointer.
|
||||
// Copy string.
|
||||
__ lx(T1, Address(SP, kStringOffset));
|
||||
__ lx(T2, Address(SP, kStartIndexOffset));
|
||||
__ SmiUntag(T2);
|
||||
__ lx(S8, Address(SP, kStartIndexOffset));
|
||||
__ SmiUntag(S8);
|
||||
// Calculate start address.
|
||||
__ add(T1, T1, T2);
|
||||
__ add(T1, T1, S8);
|
||||
|
||||
// T1: Start address to copy from.
|
||||
// T2: Untagged start index.
|
||||
// S8: Untagged start index.
|
||||
__ lx(T0, Address(SP, kEndIndexOffset));
|
||||
__ SmiUntag(T0);
|
||||
__ sub(T0, T0, T2);
|
||||
__ sub(T0, T0, S8);
|
||||
|
||||
// T1: Start address to copy from (untagged).
|
||||
// T0: Untagged number of bytes to copy.
|
||||
// A0: Tagged result string.
|
||||
// T3: Pointer into T1.
|
||||
// T4: Pointer into A0.
|
||||
// T2: Scratch register.
|
||||
// S8: Scratch register.
|
||||
Label loop, done;
|
||||
__ blez(T0, &done, Assembler::kNearJump);
|
||||
__ mv(T3, T1);
|
||||
__ mv(T4, A0);
|
||||
__ Bind(&loop);
|
||||
__ subi(T0, T0, 1);
|
||||
__ lbu(T2, FieldAddress(T3, target::OneByteString::data_offset()));
|
||||
__ lbu(S8, FieldAddress(T3, target::OneByteString::data_offset()));
|
||||
__ addi(T3, T3, 1);
|
||||
__ sb(T2, FieldAddress(T4, target::OneByteString::data_offset()));
|
||||
__ sb(S8, FieldAddress(T4, target::OneByteString::data_offset()));
|
||||
__ addi(T4, T4, 1);
|
||||
__ bgtz(T0, &loop);
|
||||
|
||||
@@ -1947,7 +1947,7 @@ void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
|
||||
__ lx(A0, Address(SP, 1 * target::kWordSize)); // This.
|
||||
__ lx(A1, Address(SP, 0 * target::kWordSize)); // Other.
|
||||
|
||||
StringEquality(assembler, A0, A1, T2, TMP2, A0, normal_ir_body,
|
||||
StringEquality(assembler, A0, A1, S8, TMP2, A0, normal_ir_body,
|
||||
kOneByteStringCid);
|
||||
}
|
||||
|
||||
@@ -1956,7 +1956,7 @@ void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
|
||||
__ lx(A0, Address(SP, 1 * target::kWordSize)); // This.
|
||||
__ lx(A1, Address(SP, 0 * target::kWordSize)); // Other.
|
||||
|
||||
StringEquality(assembler, A0, A1, T2, TMP2, A0, normal_ir_body,
|
||||
StringEquality(assembler, A0, A1, S8, TMP2, A0, normal_ir_body,
|
||||
kTwoByteStringCid);
|
||||
}
|
||||
|
||||
@@ -1975,10 +1975,10 @@ void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
|
||||
__ LoadFromOffset(T0, THR, target::Thread::next_task_id_offset());
|
||||
__ LoadFromOffset(T1, THR, target::Thread::next_task_id_offset() + 4);
|
||||
__ SmiTag(A0, T0); // Ignore loss of precision.
|
||||
__ addi(T2, T0, 1);
|
||||
__ sltu(T3, T2, T0); // Carry.
|
||||
__ addi(S8, T0, 1);
|
||||
__ sltu(T3, S8, T0); // Carry.
|
||||
__ add(T1, T1, T3);
|
||||
__ StoreToOffset(T2, THR, target::Thread::next_task_id_offset());
|
||||
__ StoreToOffset(S8, THR, target::Thread::next_task_id_offset());
|
||||
__ StoreToOffset(T1, THR, target::Thread::next_task_id_offset() + 4);
|
||||
__ ret();
|
||||
#endif
|
||||
|
||||
@@ -4930,10 +4930,10 @@ void Assembler::TransitionGeneratedToNative(Register destination,
|
||||
Register tmp = new_exit_through_ffi;
|
||||
|
||||
#if defined(DEBUG)
|
||||
ASSERT(T2 != TMP2);
|
||||
mv(T2, TMP2); // BranchIf in VerifyInGenerated clobbers TMP2.
|
||||
ASSERT(S8 != TMP2);
|
||||
mv(S8, TMP2); // BranchIf in VerifyInGenerated clobbers TMP2.
|
||||
VerifyInGenerated(tmp);
|
||||
mv(TMP2, T2);
|
||||
mv(TMP2, S8);
|
||||
#endif
|
||||
// Mark that the thread is executing native code.
|
||||
sx(destination, Address(THR, target::Thread::vm_tag_offset()));
|
||||
|
||||
@@ -1071,7 +1071,7 @@ void FlowGraphCompiler::EmitNativeLoad(Register dst,
|
||||
|
||||
Register tmp = kNoRegister;
|
||||
if (dst != T1 && base != T1) tmp = T1;
|
||||
if (dst != T2 && base != T2) tmp = T2;
|
||||
if (dst != S8 && base != S8) tmp = S8;
|
||||
if (dst != T3 && base != T3) tmp = T3;
|
||||
ASSERT(tmp != kNoRegister);
|
||||
if (base == SP) offset += compiler::target::kWordSize;
|
||||
|
||||
@@ -1367,7 +1367,7 @@ void NativeCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
const Register result = locs()->out(0).reg();
|
||||
|
||||
// Pass a pointer to the first argument in R2.
|
||||
__ AddImmediate(T2, SP, (ArgumentCount() - 1) * kWordSize);
|
||||
__ AddImmediate(S8, SP, (ArgumentCount() - 1) * kWordSize);
|
||||
|
||||
// Compute the effective address. When running under the simulator,
|
||||
// this is a redirection address that forces the simulator to call
|
||||
@@ -1629,7 +1629,7 @@ void NativeReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
// The dummy return address is in RA, no need to pop it as on Intel.
|
||||
|
||||
// These can be anything besides the return registers (A0, A1) and THR (S1).
|
||||
const Register vm_tag_reg = T2;
|
||||
const Register vm_tag_reg = S8;
|
||||
const Register old_exit_frame_reg = T3;
|
||||
const Register old_exit_through_ffi_reg = T4;
|
||||
const Register tmp = T5;
|
||||
@@ -2965,7 +2965,7 @@ LocationSummary* AllocateUninitializedContextInstr::MakeLocationSummary(
|
||||
LocationSummary* locs = new (zone) LocationSummary(
|
||||
zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
|
||||
locs->set_temp(0, Location::RegisterLocation(T1));
|
||||
locs->set_temp(1, Location::RegisterLocation(T2));
|
||||
locs->set_temp(1, Location::RegisterLocation(S8));
|
||||
locs->set_temp(2, Location::RegisterLocation(T3));
|
||||
locs->set_out(0, Location::RegisterLocation(A0));
|
||||
return locs;
|
||||
@@ -6933,22 +6933,20 @@ void GotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
LocationSummary* IndirectGotoInstr::MakeLocationSummary(Zone* zone,
|
||||
bool opt) const {
|
||||
const intptr_t kNumInputs = 1;
|
||||
const intptr_t kNumTemps = 2;
|
||||
const intptr_t kNumTemps = 1;
|
||||
|
||||
LocationSummary* summary = new (zone)
|
||||
LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
|
||||
|
||||
summary->set_in(0, Location::RequiresRegister());
|
||||
summary->set_temp(0, Location::RequiresRegister());
|
||||
summary->set_temp(1, Location::RequiresRegister());
|
||||
|
||||
return summary;
|
||||
}
|
||||
|
||||
void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
Register index_reg = locs()->in(0).reg();
|
||||
Register target_address_reg = locs()->temp(0).reg();
|
||||
Register offset_reg = locs()->temp(1).reg();
|
||||
Register offset_reg = locs()->temp(0).reg();
|
||||
|
||||
ASSERT(RequiredInputRepresentation(0) == kTagged);
|
||||
__ LoadObject(offset_reg, offsets_);
|
||||
@@ -6962,9 +6960,9 @@ void IndirectGotoInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
|
||||
intx_t imm = -entry_offset;
|
||||
intx_t lo = ImmLo(imm);
|
||||
intx_t hi = ImmHi(imm);
|
||||
__ auipc(target_address_reg, hi);
|
||||
__ add(target_address_reg, target_address_reg, offset_reg);
|
||||
__ jr(target_address_reg, lo);
|
||||
__ auipc(FAR_TMP, hi);
|
||||
__ add(FAR_TMP, FAR_TMP, offset_reg);
|
||||
__ jr(FAR_TMP, lo);
|
||||
}
|
||||
|
||||
LocationSummary* StrictCompareInstr::MakeLocationSummary(Zone* zone,
|
||||
|
||||
@@ -5298,9 +5298,9 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
|
||||
0x4, 0xc, 0x8, 0x10};
|
||||
static constexpr dart::compiler::target::word
|
||||
Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, 0x2c8, -1, -1, 0x2cc,
|
||||
0x2d0, 0x2d4, -1, -1, -1, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec,
|
||||
0x2f0, 0x2f4, -1, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, -1, -1, -1, 0x2c8,
|
||||
0x2cc, 0x2d0, -1, -1, -1, 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8,
|
||||
0x2ec, 0x2f0, 0x2f4, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x14;
|
||||
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x8;
|
||||
static constexpr dart::compiler::target::word Array_header_size = 0xc;
|
||||
@@ -6074,9 +6074,9 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
|
||||
0x8, 0x18, 0x10, 0x20};
|
||||
static constexpr dart::compiler::target::word
|
||||
Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, 0x590, -1, -1, 0x598,
|
||||
0x5a0, 0x5a8, -1, -1, -1, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0, 0x5d8,
|
||||
0x5e0, 0x5e8, -1, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, -1, -1, -1, 0x590,
|
||||
0x598, 0x5a0, -1, -1, -1, 0x5a8, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0,
|
||||
0x5d8, 0x5e0, 0x5e8, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x28;
|
||||
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
|
||||
static constexpr dart::compiler::target::word Array_header_size = 0x18;
|
||||
@@ -11408,9 +11408,9 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
|
||||
0x4, 0xc, 0x8, 0x10};
|
||||
static constexpr dart::compiler::target::word
|
||||
Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, 0x2c8, -1, -1, 0x2cc,
|
||||
0x2d0, 0x2d4, -1, -1, -1, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec,
|
||||
0x2f0, 0x2f4, -1, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, -1, -1, -1, 0x2c8,
|
||||
0x2cc, 0x2d0, -1, -1, -1, 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8,
|
||||
0x2ec, 0x2f0, 0x2f4, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x14;
|
||||
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x8;
|
||||
static constexpr dart::compiler::target::word Array_header_size = 0xc;
|
||||
@@ -12176,9 +12176,9 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = {
|
||||
0x8, 0x18, 0x10, 0x20};
|
||||
static constexpr dart::compiler::target::word
|
||||
Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, 0x590, -1, -1, 0x598,
|
||||
0x5a0, 0x5a8, -1, -1, -1, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0, 0x5d8,
|
||||
0x5e0, 0x5e8, -1, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, -1, -1, -1, 0x590,
|
||||
0x598, 0x5a0, -1, -1, -1, 0x5a8, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0,
|
||||
0x5d8, 0x5e0, 0x5e8, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
static constexpr dart::compiler::target::word AbstractType_InstanceSize = 0x28;
|
||||
static constexpr dart::compiler::target::word ApiError_InstanceSize = 0x10;
|
||||
static constexpr dart::compiler::target::word Array_header_size = 0x18;
|
||||
@@ -17283,9 +17283,9 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
|
||||
0x4, 0xc, 0x8, 0x10};
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, 0x2c8, -1, -1, 0x2cc,
|
||||
0x2d0, 0x2d4, -1, -1, -1, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec,
|
||||
0x2f0, 0x2f4, -1, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, -1, -1, -1, 0x2c8,
|
||||
0x2cc, 0x2d0, -1, -1, -1, 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8,
|
||||
0x2ec, 0x2f0, 0x2f4, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
|
||||
0x14;
|
||||
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 0x8;
|
||||
@@ -18137,9 +18137,9 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
|
||||
0x8, 0x18, 0x10, 0x20};
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, 0x590, -1, -1, 0x598,
|
||||
0x5a0, 0x5a8, -1, -1, -1, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0, 0x5d8,
|
||||
0x5e0, 0x5e8, -1, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, -1, -1, -1, 0x590,
|
||||
0x598, 0x5a0, -1, -1, -1, 0x5a8, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0,
|
||||
0x5d8, 0x5e0, 0x5e8, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 0x10;
|
||||
@@ -23213,9 +23213,9 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
|
||||
0x4, 0xc, 0x8, 0x10};
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, 0x2c8, -1, -1, 0x2cc,
|
||||
0x2d0, 0x2d4, -1, -1, -1, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8, 0x2ec,
|
||||
0x2f0, 0x2f4, -1, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
-1, -1, -1, -1, -1, 0x2c0, 0x2c4, -1, -1, -1, 0x2c8,
|
||||
0x2cc, 0x2d0, -1, -1, -1, 0x2d4, 0x2d8, 0x2dc, 0x2e0, 0x2e4, 0x2e8,
|
||||
0x2ec, 0x2f0, 0x2f4, -1, -1, -1, 0x2f8, 0x2fc, 0x300, 0x304};
|
||||
static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
|
||||
0x14;
|
||||
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 0x8;
|
||||
@@ -24058,9 +24058,9 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = {
|
||||
0x8, 0x18, 0x10, 0x20};
|
||||
static constexpr dart::compiler::target::word
|
||||
AOT_Thread_write_barrier_wrappers_thread_offset[] = {
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, 0x590, -1, -1, 0x598,
|
||||
0x5a0, 0x5a8, -1, -1, -1, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0, 0x5d8,
|
||||
0x5e0, 0x5e8, -1, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
-1, -1, -1, -1, -1, 0x580, 0x588, -1, -1, -1, 0x590,
|
||||
0x598, 0x5a0, -1, -1, -1, 0x5a8, 0x5b0, 0x5b8, 0x5c0, 0x5c8, 0x5d0,
|
||||
0x5d8, 0x5e0, 0x5e8, -1, -1, -1, 0x5f0, 0x5f8, 0x600, 0x608};
|
||||
static constexpr dart::compiler::target::word AOT_AbstractType_InstanceSize =
|
||||
0x28;
|
||||
static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 0x10;
|
||||
|
||||
@@ -111,18 +111,18 @@ void StubCodeCompiler::GenerateCallToRuntimeStub() {
|
||||
ASSERT(thread_offset == 0 * target::kWordSize);
|
||||
ASSERT(argc_tag_offset == 1 * target::kWordSize);
|
||||
ASSERT(argv_offset == 2 * target::kWordSize);
|
||||
__ slli(T2, T4, target::kWordSizeLog2);
|
||||
__ add(T2, FP, T2); // Compute argv.
|
||||
__ slli(S8, T4, target::kWordSizeLog2);
|
||||
__ add(S8, FP, S8); // Compute argv.
|
||||
// Set argv in target::NativeArguments.
|
||||
__ AddImmediate(T2,
|
||||
__ AddImmediate(S8,
|
||||
target::frame_layout.param_end_from_fp * target::kWordSize);
|
||||
|
||||
ASSERT(retval_offset == 3 * target::kWordSize);
|
||||
__ AddImmediate(T3, T2, target::kWordSize);
|
||||
__ AddImmediate(T3, S8, target::kWordSize);
|
||||
|
||||
__ StoreToOffset(THR, SP, thread_offset);
|
||||
__ StoreToOffset(T4, SP, argc_tag_offset);
|
||||
__ StoreToOffset(T2, SP, argv_offset);
|
||||
__ StoreToOffset(S8, SP, argv_offset);
|
||||
__ StoreToOffset(T3, SP, retval_offset);
|
||||
__ mv(A0, SP); // Pass the pointer to the target::NativeArguments.
|
||||
|
||||
@@ -266,9 +266,9 @@ void StubCodeCompiler::GenerateCallNativeThroughSafepointStub() {
|
||||
|
||||
#if defined(DEBUG)
|
||||
// Check SP alignment.
|
||||
__ andi(T2 /*volatile*/, SP, ~(OS::ActivationFrameAlignment() - 1));
|
||||
__ andi(S8 /*volatile*/, SP, ~(OS::ActivationFrameAlignment() - 1));
|
||||
Label done;
|
||||
__ beq(T2, SP, &done);
|
||||
__ beq(S8, SP, &done);
|
||||
__ Breakpoint();
|
||||
__ Bind(&done);
|
||||
#endif
|
||||
@@ -408,7 +408,7 @@ void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
|
||||
|
||||
__ jalr(T1);
|
||||
__ mv(THR, A0);
|
||||
__ lx(T2, Address(SP, 0 * target::kWordSize)); // entry_point
|
||||
__ lx(T4, Address(SP, 0 * target::kWordSize)); // entry_point
|
||||
__ lx(T3, Address(SP, 1 * target::kWordSize)); // is_tail
|
||||
__ lx(S2, Address(SP, 2 * target::kWordSize)); // epilogue
|
||||
|
||||
@@ -419,7 +419,7 @@ void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
|
||||
__ bnez(T3, &tail, Assembler::kNearJump);
|
||||
|
||||
{
|
||||
__ jalr(T2); // entry_point
|
||||
__ jalr(T4); // entry_point
|
||||
__ PushRegistersAligned(kReturnRegisterSet, 0);
|
||||
__ mv(A0, THR);
|
||||
__ jalr(S2); // DLRT_ExitSyncCallback, etc
|
||||
@@ -437,7 +437,7 @@ void StubCodeCompiler::GenerateFfiCallbackTrampolineStub() {
|
||||
|
||||
{
|
||||
__ Bind(&tail);
|
||||
__ jalr(T2); // entry_point
|
||||
__ jalr(T4); // entry_point
|
||||
__ mv(A0, THR);
|
||||
__ mv(A1, S2);
|
||||
__ lx(S2, Address(SP, 0 * target::kWordSize));
|
||||
@@ -543,7 +543,7 @@ void StubCodeCompiler::GenerateWriteError(bool with_fpu_regs) {
|
||||
// RA : return address.
|
||||
// SP : address of return value.
|
||||
// T5 : address of the native function to call.
|
||||
// T2 : address of first argument in argument array.
|
||||
// S8 : address of first argument in argument array.
|
||||
// T1 : argc_tag including number of arguments and function kind.
|
||||
static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
|
||||
Address wrapper) {
|
||||
@@ -598,7 +598,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler,
|
||||
// For now, space is reserved on the stack and we pass a pointer to it.
|
||||
__ StoreToOffset(THR, SP, thread_offset);
|
||||
__ StoreToOffset(T1, SP, argc_tag_offset);
|
||||
__ StoreToOffset(T2, SP, argv_offset);
|
||||
__ StoreToOffset(S8, SP, argv_offset);
|
||||
__ StoreToOffset(T3, SP, retval_offset);
|
||||
__ mv(A0, SP); // Pass the pointer to the target::NativeArguments.
|
||||
__ mv(A1, T5); // Pass the function entrypoint to call.
|
||||
@@ -777,22 +777,22 @@ void StubCodeCompiler::GenerateFixParameterizedAllocationStubTargetStub() {
|
||||
}
|
||||
|
||||
// Input parameters:
|
||||
// T2: smi-tagged argument count, may be zero.
|
||||
// S8: smi-tagged argument count, may be zero.
|
||||
// FP[target::frame_layout.param_end_from_fp + 1]: last argument.
|
||||
static void PushArrayOfArguments(Assembler* assembler) {
|
||||
COMPILE_ASSERT(AllocateArrayABI::kLengthReg == T2);
|
||||
COMPILE_ASSERT(AllocateArrayABI::kLengthReg == S8);
|
||||
COMPILE_ASSERT(AllocateArrayABI::kTypeArgumentsReg == T1);
|
||||
|
||||
// Allocate array to store arguments of caller.
|
||||
__ LoadObject(T1, NullObject());
|
||||
// T1: null element type for raw Array.
|
||||
// T2: smi-tagged argument count, may be zero.
|
||||
// S8: smi-tagged argument count, may be zero.
|
||||
__ JumpAndLink(StubCodeAllocateArray());
|
||||
// A0: newly allocated array.
|
||||
// T2: smi-tagged argument count, may be zero (was preserved by the stub).
|
||||
// S8: smi-tagged argument count, may be zero (was preserved by the stub).
|
||||
__ PushRegister(A0); // Array is in A0 and on top of stack.
|
||||
__ SmiUntag(T2);
|
||||
__ slli(T1, T2, target::kWordSizeLog2);
|
||||
__ SmiUntag(S8);
|
||||
__ slli(T1, S8, target::kWordSizeLog2);
|
||||
__ add(T1, T1, FP);
|
||||
__ AddImmediate(T1,
|
||||
target::frame_layout.param_end_from_fp * target::kWordSize);
|
||||
@@ -802,12 +802,12 @@ static void PushArrayOfArguments(Assembler* assembler) {
|
||||
|
||||
Label loop, loop_exit;
|
||||
__ Bind(&loop);
|
||||
__ beqz(T2, &loop_exit);
|
||||
__ beqz(S8, &loop_exit);
|
||||
__ lx(T6, Address(T1, 0));
|
||||
__ addi(T1, T1, -target::kWordSize);
|
||||
__ StoreCompressedIntoObject(A0, Address(T3, 0), T6);
|
||||
__ addi(T3, T3, target::kCompressedWordSize);
|
||||
__ addi(T2, T2, -1);
|
||||
__ addi(S8, S8, -1);
|
||||
__ j(&loop);
|
||||
__ Bind(&loop_exit);
|
||||
}
|
||||
@@ -897,7 +897,7 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
|
||||
} else if (kind == kLazyDeoptFromThrow) {
|
||||
// Restore result into T1 temporarily.
|
||||
__ LoadFromOffset(T1, FP, saved_exception_slot_from_fp * target::kWordSize);
|
||||
__ LoadFromOffset(T2, FP,
|
||||
__ LoadFromOffset(S8, FP,
|
||||
saved_stacktrace_slot_from_fp * target::kWordSize);
|
||||
}
|
||||
|
||||
@@ -915,7 +915,7 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
|
||||
} else if (kind == kLazyDeoptFromThrow) {
|
||||
// Preserve exception as first local.
|
||||
// Preserve stacktrace as second local.
|
||||
__ PushRegistersInOrder({T1, T2});
|
||||
__ PushRegistersInOrder({T1, S8});
|
||||
}
|
||||
{
|
||||
__ mv(A0, FP); // Pass last FP as parameter in R0.
|
||||
@@ -943,7 +943,7 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
|
||||
__ LoadFromOffset(
|
||||
T1, FP, target::frame_layout.first_local_from_fp * target::kWordSize);
|
||||
__ LoadFromOffset(
|
||||
T2, FP,
|
||||
S8, FP,
|
||||
(target::frame_layout.first_local_from_fp - 1) * target::kWordSize);
|
||||
}
|
||||
// Code above cannot cause GC.
|
||||
@@ -963,15 +963,15 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
|
||||
__ PushRegister(CODE_REG);
|
||||
// Preserve exception, it will be GC-d here.
|
||||
// Preserve stacktrace, it will be GC-d here.
|
||||
__ PushRegistersInOrder({T1, T2});
|
||||
__ PushRegistersInOrder({T1, S8});
|
||||
}
|
||||
|
||||
__ PushRegister(ZR); // Space for the result.
|
||||
__ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
|
||||
// Result tells stub how many bytes to remove from the expression stack
|
||||
// of the bottom-most frame. They were used as materialization arguments.
|
||||
__ PopRegister(T2);
|
||||
__ SmiUntag(T2);
|
||||
__ PopRegister(S8);
|
||||
__ SmiUntag(S8);
|
||||
if (kind == kLazyDeoptFromReturn) {
|
||||
__ PopRegister(A0); // Restore result.
|
||||
} else if (kind == kLazyDeoptFromThrow) {
|
||||
@@ -981,7 +981,7 @@ static void GenerateDeoptimizationSequence(Assembler* assembler,
|
||||
}
|
||||
__ LeaveStubFrame();
|
||||
// Remove materialization arguments.
|
||||
__ add(SP, SP, T2);
|
||||
__ add(SP, SP, S8);
|
||||
// The caller is responsible for emitting the return instruction.
|
||||
|
||||
if (kind == kLazyDeoptFromThrow) {
|
||||
@@ -1042,8 +1042,8 @@ static void GenerateNoSuchMethodDispatcherBody(Assembler* assembler) {
|
||||
|
||||
// Load the receiver.
|
||||
__ LoadCompressedSmiFieldFromOffset(
|
||||
T2, ARGS_DESC_REG, target::ArgumentsDescriptor::size_offset());
|
||||
__ AddShifted(TMP, FP, T2, target::kWordSizeLog2 - 1); // T2 is Smi.
|
||||
S8, ARGS_DESC_REG, target::ArgumentsDescriptor::size_offset());
|
||||
__ AddShifted(TMP, FP, S8, target::kWordSizeLog2 - 1); // S8 is Smi.
|
||||
__ LoadFromOffset(A0, TMP,
|
||||
target::frame_layout.param_end_from_fp * target::kWordSize);
|
||||
// Push: result slot, receiver, ICData/MegamorphicCache,
|
||||
@@ -1056,10 +1056,10 @@ static void GenerateNoSuchMethodDispatcherBody(Assembler* assembler) {
|
||||
Label args_count_ok;
|
||||
__ beqz(T3, &args_count_ok, Assembler::kNearJump);
|
||||
// Include the type arguments.
|
||||
__ addi(T2, T2, target::ToRawSmi(1));
|
||||
__ addi(S8, S8, target::ToRawSmi(1));
|
||||
__ Bind(&args_count_ok);
|
||||
|
||||
// T2: Smi-tagged arguments array length.
|
||||
// S8: Smi-tagged arguments array length.
|
||||
PushArrayOfArguments(assembler);
|
||||
const intptr_t kNumArgs = 4;
|
||||
__ CallRuntime(kNoSuchMethodFromCallStubRuntimeEntry, kNumArgs);
|
||||
@@ -1393,13 +1393,13 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub() {
|
||||
Label push_arguments;
|
||||
Label done_push_arguments;
|
||||
__ beqz(T5, &done_push_arguments); // check if there are arguments.
|
||||
__ LoadImmediate(T2, 0);
|
||||
__ LoadImmediate(S8, 0);
|
||||
__ Bind(&push_arguments);
|
||||
__ lx(T3, Address(A2, 0));
|
||||
__ PushRegister(T3);
|
||||
__ addi(T2, T2, 1);
|
||||
__ addi(S8, S8, 1);
|
||||
__ addi(A2, A2, target::kWordSize);
|
||||
__ blt(T2, T5, &push_arguments, compiler::Assembler::kNearJump);
|
||||
__ blt(S8, T5, &push_arguments, compiler::Assembler::kNearJump);
|
||||
__ Bind(&done_push_arguments);
|
||||
|
||||
if (FLAG_precompiled_mode) {
|
||||
@@ -1459,7 +1459,7 @@ void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub() {
|
||||
// Output:
|
||||
// A0: new allocated Context object.
|
||||
// Clobbered:
|
||||
// T2, T3, T4, TMP
|
||||
// S8, T3, T4, TMP
|
||||
static void GenerateAllocateContextSpaceStub(Assembler* assembler,
|
||||
Label* slow_case) {
|
||||
// First compute the rounded instance size.
|
||||
@@ -1467,20 +1467,20 @@ static void GenerateAllocateContextSpaceStub(Assembler* assembler,
|
||||
intptr_t fixed_size_plus_alignment_padding =
|
||||
target::Context::header_size() +
|
||||
target::ObjectAlignment::kObjectAlignment - 1;
|
||||
__ slli(T2, T1, kCompressedWordSizeLog2);
|
||||
__ AddImmediate(T2, fixed_size_plus_alignment_padding);
|
||||
__ andi(T2, T2, ~(target::ObjectAlignment::kObjectAlignment - 1));
|
||||
__ slli(S8, T1, kCompressedWordSizeLog2);
|
||||
__ AddImmediate(S8, fixed_size_plus_alignment_padding);
|
||||
__ andi(S8, S8, ~(target::ObjectAlignment::kObjectAlignment - 1));
|
||||
|
||||
NOT_IN_PRODUCT(__ MaybeTraceAllocation(kContextCid, slow_case, T4));
|
||||
// Now allocate the object.
|
||||
// T1: number of context variables.
|
||||
// T2: object size.
|
||||
// S8: object size.
|
||||
__ lx(A0, Address(THR, target::Thread::top_offset()));
|
||||
__ add(T3, T2, A0);
|
||||
__ add(T3, S8, A0);
|
||||
// Check if the allocation fits into the remaining space.
|
||||
// A0: potential new object.
|
||||
// T1: number of context variables.
|
||||
// T2: object size.
|
||||
// S8: object size.
|
||||
// T3: potential next object start.
|
||||
__ lx(TMP, Address(THR, target::Thread::end_offset()));
|
||||
__ CompareRegisters(T3, TMP);
|
||||
@@ -1491,7 +1491,7 @@ static void GenerateAllocateContextSpaceStub(Assembler* assembler,
|
||||
// next object start and initialize the object.
|
||||
// A0: new object.
|
||||
// T1: number of context variables.
|
||||
// T2: object size.
|
||||
// S8: object size.
|
||||
// T3: next object start.
|
||||
__ sx(T3, Address(THR, target::Thread::top_offset()));
|
||||
__ addi(A0, A0, kHeapObjectTag);
|
||||
@@ -1499,15 +1499,15 @@ static void GenerateAllocateContextSpaceStub(Assembler* assembler,
|
||||
// Calculate the size tag.
|
||||
// A0: new object.
|
||||
// T1: number of context variables.
|
||||
// T2: object size.
|
||||
// S8: object size.
|
||||
const intptr_t shift = target::UntaggedObject::kSizeTagPos -
|
||||
target::ObjectAlignment::kObjectAlignmentLog2;
|
||||
__ li(T3, 0);
|
||||
__ CompareImmediate(T2, target::UntaggedObject::kSizeTagMaxSizeTag);
|
||||
__ CompareImmediate(S8, target::UntaggedObject::kSizeTagMaxSizeTag);
|
||||
// If no size tag overflow, shift R2 left, else set R2 to zero.
|
||||
compiler::Label zero_tag;
|
||||
__ BranchIf(HI, &zero_tag);
|
||||
__ slli(T3, T2, shift);
|
||||
__ slli(T3, S8, shift);
|
||||
__ Bind(&zero_tag);
|
||||
|
||||
// Get the class index and insert it into the tags.
|
||||
@@ -1707,7 +1707,7 @@ COMPILE_ASSERT(kWriteBarrierObjectReg == A0);
|
||||
COMPILE_ASSERT(kWriteBarrierValueReg == A1);
|
||||
COMPILE_ASSERT(kWriteBarrierSlotReg == A6);
|
||||
static void GenerateWriteBarrierStubHelper(Assembler* assembler, bool cards) {
|
||||
RegisterSet spill_set((1 << T2) | (1 << T3) | (1 << T4), 0);
|
||||
RegisterSet spill_set((1 << S8) | (1 << T3) | (1 << T4), 0);
|
||||
|
||||
Label skip_marking;
|
||||
__ lbu(TMP, FieldAddress(A1, target::Object::tags_offset()));
|
||||
@@ -1732,13 +1732,13 @@ static void GenerateWriteBarrierStubHelper(Assembler* assembler, bool cards) {
|
||||
|
||||
auto mark_stack_push = [&](intptr_t offset, const RuntimeEntry& entry) {
|
||||
__ lx(T4, Address(THR, offset));
|
||||
__ lw(T2, Address(T4, target::MarkingStackBlock::top_offset()));
|
||||
__ slli(T3, T2, target::kWordSizeLog2);
|
||||
__ lw(S8, Address(T4, target::MarkingStackBlock::top_offset()));
|
||||
__ slli(T3, S8, target::kWordSizeLog2);
|
||||
__ add(T3, T4, T3);
|
||||
__ sx(A1, Address(T3, target::MarkingStackBlock::pointers_offset()));
|
||||
__ addi(T2, T2, 1);
|
||||
__ sw(T2, Address(T4, target::MarkingStackBlock::top_offset()));
|
||||
__ CompareImmediate(T2, target::MarkingStackBlock::kSize);
|
||||
__ addi(S8, S8, 1);
|
||||
__ sw(S8, Address(T4, target::MarkingStackBlock::top_offset()));
|
||||
__ CompareImmediate(S8, target::MarkingStackBlock::kSize);
|
||||
__ BranchIf(NE, &done);
|
||||
|
||||
{
|
||||
@@ -1798,13 +1798,13 @@ static void GenerateWriteBarrierStubHelper(Assembler* assembler, bool cards) {
|
||||
__ beqz(TMP2, &done); // Was already clear -> lost race.
|
||||
|
||||
__ lx(T4, Address(THR, target::Thread::store_buffer_block_offset()));
|
||||
__ lw(T2, Address(T4, target::StoreBufferBlock::top_offset()));
|
||||
__ slli(T3, T2, target::kWordSizeLog2);
|
||||
__ lw(S8, Address(T4, target::StoreBufferBlock::top_offset()));
|
||||
__ slli(T3, S8, target::kWordSizeLog2);
|
||||
__ add(T3, T4, T3);
|
||||
__ sx(A0, Address(T3, target::StoreBufferBlock::pointers_offset()));
|
||||
__ addi(T2, T2, 1);
|
||||
__ sw(T2, Address(T4, target::StoreBufferBlock::top_offset()));
|
||||
__ CompareImmediate(T2, target::StoreBufferBlock::kSize);
|
||||
__ addi(S8, S8, 1);
|
||||
__ sw(S8, Address(T4, target::StoreBufferBlock::top_offset()));
|
||||
__ CompareImmediate(S8, target::StoreBufferBlock::kSize);
|
||||
__ BranchIf(NE, &done);
|
||||
|
||||
{
|
||||
@@ -2076,8 +2076,8 @@ void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub() {
|
||||
|
||||
// Load the receiver.
|
||||
__ LoadCompressedSmiFieldFromOffset(
|
||||
T2, S4, target::ArgumentsDescriptor::size_offset());
|
||||
__ AddShifted(TMP, FP, T2, target::kWordSizeLog2 - 1); // T2 is Smi
|
||||
S8, S4, target::ArgumentsDescriptor::size_offset());
|
||||
__ AddShifted(TMP, FP, S8, target::kWordSizeLog2 - 1); // S8 is Smi
|
||||
__ LoadFromOffset(A0, TMP,
|
||||
target::frame_layout.param_end_from_fp * target::kWordSize);
|
||||
|
||||
@@ -2093,10 +2093,10 @@ void StubCodeCompiler::GenerateCallClosureNoSuchMethodStub() {
|
||||
Label args_count_ok;
|
||||
__ beqz(T3, &args_count_ok, Assembler::kNearJump);
|
||||
// Include the type arguments.
|
||||
__ addi(T2, T2, target::ToRawSmi(1));
|
||||
__ addi(S8, S8, target::ToRawSmi(1));
|
||||
__ Bind(&args_count_ok);
|
||||
|
||||
// T2: Smi-tagged arguments array length.
|
||||
// S8: Smi-tagged arguments array length.
|
||||
PushArrayOfArguments(assembler);
|
||||
|
||||
const intptr_t kNumArgs = 4;
|
||||
@@ -2317,7 +2317,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
|
||||
__ slli(A7, A7, target::kWordSizeLog2 - kSmiTagSize);
|
||||
__ add(A7, SP, A7);
|
||||
__ lx(A6, Address(A7, -2 * target::kWordSize));
|
||||
__ LoadTaggedClassIdMayBeSmi(T2, A6);
|
||||
__ LoadTaggedClassIdMayBeSmi(S8, A6);
|
||||
}
|
||||
} else {
|
||||
__ LoadFieldFromOffset(ARGS_DESC_REG, IC_DATA_REG,
|
||||
@@ -2330,11 +2330,11 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
|
||||
__ LoadTaggedClassIdMayBeSmi(T1, A6);
|
||||
if (num_args == 2) {
|
||||
__ lx(A6, Address(A7, -2 * target::kWordSize));
|
||||
__ LoadTaggedClassIdMayBeSmi(T2, A6);
|
||||
__ LoadTaggedClassIdMayBeSmi(S8, A6);
|
||||
}
|
||||
}
|
||||
// T1: first argument class ID as Smi.
|
||||
// T2: second argument class ID as Smi.
|
||||
// S8: second argument class ID as Smi.
|
||||
// S4: args descriptor
|
||||
|
||||
// We unroll the generic one that is generated once more than the others.
|
||||
@@ -2354,7 +2354,7 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
|
||||
} else {
|
||||
__ bne(A7, T1, &update); // Continue.
|
||||
__ LoadCompressedSmiFromOffset(A7, A1, target::kCompressedWordSize);
|
||||
__ beq(A7, T2, &found); // Class id match?
|
||||
__ beq(A7, S8, &found); // Class id match?
|
||||
}
|
||||
__ Bind(&update);
|
||||
|
||||
@@ -2446,14 +2446,14 @@ void StubCodeCompiler::GenerateNArgsCheckInlineCacheStub(
|
||||
// Note: UntaggedICData::receivers_static_type_ is guaranteed to be not null
|
||||
// because we only emit calls to this stub when it is not null.
|
||||
__ LoadCompressed(
|
||||
T2, FieldAddress(S5, target::ICData::receivers_static_type_offset()));
|
||||
__ LoadCompressed(T2, FieldAddress(T2, target::Type::arguments_offset()));
|
||||
S8, FieldAddress(S5, target::ICData::receivers_static_type_offset()));
|
||||
__ LoadCompressed(S8, FieldAddress(S8, target::Type::arguments_offset()));
|
||||
// T1 contains an offset to type arguments in words as a smi,
|
||||
// hence TIMES_4. A0 is guaranteed to be non-smi because it is expected
|
||||
// to have type arguments.
|
||||
__ LoadIndexedPayload(TMP, A0, 0, T1, TIMES_COMPRESSED_HALF_WORD_SIZE,
|
||||
kObjectBytes);
|
||||
__ beq(T2, TMP, &call_target_function_through_unchecked_entry);
|
||||
__ beq(S8, TMP, &call_target_function_through_unchecked_entry);
|
||||
|
||||
// Update exactness state (not-exact anymore).
|
||||
__ LoadImmediate(
|
||||
@@ -3144,10 +3144,10 @@ void StubCodeCompiler::GenerateMegamorphicCallStub() {
|
||||
Label cid_loaded;
|
||||
__ Bind(&cid_loaded);
|
||||
__ lx(T1, FieldAddress(IC_DATA_REG, target::MegamorphicCache::mask_offset()));
|
||||
__ lx(T2,
|
||||
__ lx(S8,
|
||||
FieldAddress(IC_DATA_REG, target::MegamorphicCache::buckets_offset()));
|
||||
// T1: mask as a smi - load first to support insertion w/o stopping Dart code.
|
||||
// T2: cache buckets array.
|
||||
// S8: cache buckets array.
|
||||
|
||||
// Make the cid into a smi.
|
||||
__ SmiTag(T5);
|
||||
@@ -3165,7 +3165,7 @@ void StubCodeCompiler::GenerateMegamorphicCallStub() {
|
||||
|
||||
const intptr_t base = target::Array::data_offset();
|
||||
// T3 is smi tagged, but table entries are 16 bytes, so LSL 3.
|
||||
__ AddShifted(TMP, T2, T3, kCompressedWordSizeLog2);
|
||||
__ AddShifted(TMP, S8, T3, kCompressedWordSizeLog2);
|
||||
__ LoadCompressedSmiFieldFromOffset(T4, TMP, base);
|
||||
Label probe_failed;
|
||||
__ CompareObjectRegisters(T4, T5);
|
||||
@@ -3223,9 +3223,9 @@ void StubCodeCompiler::GenerateICCallThroughCodeStub() {
|
||||
// A1: receiver cid as Smi
|
||||
|
||||
__ Bind(&loop);
|
||||
__ LoadCompressedSmi(T2, Address(T1, 0));
|
||||
__ beq(A1, T2, &found);
|
||||
__ CompareImmediate(T2, target::ToRawSmi(kIllegalCid));
|
||||
__ LoadCompressedSmi(S8, Address(T1, 0));
|
||||
__ beq(A1, S8, &found);
|
||||
__ CompareImmediate(S8, target::ToRawSmi(kIllegalCid));
|
||||
__ BranchIf(EQ, &miss);
|
||||
|
||||
const intptr_t entry_length =
|
||||
@@ -3260,19 +3260,19 @@ void StubCodeCompiler::GenerateICCallThroughCodeStub() {
|
||||
// A0: receiver
|
||||
// S5: MonomorphicSmiableCall object
|
||||
//
|
||||
// T1,T2: clobbered
|
||||
// T1,S8: clobbered
|
||||
void StubCodeCompiler::GenerateMonomorphicSmiableCheckStub() {
|
||||
Label miss;
|
||||
__ LoadClassIdMayBeSmi(T1, A0);
|
||||
|
||||
// Note: this stub is only used in AOT mode, hence the direct (bare) call.
|
||||
__ LoadField(
|
||||
T2,
|
||||
S8,
|
||||
FieldAddress(S5, target::MonomorphicSmiableCall::expected_cid_offset()));
|
||||
__ LoadField(
|
||||
TMP,
|
||||
FieldAddress(S5, target::MonomorphicSmiableCall::entrypoint_offset()));
|
||||
__ bne(T1, T2, &miss);
|
||||
__ bne(T1, S8, &miss);
|
||||
__ jr(TMP);
|
||||
|
||||
__ Bind(&miss);
|
||||
@@ -3310,10 +3310,10 @@ void StubCodeCompiler::GenerateSwitchableCallMissStub() {
|
||||
void StubCodeCompiler::GenerateSingleTargetCallStub() {
|
||||
Label miss;
|
||||
__ LoadClassIdMayBeSmi(A1, A0);
|
||||
__ lhu(T2, FieldAddress(S5, target::SingleTargetCache::lower_limit_offset()));
|
||||
__ lhu(S8, FieldAddress(S5, target::SingleTargetCache::lower_limit_offset()));
|
||||
__ lhu(T3, FieldAddress(S5, target::SingleTargetCache::upper_limit_offset()));
|
||||
|
||||
__ blt(A1, T2, &miss);
|
||||
__ blt(A1, S8, &miss);
|
||||
__ bgt(A1, T3, &miss);
|
||||
|
||||
__ lx(TMP, FieldAddress(S5, target::SingleTargetCache::entry_point_offset()));
|
||||
@@ -3360,7 +3360,7 @@ void StubCodeCompiler::GenerateAllocateTypedDataArrayStub(intptr_t cid) {
|
||||
const intptr_t max_len = TypedDataMaxNewSpaceElements(cid);
|
||||
const intptr_t scale_shift = GetScaleFactor(element_size);
|
||||
|
||||
COMPILE_ASSERT(AllocateTypedDataArrayABI::kLengthReg == T2);
|
||||
COMPILE_ASSERT(AllocateTypedDataArrayABI::kLengthReg == S8);
|
||||
COMPILE_ASSERT(AllocateTypedDataArrayABI::kResultReg == A0);
|
||||
|
||||
if (!FLAG_use_slow_path && FLAG_inline_alloc) {
|
||||
|
||||
@@ -46,9 +46,9 @@ enum Register {
|
||||
SP = 2,
|
||||
GP = 3, // Shadow call stack on Fuchsia and Android
|
||||
TP = 4,
|
||||
T0 = 5,
|
||||
T0 = 5, // RA2
|
||||
T1 = 6,
|
||||
T2 = 7,
|
||||
T2 = 7, // FAR_TMP, EXPECTED_LANDING_PAD
|
||||
FP = 8,
|
||||
S1 = 9, // THR
|
||||
A0 = 10,
|
||||
@@ -64,8 +64,8 @@ enum Register {
|
||||
S4 = 20, // ARGS_DESC_REG
|
||||
S5 = 21, // IC_DATA_REG
|
||||
S6 = 22,
|
||||
S7 = 23, // CALLEE_SAVED_TEMP
|
||||
S8 = 24, // FAR_TMP
|
||||
S7 = 23, // CALLEE_SAVED_TEMP
|
||||
S8 = 24,
|
||||
S9 = 25, // DISPATCH_TABLE_REG
|
||||
S10 = 26, // NULL_REG
|
||||
S11 = 27, // WRITE_BARRIER_STATE
|
||||
@@ -185,7 +185,7 @@ extern const char* const vector_reg_names[kNumberOfVectorRegisters];
|
||||
// Register aliases.
|
||||
constexpr Register TMP = A3; // Used as scratch register by assembler.
|
||||
constexpr Register TMP2 = A4;
|
||||
constexpr Register FAR_TMP = S8;
|
||||
constexpr Register FAR_TMP = T2;
|
||||
constexpr Register PP = A5; // Caches object pool pointer in generated code.
|
||||
constexpr Register DISPATCH_TABLE_REG = S9; // Dispatch table register.
|
||||
constexpr Register CODE_REG = A2;
|
||||
@@ -218,7 +218,7 @@ struct SharedSlowPathStubABI {
|
||||
// ABI for instantiation stubs.
|
||||
struct InstantiationABI {
|
||||
static constexpr Register kUninstantiatedTypeArgumentsReg = T1;
|
||||
static constexpr Register kInstantiatorTypeArgumentsReg = T2;
|
||||
static constexpr Register kInstantiatorTypeArgumentsReg = S8;
|
||||
static constexpr Register kFunctionTypeArgumentsReg = T3;
|
||||
static constexpr Register kResultTypeArgumentsReg = A0;
|
||||
static constexpr Register kResultTypeReg = A0;
|
||||
@@ -281,7 +281,7 @@ struct STCInternalRegs {
|
||||
struct TypeTestABI {
|
||||
static constexpr Register kInstanceReg = A0;
|
||||
static constexpr Register kDstTypeReg = T1;
|
||||
static constexpr Register kInstantiatorTypeArgumentsReg = T2;
|
||||
static constexpr Register kInstantiatorTypeArgumentsReg = S8;
|
||||
static constexpr Register kFunctionTypeArgumentsReg = T3;
|
||||
static constexpr Register kSubtypeTestCacheReg = T4;
|
||||
static constexpr Register kScratchReg = T5;
|
||||
@@ -308,7 +308,7 @@ struct TypeTestABI {
|
||||
// Calling convention when calling AssertSubtypeStub.
|
||||
struct AssertSubtypeABI {
|
||||
static constexpr Register kSubTypeReg = T1;
|
||||
static constexpr Register kSuperTypeReg = T2;
|
||||
static constexpr Register kSuperTypeReg = S8;
|
||||
static constexpr Register kInstantiatorTypeArgumentsReg = T3;
|
||||
static constexpr Register kFunctionTypeArgumentsReg = T4;
|
||||
static constexpr Register kDstNameReg = T5;
|
||||
@@ -324,7 +324,7 @@ struct AssertSubtypeABI {
|
||||
|
||||
// ABI for InitStaticFieldStub.
|
||||
struct InitStaticFieldABI {
|
||||
static constexpr Register kFieldReg = T2;
|
||||
static constexpr Register kFieldReg = S8;
|
||||
static constexpr Register kResultReg = A0;
|
||||
};
|
||||
|
||||
@@ -337,7 +337,7 @@ struct InitLateStaticFieldInternalRegs {
|
||||
// ABI for InitInstanceFieldStub.
|
||||
struct InitInstanceFieldABI {
|
||||
static constexpr Register kInstanceReg = T1;
|
||||
static constexpr Register kFieldReg = T2;
|
||||
static constexpr Register kFieldReg = S8;
|
||||
static constexpr Register kResultReg = A0;
|
||||
};
|
||||
|
||||
@@ -349,12 +349,12 @@ struct InitLateInstanceFieldInternalRegs {
|
||||
|
||||
// ABI for LateInitializationError stubs.
|
||||
struct LateInitializationErrorABI {
|
||||
static constexpr Register kFieldReg = T2;
|
||||
static constexpr Register kFieldReg = S8;
|
||||
};
|
||||
|
||||
// ABI for FieldAccessError stubs.
|
||||
struct FieldAccessErrorABI {
|
||||
static constexpr Register kFieldReg = T2;
|
||||
static constexpr Register kFieldReg = S8;
|
||||
};
|
||||
|
||||
// ABI for ThrowStub.
|
||||
@@ -371,21 +371,21 @@ struct ReThrowABI {
|
||||
// ABI for RangeErrorStub.
|
||||
struct RangeErrorABI {
|
||||
static constexpr Register kLengthReg = T1;
|
||||
static constexpr Register kIndexReg = T2;
|
||||
static constexpr Register kIndexReg = S8;
|
||||
};
|
||||
|
||||
// ABI for AllocateObjectStub.
|
||||
struct AllocateObjectABI {
|
||||
static constexpr Register kResultReg = A0;
|
||||
static constexpr Register kTypeArgumentsReg = A1;
|
||||
static constexpr Register kTagsReg = T2;
|
||||
static constexpr Register kTagsReg = S8;
|
||||
};
|
||||
|
||||
// ABI for AllocateClosureStub.
|
||||
struct AllocateClosureABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kFunctionReg = T1;
|
||||
static constexpr Register kLengthAndFlagsReg = T2;
|
||||
static constexpr Register kLengthAndFlagsReg = S8;
|
||||
static constexpr Register kContextReg = T3;
|
||||
static constexpr Register kScratchReg = T4;
|
||||
};
|
||||
@@ -393,19 +393,19 @@ struct AllocateClosureABI {
|
||||
// ABI for AllocateMintShared*Stub.
|
||||
struct AllocateMintABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kTempReg = T2;
|
||||
static constexpr Register kTempReg = S8;
|
||||
};
|
||||
|
||||
// ABI for Allocate{Mint,Double,Float32x4,Float64x2}Stub.
|
||||
struct AllocateBoxABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kTempReg = T2;
|
||||
static constexpr Register kTempReg = S8;
|
||||
};
|
||||
|
||||
// ABI for AllocateArrayStub.
|
||||
struct AllocateArrayABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kLengthReg = T2;
|
||||
static constexpr Register kLengthReg = S8;
|
||||
static constexpr Register kTypeArgumentsReg = T1;
|
||||
};
|
||||
|
||||
@@ -413,7 +413,7 @@ struct AllocateArrayABI {
|
||||
struct AllocateRecordABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kShapeReg = T1;
|
||||
static constexpr Register kTemp1Reg = T2;
|
||||
static constexpr Register kTemp1Reg = S8;
|
||||
static constexpr Register kTemp2Reg = T3;
|
||||
};
|
||||
|
||||
@@ -421,7 +421,7 @@ struct AllocateRecordABI {
|
||||
// AllocateRecord3, AllocateRecord3Named).
|
||||
struct AllocateSmallRecordABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kShapeReg = T2;
|
||||
static constexpr Register kShapeReg = S8;
|
||||
static constexpr Register kValue0Reg = T3;
|
||||
static constexpr Register kValue1Reg = T4;
|
||||
static constexpr Register kValue2Reg = A1;
|
||||
@@ -431,7 +431,7 @@ struct AllocateSmallRecordABI {
|
||||
// ABI for AllocateTypedDataArrayStub.
|
||||
struct AllocateTypedDataArrayABI {
|
||||
static constexpr Register kResultReg = AllocateObjectABI::kResultReg;
|
||||
static constexpr Register kLengthReg = T2;
|
||||
static constexpr Register kLengthReg = S8;
|
||||
};
|
||||
|
||||
// ABI for BoxDoubleStub.
|
||||
@@ -451,7 +451,7 @@ struct DoubleToIntegerStubABI {
|
||||
// ABI for CheckedStoreIntoSharedStub.
|
||||
struct CheckedStoreIntoSharedStubABI {
|
||||
static constexpr Register kFieldReg = T1;
|
||||
static constexpr Register kValueReg = T2;
|
||||
static constexpr Register kValueReg = S8;
|
||||
static constexpr Register kResultReg = A0;
|
||||
};
|
||||
|
||||
@@ -468,7 +468,7 @@ struct SuspendStubABI {
|
||||
static constexpr Register kTypeArgsReg = T0; // Can be the same as kTempReg
|
||||
static constexpr Register kTempReg = T0;
|
||||
static constexpr Register kFrameSizeReg = T1;
|
||||
static constexpr Register kSuspendStateReg = T2;
|
||||
static constexpr Register kSuspendStateReg = S8;
|
||||
static constexpr Register kFunctionDataReg = T3;
|
||||
static constexpr Register kSrcFrameReg = T4;
|
||||
static constexpr Register kDstFrameReg = T5;
|
||||
@@ -489,12 +489,12 @@ struct ResumeStubABI {
|
||||
static constexpr Register kSuspendStateReg = T1;
|
||||
static constexpr Register kTempReg = T0;
|
||||
// Registers for the frame copying (the 1st part).
|
||||
static constexpr Register kFrameSizeReg = T2;
|
||||
static constexpr Register kFrameSizeReg = S8;
|
||||
static constexpr Register kSrcFrameReg = T3;
|
||||
static constexpr Register kDstFrameReg = T4;
|
||||
// Registers for control transfer.
|
||||
// (the 2nd part, can reuse registers from the 1st part)
|
||||
static constexpr Register kResumePcReg = T2;
|
||||
static constexpr Register kResumePcReg = S8;
|
||||
// Can also reuse kSuspendStateReg but should not conflict with CODE_REG/PP.
|
||||
static constexpr Register kExceptionReg = T3;
|
||||
static constexpr Register kStackTraceReg = T4;
|
||||
@@ -517,7 +517,7 @@ struct CloneSuspendStateStubABI {
|
||||
static constexpr Register kDestinationReg = A1;
|
||||
static constexpr Register kTempReg = T0;
|
||||
static constexpr Register kFrameSizeReg = T1;
|
||||
static constexpr Register kSrcFrameReg = T2;
|
||||
static constexpr Register kSrcFrameReg = S8;
|
||||
static constexpr Register kDstFrameReg = T3;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user