6#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
8#define SHOULD_NOT_INCLUDE_RUNTIME
31static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
38void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
43 TestBothArgumentsSmis(assembler, normal_ir_body);
49 __ sll(
TMP, left, right);
59 Label* normal_ir_body,
62 TestBothArgumentsSmis(assembler, normal_ir_body);
63 __ CompareObjectRegisters(
A0,
A1);
74void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
75 Label* normal_ir_body) {
79void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
80 Label* normal_ir_body) {
84void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
85 Label* normal_ir_body) {
89void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
90 Label* normal_ir_body) {
96void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
97 Label* normal_ir_body) {
98 Label true_label, check_for_mint;
102 __ CompareObjectRegisters(
A0,
A1);
117 Label receiver_not_smi;
120 __ BranchIfNotSmi(
A0, &receiver_not_smi,
127 __ CompareClassId(
A1, kDoubleCid,
TMP);
133 __ Bind(&receiver_not_smi);
136 __ CompareClassId(
A0, kMintCid,
TMP);
147void AsmIntrinsifier::Integer_equal(Assembler* assembler,
148 Label* normal_ir_body) {
149 Integer_equalToInteger(assembler, normal_ir_body);
152void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
153 Label* normal_ir_body) {
158 __ srai(
A1,
A0, XLEN - 1);
161 __ CountLeadingZeroes(
A0,
A0);
169void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
223void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
277void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
278 Label* normal_ir_body) {
283 Label first_loop, second_loop, last_carry,
done;
304 __ beqz(
T3, &second_loop);
321 __ beqz(
T1, &last_carry);
340void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
341 Label* normal_ir_body) {
345 Label first_loop, second_loop, last_borrow,
done;
366 __ beqz(
T3, &second_loop);
383 __ beqz(
T1, &last_borrow);
404void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
405 Label* normal_ir_body) {
512 __ bnez(
T6, &muladd_loop);
524 Label propagate_carry_loop;
525 __ Bind(&propagate_carry_loop);
531 __ bnez(
T1, &propagate_carry_loop);
539void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
540 Label* normal_ir_body) {
577 __ lx(
T1, Address(
T2, 0));
579 __ beqz(
T1, &x_zero);
588 __ lx(
A0, Address(
T3, 0));
597 __ sx(
A1, Address(
T3, 0));
626 __ lx(
T0, Address(
T2, 0));
652 __ lx(
T5, Address(
T3, 0));
660 __ sx(
A0, Address(
T3, 0));
669 __ lx(
A0, Address(
T3, 0));
678 __ sx(
T4, Address(
T3, 0));
687void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
688 Label* normal_ir_body) {
762 __ beq(
T2,
T3, &return_qd);
793 Label qh_adj_loop, qh_adj, qh_ok;
846 Label ql_adj_loop, ql_adj, ql_ok;
880void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
881 Label* normal_ir_body) {
918static void PrepareDoubleOp(Assembler* assembler, Label* normal_ir_body) {
932 __ CompareClassId(
A1, kDoubleCid,
TMP);
939void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
940 Label* normal_ir_body) {
942 PrepareDoubleOp(assembler, normal_ir_body);
954void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
955 Label* normal_ir_body) {
957 PrepareDoubleOp(assembler, normal_ir_body);
969void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
970 Label* normal_ir_body) {
972 PrepareDoubleOp(assembler, normal_ir_body);
984void AsmIntrinsifier::Double_equal(Assembler* assembler,
985 Label* normal_ir_body) {
987 PrepareDoubleOp(assembler, normal_ir_body);
999void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
1000 Label* normal_ir_body) {
1002 PrepareDoubleOp(assembler, normal_ir_body);
1016static void DoubleArithmeticOperations(Assembler* assembler,
1017 Label* normal_ir_body,
1019 PrepareDoubleOp(assembler, normal_ir_body);
1044void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
1045 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
1048void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
1049 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
1052void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
1053 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
1056void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
1057 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
1061void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
1062 Label* normal_ir_body) {
1083void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
1084 Label* normal_ir_body) {
1101static void DoubleIsClass(Assembler* assembler, intx_t fclass) {
1115void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
1116 Label* normal_ir_body) {
1120void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
1121 Label* normal_ir_body) {
1125void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
1126 Label* normal_ir_body) {
1131void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
1132 Label* normal_ir_body) {
1144static void JumpIfInteger(Assembler* assembler,
1152static void JumpIfNotInteger(Assembler* assembler,
1160static void JumpIfString(Assembler* assembler,
1164 assembler->RangeCheck(
cid, tmp, kOneByteStringCid, kTwoByteStringCid,
1168static void JumpIfNotString(Assembler* assembler,
1172 assembler->RangeCheck(
cid, tmp, kOneByteStringCid, kTwoByteStringCid,
1176static void JumpIfNotList(Assembler* assembler,
1180 assembler->RangeCheck(
cid, tmp, kArrayCid, kGrowableObjectArrayCid,
1184static void JumpIfType(Assembler* assembler,
1189 (kRecordTypeCid == kTypeCid + 2));
1190 assembler->RangeCheck(
cid, tmp, kTypeCid, kRecordTypeCid,
1194static void JumpIfNotType(Assembler* assembler,
1199 (kRecordTypeCid == kTypeCid + 2));
1200 assembler->RangeCheck(
cid, tmp, kTypeCid, kRecordTypeCid,
1205void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
1206 Label* normal_ir_body) {
1207 Label use_declaration_type, not_double, not_integer, not_string;
1209 __ LoadClassIdMayBeSmi(
A1,
A0);
1211 __ CompareImmediate(
A1, kClosureCid);
1212 __ BranchIf(EQ, normal_ir_body,
1215 __ CompareImmediate(
A1, kRecordCid);
1216 __ BranchIf(EQ, normal_ir_body,
1222 __ LoadIsolateGroup(
A0);
1225 __ CompareImmediate(
A1, kDoubleCid);
1231 JumpIfNotInteger(assembler,
A1,
TMP, ¬_integer);
1236 JumpIfNotString(assembler,
A1,
TMP, ¬_string);
1241 JumpIfNotType(assembler,
A1,
TMP, &use_declaration_type);
1245 __ Bind(&use_declaration_type);
1246 __ LoadClassById(
T2,
A1);
1250 __ LoadCompressed(
A0,
1262static void EquivalentClassIds(Assembler* assembler,
1263 Label* normal_ir_body,
1264 Label* equal_may_be_generic,
1265 Label* equal_not_generic,
1270 bool testing_instance_cids) {
1271 Label not_integer, not_integer_or_string, not_integer_or_string_or_list;
1274 __ CompareImmediate(cid1, kClosureCid);
1278 __ CompareImmediate(cid1, kRecordCid);
1284 __ beq(cid1, cid2, equal_may_be_generic);
1290 __ BranchIf(
HI, not_equal);
1293 JumpIfNotInteger(assembler, cid1, scratch, ¬_integer);
1296 JumpIfInteger(assembler, cid2, scratch, equal_not_generic);
1302 JumpIfNotString(assembler, cid1, scratch,
1303 testing_instance_cids ? ¬_integer_or_string : not_equal);
1306 JumpIfString(assembler, cid2, scratch, equal_not_generic);
1310 if (testing_instance_cids) {
1311 __ Bind(¬_integer_or_string);
1313 JumpIfNotList(assembler, cid1, scratch, ¬_integer_or_string_or_list);
1316 JumpIfNotList(assembler, cid2, scratch, not_equal);
1321 __ Bind(¬_integer_or_string_or_list);
1325 JumpIfNotType(assembler, cid1, scratch, not_equal);
1328 JumpIfType(assembler, cid2, scratch, equal_not_generic);
1334void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
1335 Label* normal_ir_body) {
1338 __ LoadClassIdMayBeSmi(
T2,
A1);
1339 __ LoadClassIdMayBeSmi(
A1,
A0);
1341 Label equal_may_be_generic,
equal, not_equal;
1342 EquivalentClassIds(assembler, normal_ir_body, &equal_may_be_generic, &
equal,
1346 __ Bind(&equal_may_be_generic);
1350 __ LoadClassById(
A0,
A1);
1364 __ lx(
A0, FieldAddress(
A0, 0));
1365 __ lx(
A1, FieldAddress(
A1, 0));
1380void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1381 Label* normal_ir_body) {
1384#if defined(HASH_IN_OBJECT_HEADER)
1399void AsmIntrinsifier::Type_equality(Assembler* assembler,
1400 Label* normal_ir_body) {
1401 Label
equal, not_equal, equiv_cids_may_be_generic, equiv_cids;
1409 __ LoadClassIdMayBeSmi(
T3,
A1);
1410 __ CompareImmediate(
T3, kTypeCid);
1414 __ LoadTypeClassId(
T3,
A1);
1415 __ LoadTypeClassId(
T4,
A0);
1417 EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
1418 &equiv_cids, ¬_equal,
T3,
T4,
TMP,
1421 __ Bind(&equiv_cids_may_be_generic);
1425 __ CompareObjectRegisters(
T3,
T4);
1431 __ LoadAbstractTypeNullability(
A0,
A0);
1432 __ LoadAbstractTypeNullability(
A1,
A1);
1433 __ bne(
A0,
A1, ¬_equal);
1447void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1448 Label* normal_ir_body) {
1457void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1458 Label* normal_ir_body) {
1473void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1474 Label* normal_ir_body) {
1478 Label not_yet_computed;
1480 __ lwu(
A0, FieldAddress(
1483 __ beqz(
A0, ¬_yet_computed);
1487 __ Bind(¬_yet_computed);
1489 __ AndImmediate(
T2,
A1, 0xffffffff);
1491 __ LoadImmediate(
A1, 0xffffda61);
1495 __ AndImmediate(
A1,
A1, 0x3fffffff);
1496 __ beqz(
A1, ¬_yet_computed);
1502 Label retry, already_set_in_r4;
1504 __ lr(
T2, Address(
A0, 0));
1506 __ bnez(
T4, &already_set_in_r4);
1509 __ bnez(
T4, &retry);
1513 __ Bind(&already_set_in_r4);
1519void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1520 intptr_t receiver_cid,
1523 Label* return_false) {
1525 __ LoadCompressedSmi(
1528 __ LoadCompressedSmi(
1533 __ beqz(
T2, return_true);
1536 __ bltz(
T0, return_false);
1540 __ bgt(
T3,
T1, return_false);
1542 if (receiver_cid == kOneByteStringCid) {
1545 ASSERT(receiver_cid == kTwoByteStringCid);
1558 if (receiver_cid == kOneByteStringCid) {
1564 if (other_cid == kOneByteStringCid) {
1573 __ addi(
A0,
A0, receiver_cid == kOneByteStringCid ? 1 : 2);
1574 __ addi(
A1,
A1, other_cid == kOneByteStringCid ? 1 : 2);
1583void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1584 Label* normal_ir_body) {
1585 Label return_true, return_false, try_two_byte;
1590 __ BranchIfNotSmi(
T0, normal_ir_body);
1592 __ CompareClassId(
A1, kOneByteStringCid,
TMP);
1595 __ CompareClassId(
A0, kOneByteStringCid,
TMP);
1598 GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
1599 kOneByteStringCid, &return_true,
1603 __ CompareClassId(
A0, kTwoByteStringCid,
TMP);
1606 GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
1607 kOneByteStringCid, &return_true,
1621void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1622 Label* normal_ir_body) {
1623 Label try_two_byte_string;
1627 __ BranchIfNotSmi(
A1, normal_ir_body,
1631 __ bgeu(
A1,
TMP, normal_ir_body);
1633 __ CompareClassId(
A0, kOneByteStringCid,
TMP);
1634 __ BranchIf(
NE, &try_two_byte_string);
1647 __ Bind(&try_two_byte_string);
1648 __ CompareClassId(
A0, kTwoByteStringCid,
TMP);
1665void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1666 Label* normal_ir_body) {
1678void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1679 Label* normal_ir_body) {
1682#if defined(HASH_IN_OBJECT_HEADER)
1690 __ beqz(
A0, &compute_hash);
1711 __ lbu(
T3, Address(
T2, 0));
1721#if defined(HASH_IN_OBJECT_HEADER)
1727 __ lr(
T0, Address(
A1, 0));
1730 __ bnez(
TMP, &retry);
1744static void TryAllocateString(Assembler* assembler,
1746 intptr_t max_elements,
1749 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1752 __ BranchIfNotSmi(length_reg, failure);
1759 __ mv(
T0, length_reg);
1760 if (
cid == kOneByteStringCid) {
1762 __ SmiUntag(length_reg);
1767 const intptr_t fixed_size_plus_alignment_padding =
1770 __ addi(length_reg, length_reg, fixed_size_plus_alignment_padding);
1771 __ andi(length_reg, length_reg,
1777 __ add(
T1,
A0, length_reg);
1778 __ bltu(
T1,
A0, failure);
1786 __ CheckAllocationCanary(
A0);
1807 Label dont_zero_tag;
1818 __ OrImmediate(
A1,
A1, tags);
1823 __ StoreIntoObjectNoBarrier(
1825#if !defined(HASH_IN_OBJECT_HEADER)
1827 __ StoreIntoObjectNoBarrier(
1837void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1838 Label* normal_ir_body) {
1844 __ lx(
T0, Address(
SP, kEndIndexOffset));
1845 __ lx(
TMP, Address(
SP, kStartIndexOffset));
1847 __ BranchIfNotSmi(
T1, normal_ir_body);
1850 TryAllocateString(assembler, kOneByteStringCid,
1856 __ lx(
T1, Address(
SP, kStringOffset));
1857 __ lx(
T2, Address(
SP, kStartIndexOffset));
1864 __ lx(
T0, Address(
SP, kEndIndexOffset));
1891void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1892 Label* normal_ir_body) {
1903void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1904 Label* normal_ir_body) {
1915void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1916 Label* normal_ir_body) {
1920 TryAllocateString(assembler, kOneByteStringCid,
1930void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1931 Label* normal_ir_body) {
1935 TryAllocateString(assembler, kTwoByteStringCid,
1945void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1946 Label* normal_ir_body) {
1950 StringEquality(assembler,
A0,
A1,
T2,
TMP2,
A0, normal_ir_body,
1954void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1955 Label* normal_ir_body) {
1959 StringEquality(assembler,
A0,
A1,
T2,
TMP2,
A0, normal_ir_body,
1963void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1964 Label* normal_ir_body,
1966 if (FLAG_interpret_irregexp)
return;
1979 __ lx(
T2, Address(
SP, kRegExpParamOffset));
1980 __ lx(
T1, Address(
SP, kStringParamOffset));
1982 __ AddImmediate(
T1, -kOneByteStringCid);
1986 kOneByteStringCid, sticky)));
1998void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
1999 Label* normal_ir_body) {
2005void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
2006 Label* normal_ir_body) {
2012void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
2013 Label* normal_ir_body) {
2014#if !defined(SUPPORT_TIMELINE)
2032void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
2033 Label* normal_ir_body) {
2034#if !defined(SUPPORT_TIMELINE)
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
static bool equal(const SkBitmap &a, const SkBitmap &b)
static bool ok(int result)
static word hash_offset()
static word type_arguments_offset()
static word declaration_type_offset()
static word host_type_arguments_field_offset_in_words_offset()
static const word kNoTypeArguments
static word num_type_arguments_offset()
static word value_offset()
static word code_offset()
static word entry_point_offset(CodeEntryKind kind=CodeEntryKind::kNormal)
static word type_arguments_offset()
static word object_store_offset()
static word current_tag_offset()
static word default_tag_offset()
static word double_type_offset()
static word type_type_offset()
static word int_type_offset()
static word string_type_offset()
static word tags_offset()
static word data_offset()
static const word kMaxNewSpaceElements
static word function_offset(classid_t cid, bool sticky)
static const word kHashBits
static word hash_offset()
static word InstanceSize()
static word length_offset()
static const word kNullCharCodeSymbolOffset
static const word kNumberOfOneCharCodeSymbols
static word random_offset()
static word dart_stream_offset()
static word predefined_symbols_address_offset()
static word next_task_id_offset()
static word enabled_offset()
static const word kMaxNewSpaceElements
static word data_offset()
static word arguments_offset()
static word payload_offset()
static const word kHashTagPos
static const word kSizeTagMaxSizeTag
static const word kTagBitsSizeTagPos
uword MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size)
static constexpr intptr_t kCompressedWordSizeLog2
static constexpr word kBitsPerWordLog2
word ToRawSmi(const dart::Object &a)
static constexpr intptr_t kWordSize
static constexpr word kBitsPerWord
constexpr intptr_t kSmiBits
const Bool & TrueObject()
const Bool & FalseObject()
const Object & NullObject()
const Class & DoubleClass()
static bool CompareIntegers(Token::Kind kind, const Integer &left, const Integer &right)
uint32_t CombineHashes(uint32_t hash, uint32_t other_hash)
constexpr intptr_t kBitsPerByte
constexpr intptr_t kWordSizeLog2
const Register FUNCTION_REG
const intptr_t kBytesPerBigIntDigit
NOT_IN_PRODUCT(LibraryPtr ReloadTestScript(const char *script))
COMPILE_ASSERT(kUnreachableReference==WeakTable::kNoValue)
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
static constexpr intptr_t kObjectAlignmentLog2
static constexpr intptr_t kObjectAlignment