6#if defined(TARGET_ARCH_RISCV32) || defined(TARGET_ARCH_RISCV64)
8#define SHOULD_NOT_INCLUDE_RUNTIME
31static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
32 __ lx(
A0, Address(
SP, +1 * target::kWordSize));
33 __ lx(
A1, Address(
SP, +0 * target::kWordSize));
38void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
43 TestBothArgumentsSmis(assembler, normal_ir_body);
55 __ Bind(normal_ir_body);
59 Label* normal_ir_body,
62 TestBothArgumentsSmis(assembler, normal_ir_body);
63 __ CompareObjectRegisters(
A0,
A1);
71 __ Bind(normal_ir_body);
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;
100 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
101 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
102 __ CompareObjectRegisters(
A0,
A1);
112 __ Bind(&true_label);
117 Label receiver_not_smi;
118 __ Bind(&check_for_mint);
120 __ BranchIfNotSmi(
A0, &receiver_not_smi,
127 __ CompareClassId(
A1, kDoubleCid,
TMP);
133 __ Bind(&receiver_not_smi);
136 __ CompareClassId(
A0, kMintCid,
TMP);
144 __ Bind(normal_ir_body);
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) {
154 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
158 __ srai(
A1,
A0, XLEN - 1);
161 __ CountLeadingZeroes(
A0,
A0);
169void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
175 __ lx(
T0, Address(
SP, 3 * target::kWordSize));
176 __ lx(
T1, Address(
SP, 2 * target::kWordSize));
177 __ lx(
T2, Address(
SP, 1 * target::kWordSize));
178 __ lx(
T3, Address(
SP, 0 * target::kWordSize));
190 __ srai(
T4,
T2, target::kBitsPerWordLog2);
191 __ andi(
T5,
T2, target::kBitsPerWord - 1);
192 __ li(
T6, target::kBitsPerWord);
195 __ slli(
TMP,
T1, target::kWordSizeLog2);
197 __ subi(
T0,
T0, target::kWordSize);
200 __ slli(
TMP,
TMP, target::kWordSizeLog2);
207 __ lx(
TMP, FieldAddress(
T0, target::TypedData::payload_offset()));
210 __ sx(
TMP2, FieldAddress(
T3, target::TypedData::payload_offset()));
212 __ subi(
T0,
T0, target::kWordSize);
213 __ subi(
T3,
T3, target::kWordSize);
218 __ sx(
T2, FieldAddress(
T3, target::TypedData::payload_offset()));
223void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
229 __ lx(
T0, Address(
SP, 3 * target::kWordSize));
230 __ lx(
T1, Address(
SP, 2 * target::kWordSize));
231 __ lx(
T2, Address(
SP, 1 * target::kWordSize));
232 __ lx(
T3, Address(
SP, 0 * target::kWordSize));
244 __ srai(
T4,
T2, target::kBitsPerWordLog2);
245 __ andi(
T5,
T2, target::kBitsPerWord - 1);
246 __ li(
T6, target::kBitsPerWord);
250 __ slli(
TMP,
T4, target::kWordSizeLog2);
254 __ lx(
T2, FieldAddress(
T0, target::TypedData::payload_offset()));
256 __ addi(
T0,
T0, target::kWordSize);
261 __ lx(
TMP, FieldAddress(
T0, target::TypedData::payload_offset()));
264 __ sx(
TMP2, FieldAddress(
T3, target::TypedData::payload_offset()));
266 __ addi(
T0,
T0, target::kWordSize);
267 __ addi(
T3,
T3, target::kWordSize);
272 __ sx(
T2, FieldAddress(
T3, target::TypedData::payload_offset()));
277void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
278 Label* normal_ir_body) {
283 Label first_loop, second_loop, last_carry,
done;
284 __ lx(
T0, Address(
SP, 4 * target::kWordSize));
285 __ lx(
T1, Address(
SP, 3 * target::kWordSize));
286 __ lx(
T2, Address(
SP, 2 * target::kWordSize));
287 __ lx(
T3, Address(
SP, 1 * target::kWordSize));
288 __ lx(
T4, Address(
SP, 0 * target::kWordSize));
303 __ Bind(&first_loop);
304 __ beqz(
T3, &second_loop);
305 __ lx(
A0, FieldAddress(
T0, target::TypedData::payload_offset()));
306 __ lx(
A1, FieldAddress(
T2, target::TypedData::payload_offset()));
312 __ sx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
313 __ addi(
T0,
T0, target::kWordSize);
314 __ addi(
T2,
T2, target::kWordSize);
315 __ addi(
T4,
T4, target::kWordSize);
320 __ Bind(&second_loop);
321 __ beqz(
T1, &last_carry);
322 __ lx(
A0, FieldAddress(
T0, target::TypedData::payload_offset()));
325 __ sx(
TMP, FieldAddress(
T4, target::TypedData::payload_offset()));
326 __ addi(
T0,
T0, target::kWordSize);
327 __ addi(
T4,
T4, target::kWordSize);
331 __ Bind(&last_carry);
333 __ sx(
T5, FieldAddress(
T4, target::TypedData::payload_offset()));
340void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
341 Label* normal_ir_body) {
345 Label first_loop, second_loop, last_borrow,
done;
346 __ lx(
T0, Address(
SP, 4 * target::kWordSize));
347 __ lx(
T1, Address(
SP, 3 * target::kWordSize));
348 __ lx(
T2, Address(
SP, 2 * target::kWordSize));
349 __ lx(
T3, Address(
SP, 1 * target::kWordSize));
350 __ lx(
T4, Address(
SP, 0 * target::kWordSize));
365 __ Bind(&first_loop);
366 __ beqz(
T3, &second_loop);
367 __ lx(
A0, FieldAddress(
T0, target::TypedData::payload_offset()));
368 __ lx(
A1, FieldAddress(
T2, target::TypedData::payload_offset()));
374 __ sx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
375 __ addi(
T0,
T0, target::kWordSize);
376 __ addi(
T2,
T2, target::kWordSize);
377 __ addi(
T4,
T4, target::kWordSize);
382 __ Bind(&second_loop);
383 __ beqz(
T1, &last_borrow);
384 __ lx(
A0, FieldAddress(
T0, target::TypedData::payload_offset()));
388 __ sx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
389 __ addi(
T0,
T0, target::kWordSize);
390 __ addi(
T4,
T4, target::kWordSize);
394 __ Bind(&last_borrow);
397 __ sx(
T5, FieldAddress(
T4, target::TypedData::payload_offset()));
404void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
405 Label* normal_ir_body) {
435 __ lx(
T0, Address(
SP, 6 * target::kWordSize));
436 __ lx(
T1, Address(
SP, 5 * target::kWordSize));
437 __ lx(
T2, Address(
SP, 4 * target::kWordSize));
438 __ lx(
T3, Address(
SP, 3 * target::kWordSize));
439 __ lx(
T4, Address(
SP, 2 * target::kWordSize));
440 __ lx(
T5, Address(
SP, 1 * target::kWordSize));
441 __ lx(
T6, Address(
SP, 0 * target::kWordSize));
447 __ lx(
T0, FieldAddress(
T0, target::TypedData::payload_offset()));
475 __ Bind(&muladd_loop);
484 __ lx(
A0, FieldAddress(
T2, target::TypedData::payload_offset()));
485 __ addi(
T2,
T2, target::kWordSize);
488 __ lx(
A1, FieldAddress(
T4, target::TypedData::payload_offset()));
507 __ sx(
A6, FieldAddress(
T4, target::TypedData::payload_offset()));
508 __ addi(
T4,
T4, target::kWordSize);
512 __ bnez(
T6, &muladd_loop);
517 __ lx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
520 __ sx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
521 __ addi(
T4,
T4, target::kWordSize);
524 Label propagate_carry_loop;
525 __ Bind(&propagate_carry_loop);
526 __ lx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
529 __ sx(
A0, FieldAddress(
T4, target::TypedData::payload_offset()));
530 __ addi(
T4,
T4, target::kWordSize);
531 __ bnez(
T1, &propagate_carry_loop);
539void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
540 Label* normal_ir_body) {
569 __ lx(
T0, Address(
SP, 2 * target::kWordSize));
570 __ lx(
T1, Address(
SP, 3 * target::kWordSize));
577 __ lx(
T1, Address(
T2, 0));
578 __ addi(
T2,
T2, target::kWordSize);
579 __ beqz(
T1, &x_zero);
582 __ lx(
A1, Address(
SP, 1 * target::kWordSize));
588 __ lx(
A0, Address(
T3, 0));
597 __ sx(
A1, Address(
T3, 0));
598 __ addi(
T3,
T3, target::kWordSize);
600 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
626 __ lx(
T0, Address(
T2, 0));
627 __ addi(
T2,
T2, target::kWordSize);
652 __ lx(
T5, Address(
T3, 0));
660 __ sx(
A0, Address(
T3, 0));
661 __ addi(
T3,
T3, target::kWordSize);
669 __ lx(
A0, Address(
T3, 0));
678 __ sx(
T4, Address(
T3, 0));
679 __ sx(
T5, Address(
T3, target::kWordSize));
687void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
688 Label* normal_ir_body) {
733 __ lx(
T4, Address(
SP, 2 * target::kWordSize));
737 __ lx(
T3, FieldAddress(
T4, target::TypedData::payload_offset() +
741 __ lx(
T3, FieldAddress(
T4, target::TypedData::payload_offset()));
744 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
745 __ lx(
T1, Address(
SP, 1 * target::kWordSize));
750 __ lx(
T2, FieldAddress(
T1, target::TypedData::payload_offset()));
753 __ lx(
T2, FieldAddress(
T1, target::TypedData::payload_offset() -
762 __ beq(
T2,
T3, &return_qd);
766 __ lx(
T1, FieldAddress(
T1, target::TypedData::payload_offset() -
770 __ lx(
T1, FieldAddress(
T1, target::TypedData::payload_offset() -
775 __ srli(
T5,
T3, target::kWordSize * 4);
785 __ slli(
A7,
T2, target::kWordSize * 4);
786 __ srli(
TMP,
T1, target::kWordSize * 4);
790 __ srli(
S3,
T2, target::kWordSize * 4);
793 Label qh_adj_loop, qh_adj, qh_ok;
794 __ Bind(&qh_adj_loop);
815 __ slli(
A0,
T6, target::kWordSize * 4);
818 __ slli(
A7,
A1, target::kWordSize * 4);
821 __ slli(
S3,
A6, target::kWordSize * 4);
822 __ srli(
TMP,
A1, target::kWordSize * 4);
836 __ slli(
T6,
T2, target::kWordSize * 4);
837 __ srli(
TMP,
T1, target::kWordSize * 4);
846 Label ql_adj_loop, ql_adj, ql_ok;
847 __ Bind(&ql_adj_loop);
872 __ sx(
A0, FieldAddress(
T4, target::TypedData::payload_offset() +
880void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
881 Label* normal_ir_body) {
891 __ lx(
T0, Address(
SP, 2 * target::kWordSize));
892 __ lx(
T1, Address(
SP, 1 * target::kWordSize));
893 __ lx(
T2, Address(
SP, 0 * target::kWordSize));
896 __ lx(
T3, FieldAddress(
T0, target::TypedData::payload_offset() +
902 __ lx(
T4, FieldAddress(
T1, target::TypedData::payload_offset()));
908 __ sx(
T5, FieldAddress(
T0, target::TypedData::payload_offset() +
918static void PrepareDoubleOp(Assembler* assembler, Label* normal_ir_body) {
920 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
921 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
923 __ fld(
FA0, FieldAddress(
A0, target::Double::value_offset()));
932 __ CompareClassId(
A1, kDoubleCid,
TMP);
934 __ fld(
FA1, FieldAddress(
A1, target::Double::value_offset()));
939void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
940 Label* normal_ir_body) {
942 PrepareDoubleOp(assembler, normal_ir_body);
947 __ Bind(&true_label);
951 __ Bind(normal_ir_body);
954void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
955 Label* normal_ir_body) {
957 PrepareDoubleOp(assembler, normal_ir_body);
962 __ Bind(&true_label);
966 __ Bind(normal_ir_body);
969void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
970 Label* normal_ir_body) {
972 PrepareDoubleOp(assembler, normal_ir_body);
977 __ Bind(&true_label);
981 __ Bind(normal_ir_body);
984void AsmIntrinsifier::Double_equal(Assembler* assembler,
985 Label* normal_ir_body) {
987 PrepareDoubleOp(assembler, normal_ir_body);
992 __ Bind(&true_label);
996 __ Bind(normal_ir_body);
999void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
1000 Label* normal_ir_body) {
1002 PrepareDoubleOp(assembler, normal_ir_body);
1007 __ Bind(&true_label);
1011 __ Bind(normal_ir_body);
1016static void DoubleArithmeticOperations(Assembler* assembler,
1017 Label* normal_ir_body,
1019 PrepareDoubleOp(assembler, normal_ir_body);
1038 __ StoreDFieldToOffset(
FA0,
A0, target::Double::value_offset());
1041 __ Bind(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) {
1064 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1073 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1074 __ LoadDFieldFromOffset(
FA0,
A0, target::Double::value_offset());
1078 __ StoreDFieldToOffset(
FA0,
A0, target::Double::value_offset());
1080 __ Bind(normal_ir_body);
1083void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
1084 Label* normal_ir_body) {
1085 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1096 __ StoreDFieldToOffset(
FA0,
A0, target::Double::value_offset());
1098 __ Bind(normal_ir_body);
1101static void DoubleIsClass(Assembler* assembler, intx_t fclass) {
1103 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1104 __ LoadDFieldFromOffset(
FA0,
A0, target::Double::value_offset());
1110 __ Bind(&true_label);
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) {
1134 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1135 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1139 __ Bind(&true_label);
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;
1208 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
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);
1223 __ LoadFromOffset(
A0,
A0, target::IsolateGroup::object_store_offset());
1225 __ CompareImmediate(
A1, kDoubleCid);
1227 __ LoadFromOffset(
A0,
A0, target::ObjectStore::double_type_offset());
1230 __ Bind(¬_double);
1231 JumpIfNotInteger(assembler,
A1,
TMP, ¬_integer);
1232 __ LoadFromOffset(
A0,
A0, target::ObjectStore::int_type_offset());
1235 __ Bind(¬_integer);
1236 JumpIfNotString(assembler,
A1,
TMP, ¬_string);
1237 __ LoadFromOffset(
A0,
A0, target::ObjectStore::string_type_offset());
1240 __ Bind(¬_string);
1241 JumpIfNotType(assembler,
A1,
TMP, &use_declaration_type);
1242 __ LoadFromOffset(
A0,
A0, target::ObjectStore::type_type_offset());
1245 __ Bind(&use_declaration_type);
1246 __ LoadClassById(
T2,
A1);
1247 __ lh(
T3, FieldAddress(
T2, target::Class::num_type_arguments_offset()));
1250 __ LoadCompressed(
A0,
1251 FieldAddress(
T2, target::Class::declaration_type_offset()));
1255 __ Bind(normal_ir_body);
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);
1300 __ Bind(¬_integer);
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);
1317 ASSERT(compiler::target::Array::type_arguments_offset() ==
1318 compiler::target::GrowableObjectArray::type_arguments_offset());
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) {
1336 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1337 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
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);
1354 target::Class::host_type_arguments_field_offset_in_words_offset()));
1355 __ CompareImmediate(
T0, target::Class::kNoTypeArguments);
1359 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1360 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1361 __ slli(
T0,
T0, target::kCompressedWordSizeLog2);
1364 __ lx(
A0, FieldAddress(
A0, 0));
1365 __ lx(
A1, FieldAddress(
A1, 0));
1373 __ Bind(¬_equal);
1377 __ Bind(normal_ir_body);
1380void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1381 Label* normal_ir_body) {
1382 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1384#if defined(HASH_IN_OBJECT_HEADER)
1386 __ lwu(
A0, FieldAddress(
A0, target::String::hash_offset()));
1390 __ lx(
A0, FieldAddress(
A0, target::String::hash_offset()));
1396 __ Bind(normal_ir_body);
1399void AsmIntrinsifier::Type_equality(Assembler* assembler,
1400 Label* normal_ir_body) {
1401 Label
equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
1403 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1404 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
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);
1423 __ LoadCompressed(
T3, FieldAddress(
A1, target::Type::arguments_offset()));
1424 __ LoadCompressed(
T4, FieldAddress(
A0, target::Type::arguments_offset()));
1425 __ CompareObjectRegisters(
T3,
T4);
1430 __ Bind(&equiv_cids);
1431 __ LoadAbstractTypeNullability(
A0,
A0);
1432 __ LoadAbstractTypeNullability(
A1,
A1);
1433 __ bne(
A0,
A1, &check_legacy);
1443 ASSERT(target::Nullability::kNullable < target::Nullability::kNonNullable &&
1444 target::Nullability::kNonNullable < target::Nullability::kLegacy);
1445 __ Bind(&check_legacy);
1446 __ CompareImmediate(
A1, target::Nullability::kNonNullable);
1447 __ BranchIf(
LT, ¬_equal);
1448 __ CompareImmediate(
A0, target::Nullability::kNonNullable);
1451 __ Bind(¬_equal);
1455 __ Bind(normal_ir_body);
1458void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1459 Label* normal_ir_body) {
1460 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1461 __ LoadCompressed(
A0, FieldAddress(
A0, target::AbstractType::hash_offset()));
1465 __ Bind(normal_ir_body);
1468void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1469 Label* normal_ir_body) {
1470 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1471 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1477 __ Bind(normal_ir_body);
1484void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1485 Label* normal_ir_body) {
1489 Label not_yet_computed;
1490 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1491 __ lwu(
A0, FieldAddress(
1492 A0, target::Object::tags_offset() +
1494 __ beqz(
A0, ¬_yet_computed);
1498 __ Bind(¬_yet_computed);
1499 __ LoadFromOffset(
A1,
THR, target::Thread::random_offset());
1500 __ AndImmediate(
T2,
A1, 0xffffffff);
1502 __ LoadImmediate(
A1, 0xffffda61);
1505 __ StoreToOffset(
A1,
THR, target::Thread::random_offset());
1506 __ AndImmediate(
A1,
A1, 0x3fffffff);
1507 __ beqz(
A1, ¬_yet_computed);
1509 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1511 __ slli(
T3,
A1, target::UntaggedObject::kHashTagPos);
1513 Label retry, already_set_in_r4;
1515 __ lr(
T2, Address(
A0, 0));
1516 __ srli(
T4,
T2, target::UntaggedObject::kHashTagPos);
1517 __ bnez(
T4, &already_set_in_r4);
1520 __ bnez(
T4, &retry);
1524 __ Bind(&already_set_in_r4);
1530void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1531 intptr_t receiver_cid,
1534 Label* return_false) {
1536 __ LoadCompressedSmi(
1537 T1, FieldAddress(
A0, target::String::length_offset()));
1539 __ LoadCompressedSmi(
1540 T2, FieldAddress(
A1, target::String::length_offset()));
1544 __ beqz(
T2, return_true);
1547 __ bltz(
T0, return_false);
1551 __ bgt(
T3,
T1, return_false);
1553 if (receiver_cid == kOneByteStringCid) {
1556 ASSERT(receiver_cid == kTwoByteStringCid);
1569 if (receiver_cid == kOneByteStringCid) {
1570 __ lbu(
TMP, FieldAddress(
A0, target::OneByteString::data_offset()));
1572 __ lhu(
TMP, FieldAddress(
A0, target::TwoByteString::data_offset()));
1575 if (other_cid == kOneByteStringCid) {
1576 __ lbu(
TMP2, FieldAddress(
A1, target::OneByteString::data_offset()));
1578 __ lhu(
TMP2, FieldAddress(
A1, target::TwoByteString::data_offset()));
1584 __ addi(
A0,
A0, receiver_cid == kOneByteStringCid ? 1 : 2);
1585 __ addi(
A1,
A1, other_cid == kOneByteStringCid ? 1 : 2);
1594void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1595 Label* normal_ir_body) {
1596 Label return_true, return_false, try_two_byte;
1597 __ lx(
A0, Address(
SP, 2 * target::kWordSize));
1598 __ lx(
T0, Address(
SP, 1 * target::kWordSize));
1599 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1601 __ BranchIfNotSmi(
T0, normal_ir_body);
1603 __ CompareClassId(
A1, kOneByteStringCid,
TMP);
1606 __ CompareClassId(
A0, kOneByteStringCid,
TMP);
1609 GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
1610 kOneByteStringCid, &return_true,
1613 __ Bind(&try_two_byte);
1614 __ CompareClassId(
A0, kTwoByteStringCid,
TMP);
1617 GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
1618 kOneByteStringCid, &return_true,
1621 __ Bind(&return_true);
1625 __ Bind(&return_false);
1629 __ Bind(normal_ir_body);
1632void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1633 Label* normal_ir_body) {
1634 Label try_two_byte_string;
1636 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1637 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1638 __ BranchIfNotSmi(
A1, normal_ir_body,
1641 __ lx(
TMP, FieldAddress(
A0, target::String::length_offset()));
1642 __ bgeu(
A1,
TMP, normal_ir_body);
1644 __ CompareClassId(
A0, kOneByteStringCid,
TMP);
1645 __ BranchIf(
NE, &try_two_byte_string);
1648 __ lbu(
A1, FieldAddress(
A0, target::OneByteString::data_offset()));
1649 __ CompareImmediate(
A1, target::Symbols::kNumberOfOneCharCodeSymbols);
1651 __ lx(
A0, Address(
THR, target::Thread::predefined_symbols_address_offset()));
1652 __ slli(
A1,
A1, target::kWordSizeLog2);
1654 __ lx(
A0, Address(
A0, target::Symbols::kNullCharCodeSymbolOffset *
1655 target::kWordSize));
1658 __ Bind(&try_two_byte_string);
1659 __ CompareClassId(
A0, kTwoByteStringCid,
TMP);
1663 __ lhu(
A1, FieldAddress(
A0, target::TwoByteString::data_offset()));
1664 __ CompareImmediate(
A1, target::Symbols::kNumberOfOneCharCodeSymbols);
1666 __ lx(
A0, Address(
THR, target::Thread::predefined_symbols_address_offset()));
1667 __ slli(
A1,
A1, target::kWordSizeLog2);
1669 __ lx(
A0, Address(
A0, target::Symbols::kNullCharCodeSymbolOffset *
1670 target::kWordSize));
1673 __ Bind(normal_ir_body);
1676void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1677 Label* normal_ir_body) {
1679 __ lx(
A0, Address(
SP, 0 * target::kWordSize));
1680 __ lx(
A0, FieldAddress(
A0, target::String::length_offset()));
1689void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1690 Label* normal_ir_body) {
1692 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1693#if defined(HASH_IN_OBJECT_HEADER)
1695 __ lwu(
A0, FieldAddress(
A1, target::String::hash_offset()));
1699 __ lx(
A0, FieldAddress(
A1, target::String::hash_offset()));
1701 __ beqz(
A0, &compute_hash);
1704 __ Bind(&compute_hash);
1705 __ lx(
T0, FieldAddress(
A1, target::String::length_offset()));
1722 __ lbu(
T3, Address(
T2, 0));
1731 __ FinalizeHashForSize(target::String::kHashBits,
A0);
1732#if defined(HASH_IN_OBJECT_HEADER)
1735 __ slli(
A0,
A0, target::UntaggedObject::kHashTagPos);
1738 __ lr(
T0, Address(
A1, 0));
1741 __ bnez(
TMP, &retry);
1743 __ srli(
A0,
A0, target::UntaggedObject::kHashTagPos);
1747 __ sx(
A0, FieldAddress(
A1, target::String::hash_offset()));
1755static void TryAllocateString(Assembler* assembler,
1757 intptr_t max_elements,
1760 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1763 __ BranchIfNotSmi(length_reg, failure);
1770 __ mv(
T0, length_reg);
1771 if (
cid == kOneByteStringCid) {
1773 __ SmiUntag(length_reg);
1778 const intptr_t fixed_size_plus_alignment_padding =
1779 target::String::InstanceSize() +
1781 __ addi(length_reg, length_reg, fixed_size_plus_alignment_padding);
1782 __ andi(length_reg, length_reg,
1785 __ lx(
A0, Address(
THR, target::Thread::top_offset()));
1788 __ add(
T1,
A0, length_reg);
1789 __ bltu(
T1,
A0, failure);
1795 __ lx(
TMP, Address(
THR, target::Thread::end_offset()));
1797 __ CheckAllocationCanary(
A0);
1801 __ sx(
T1, Address(
THR, target::Thread::top_offset()));
1806 __ sx(
ZR, Address(
T1, -1 * target::kWordSize));
1807 __ sx(
ZR, Address(
T1, -2 * target::kWordSize));
1814 const intptr_t shift = target::UntaggedObject::kTagBitsSizeTagPos -
1817 __ CompareImmediate(
A1, target::UntaggedObject::kSizeTagMaxSizeTag);
1818 Label dont_zero_tag;
1821 __ Bind(&dont_zero_tag);
1829 __ OrImmediate(
A1,
A1, tags);
1830 __ sx(
A1, FieldAddress(
A0, target::Object::tags_offset()));
1834 __ StoreIntoObjectNoBarrier(
1835 A0, FieldAddress(
A0, target::String::length_offset()),
T0);
1836#if !defined(HASH_IN_OBJECT_HEADER)
1838 __ StoreIntoObjectNoBarrier(
1839 A0, FieldAddress(
A0, target::String::hash_offset()),
ZR);
1848void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1849 Label* normal_ir_body) {
1850 const intptr_t kStringOffset = 2 * target::kWordSize;
1851 const intptr_t kStartIndexOffset = 1 * target::kWordSize;
1852 const intptr_t kEndIndexOffset = 0 * target::kWordSize;
1855 __ lx(
T0, Address(
SP, kEndIndexOffset));
1856 __ lx(
TMP, Address(
SP, kStartIndexOffset));
1858 __ BranchIfNotSmi(
T1, normal_ir_body);
1861 TryAllocateString(assembler, kOneByteStringCid,
1862 target::OneByteString::kMaxNewSpaceElements, &
ok,
1867 __ lx(
T1, Address(
SP, kStringOffset));
1868 __ lx(
T2, Address(
SP, kStartIndexOffset));
1875 __ lx(
T0, Address(
SP, kEndIndexOffset));
1891 __ lbu(
T2, FieldAddress(
T3, target::OneByteString::data_offset()));
1893 __ sb(
T2, FieldAddress(
T4, target::OneByteString::data_offset()));
1899 __ Bind(normal_ir_body);
1902void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1903 Label* normal_ir_body) {
1904 __ lx(
A0, Address(
SP, 2 * target::kWordSize));
1905 __ lx(
A1, Address(
SP, 1 * target::kWordSize));
1906 __ lx(
A2, Address(
SP, 0 * target::kWordSize));
1910 __ sb(
A2, FieldAddress(
A1, target::OneByteString::data_offset()));
1914void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1915 Label* normal_ir_body) {
1916 __ lx(
A0, Address(
SP, 2 * target::kWordSize));
1917 __ lx(
A1, Address(
SP, 1 * target::kWordSize));
1918 __ lx(
A2, Address(
SP, 0 * target::kWordSize));
1922 __ sh(
A2, FieldAddress(
A1, target::OneByteString::data_offset()));
1926void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1927 Label* normal_ir_body) {
1930 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1931 TryAllocateString(assembler, kOneByteStringCid,
1932 target::OneByteString::kMaxNewSpaceElements, &
ok,
1938 __ Bind(normal_ir_body);
1941void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1942 Label* normal_ir_body) {
1945 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1946 TryAllocateString(assembler, kTwoByteStringCid,
1947 target::TwoByteString::kMaxNewSpaceElements, &
ok,
1953 __ Bind(normal_ir_body);
1956void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1957 Label* normal_ir_body) {
1958 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1959 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1961 StringEquality(assembler,
A0,
A1,
T2,
TMP2,
A0, normal_ir_body,
1965void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1966 Label* normal_ir_body) {
1967 __ lx(
A0, Address(
SP, 1 * target::kWordSize));
1968 __ lx(
A1, Address(
SP, 0 * target::kWordSize));
1970 StringEquality(assembler,
A0,
A1,
T2,
TMP2,
A0, normal_ir_body,
1974void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1975 Label* normal_ir_body,
1977 if (FLAG_interpret_irregexp)
return;
1979 const intptr_t kRegExpParamOffset = 2 * target::kWordSize;
1980 const intptr_t kStringParamOffset = 1 * target::kWordSize;
1990 __ lx(
T2, Address(
SP, kRegExpParamOffset));
1991 __ lx(
T1, Address(
SP, kStringParamOffset));
1993 __ AddImmediate(
T1, -kOneByteStringCid);
1994 __ slli(
T1,
T1, target::kWordSizeLog2);
1997 kOneByteStringCid, sticky)));
2005 __ lx(
T1, FieldAddress(
FUNCTION_REG, target::Function::entry_point_offset()));
2009void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
2010 Label* normal_ir_body) {
2012 __ lx(
A0, Address(
A0, target::Isolate::default_tag_offset()));
2016void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
2017 Label* normal_ir_body) {
2019 __ lx(
A0, Address(
A0, target::Isolate::current_tag_offset()));
2023void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
2024 Label* normal_ir_body) {
2025#if !defined(SUPPORT_TIMELINE)
2031 __ lx(
A0, Address(
THR, target::Thread::dart_stream_offset()));
2033 __ lx(
A0, Address(
A0, target::TimelineStream::enabled_offset()));
2037 __ Bind(&true_label);
2043void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
2044 Label* normal_ir_body) {
2045#if !defined(SUPPORT_TIMELINE)
2049 __ ld(
A0, Address(
THR, target::Thread::next_task_id_offset()));
2051 __ sd(
A1, Address(
THR, target::Thread::next_task_id_offset()));
2055 __ lw(
T0, Address(
THR, target::Thread::next_task_id_offset()));
2056 __ lw(
T1, Address(
THR, target::Thread::next_task_id_offset() + 4));
2061 __ sw(
T2, Address(
THR, target::Thread::next_task_id_offset()));
2062 __ sw(
T1, Address(
THR, target::Thread::next_task_id_offset() + 4));
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 bool left(const SkPoint &p0, const SkPoint &p1)
static bool right(const SkPoint &p0, const SkPoint &p1)
#define COMPILE_ASSERT(expr)
uword MakeTagWordForNewSpaceObject(classid_t cid, uword instance_size)
word ToRawSmi(const dart::Object &a)
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
const Register FUNCTION_REG
const intptr_t kBytesPerBigIntDigit
static constexpr intptr_t kObjectAlignmentLog2
static constexpr intptr_t kObjectAlignment
#define NOT_IN_PRODUCT(code)