6#if defined(TARGET_ARCH_ARM)
8#define SHOULD_NOT_INCLUDE_RUNTIME
31static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
32 __ ldr(
R0, Address(
SP, +0 * target::kWordSize));
33 __ ldr(
R1, Address(
SP, +1 * target::kWordSize));
39void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
42 TestBothArgumentsSmis(assembler, normal_ir_body);
44 __ b(normal_ir_body,
HI);
55 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
EQ));
57 __ CompareImmediate(
R1, 0);
58 __ b(normal_ir_body,
LT);
65 __ LoadImmediate(
R8, 1);
67 __ sub(
R8,
R8, Operand(1));
68 __ rsb(
R3,
R0, Operand(32));
78 __ str(
R1, FieldAddress(
R0, target::Mint::value_offset()));
80 FieldAddress(
R0, target::Mint::value_offset() + target::kWordSize));
82 __ Bind(normal_ir_body);
85static void Get64SmiOrMint(Assembler* assembler,
89 Label* not_smi_or_mint) {
96 __ mov(res_lo, Operand(reg));
97 __ mov(res_hi, Operand(res_lo,
ASR, 31));
101 __ CompareClassId(reg, kMintCid, res_lo);
102 __ b(not_smi_or_mint,
NE);
105 __ ldr(res_lo, FieldAddress(reg, target::Mint::value_offset()));
107 FieldAddress(reg, target::Mint::value_offset() + target::kWordSize));
112 Label* normal_ir_body,
114 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
115 TestBothArgumentsSmis(assembler, &try_mint_smi);
119 __ b(&is_true, true_condition);
128 Condition hi_true_cond, hi_false_cond, lo_false_cond;
129 switch (true_condition) {
134 lo_false_cond = (true_condition ==
LT) ?
CS :
HI;
140 lo_false_cond = (true_condition ==
GT) ?
LS :
CC;
144 hi_true_cond = hi_false_cond = lo_false_cond =
VS;
147 __ Bind(&try_mint_smi);
149 Get64SmiOrMint(assembler,
R3,
R2,
R1, normal_ir_body);
151 Get64SmiOrMint(assembler,
R1,
R8,
R0, normal_ir_body);
158 __ b(&is_false, hi_false_cond);
159 __ b(&is_true, hi_true_cond);
161 __ b(&is_false, lo_false_cond);
165 __ Bind(normal_ir_body);
168void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
169 Label* normal_ir_body) {
173void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
174 Label* normal_ir_body) {
178void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
179 Label* normal_ir_body) {
183void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
184 Label* normal_ir_body) {
190void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
191 Label* normal_ir_body) {
192 Label true_label, check_for_mint;
194 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
195 __ ldr(
R1, Address(
SP, 1 * target::kWordSize));
197 __ b(&true_label,
EQ);
201 __ b(&check_for_mint,
NE);
206 __ Bind(&true_label);
211 Label receiver_not_smi;
212 __ Bind(&check_for_mint);
215 __ b(&receiver_not_smi,
NE);
221 __ CompareClassId(
R0, kDoubleCid,
R2);
222 __ b(normal_ir_body,
EQ);
227 __ Bind(&receiver_not_smi);
230 __ CompareClassId(
R1, kMintCid,
R2);
231 __ b(normal_ir_body,
NE);
235 READS_RETURN_ADDRESS_FROM_LR(
238 __ Bind(normal_ir_body);
241void AsmIntrinsifier::Integer_equal(Assembler* assembler,
242 Label* normal_ir_body) {
243 Integer_equalToInteger(assembler, normal_ir_body);
246void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
247 Label* normal_ir_body) {
248 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
253 __ rsb(
R0,
R0, Operand(32));
258void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
263 __ ldrd(
R0,
R1,
SP, 2 * target::kWordSize);
265 __ ldrd(
R2,
R3,
SP, 0 * target::kWordSize);
268 __ Asr(
R4,
R3, Operand(5));
281 __ and_(
R1,
R3, Operand(31));
283 __ rsb(
R0,
R1, Operand(32));
284 __ mov(
R9, Operand(0));
298void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
303 __ ldrd(
R0,
R1,
SP, 2 * target::kWordSize);
305 __ ldrd(
R2,
R3,
SP, 0 * target::kWordSize);
308 __ Asr(
R4,
R3, Operand(5));
315 __ add(
R4,
R4, Operand(1));
319 __ and_(
R1,
R3, Operand(31));
321 __ rsb(
R0,
R1, Operand(32));
333 __ Bind(&loop_entry);
336 __ str(
R9, Address(
R6, 0));
341void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
342 Label* normal_ir_body) {
348 __ ldrd(
R0,
R1,
SP, 3 * target::kWordSize);
353 __ ldrd(
R2,
R3,
SP, 1 * target::kWordSize);
358 __ ldr(
R8, Address(
SP, 0 * target::kWordSize));
368 __ adds(
R4,
R4, Operand(0));
381 __ b(&last_carry,
EQ);
384 __ Bind(&carry_loop);
387 __ adcs(
R4,
R4, Operand(0));
390 __ b(&carry_loop,
NE);
392 __ Bind(&last_carry);
393 __ mov(
R4, Operand(0));
394 __ adc(
R4,
R4, Operand(0));
395 __ str(
R4, Address(
R8, 0));
401void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
402 Label* normal_ir_body) {
408 __ ldrd(
R0,
R1,
SP, 3 * target::kWordSize);
413 __ ldrd(
R2,
R3,
SP, 1 * target::kWordSize);
418 __ ldr(
R8, Address(
SP, 0 * target::kWordSize));
428 __ subs(
R4,
R4, Operand(0));
444 __ Bind(&carry_loop);
447 __ sbcs(
R4,
R4, Operand(0));
450 __ b(&carry_loop,
NE);
457void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
458 Label* normal_ir_body) {
488 __ ldrd(
R0,
R1,
SP, 5 * target::kWordSize);
490 __ ldr(
R3, FieldAddress(
R1, target::TypedData::payload_offset()));
495 __ ldr(
R8, Address(
SP, 0 * target::kWordSize));
500 __ ldrd(
R0,
R1,
SP, 3 * target::kWordSize);
505 __ ldrd(
R0,
R1,
SP, 1 * target::kWordSize);
510 __ mov(
R1, Operand(0));
513 __ Bind(&muladd_loop);
524 __ ldr(
R0, Address(
R9, 0));
535 __ subs(
R8,
R8, Operand(1));
536 __ b(&muladd_loop,
NE);
542 __ ldr(
R0, Address(
R9, 0));
547 Label propagate_carry_loop;
548 __ Bind(&propagate_carry_loop);
549 __ ldr(
R0, Address(
R9, 0));
550 __ adds(
R0,
R0, Operand(1));
552 __ b(&propagate_carry_loop,
CS);
559void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
560 Label* normal_ir_body) {
590 __ ldrd(
R2,
R3,
SP, 2 * target::kWordSize);
601 __ ldr(
R1, Address(
SP, 1 * target::kWordSize));
606 __ ldr(
R0, Address(
R6, 0));
607 __ mov(
R8, Operand(0));
615 __ mov(
R9, Operand(0));
618 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
620 __ mov(
R0, Operand(2));
641 __ mov(
R2, Operand(0));
642 __ adc(
R2,
R2, Operand(0));
645 __ adc(
R2,
R2, Operand(0));
646 __ ldr(
R8, Address(
R6, 0));
648 __ adcs(
R8,
R1, Operand(0));
649 __ adc(
R9,
R2, Operand(0));
660 __ ldr(
R0, Address(
R6, 0));
664 __ adc(
R9,
R9, Operand(0));
675void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
676 Label* normal_ir_body) {
680void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
681 Label* normal_ir_body) {
692 __ ldr(
R4, Address(
SP, 2 * target::kWordSize));
695 __ ldr(
R3, FieldAddress(
R4, target::TypedData::payload_offset() +
699 __ ldrd(
R0,
R1,
SP, 0 * target::kWordSize);
701 __ ldr(
R2, FieldAddress(
R1, target::TypedData::payload_offset()));
707 __ str(
R0, FieldAddress(
R4, target::TypedData::payload_offset() +
717static void TestLastArgumentIsDouble(Assembler* assembler,
719 Label* not_double_smi) {
720 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
723 __ CompareClassId(
R0, kDoubleCid,
R1);
724 __ b(not_double_smi,
NE);
732static void CompareDoubles(Assembler* assembler,
733 Label* normal_ir_body,
735 Label is_smi, double_op;
737 TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
742 __ ldr(
R0, Address(
SP, 1 * target::kWordSize));
749 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
VS));
750 __ LoadObject(
R0, CastHandle<Object>(
TrueObject()), true_condition);
758 __ Bind(normal_ir_body);
761void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
762 Label* normal_ir_body) {
763 CompareDoubles(assembler, normal_ir_body,
HI);
766void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
767 Label* normal_ir_body) {
768 CompareDoubles(assembler, normal_ir_body,
CS);
771void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
772 Label* normal_ir_body) {
773 CompareDoubles(assembler, normal_ir_body,
CC);
776void AsmIntrinsifier::Double_equal(Assembler* assembler,
777 Label* normal_ir_body) {
778 CompareDoubles(assembler, normal_ir_body,
EQ);
781void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
782 Label* normal_ir_body) {
783 CompareDoubles(assembler, normal_ir_body,
LS);
788static void DoubleArithmeticOperations(Assembler* assembler,
789 Label* normal_ir_body,
791 Label is_smi, double_op;
793 TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
797 __ ldr(
R0, Address(
SP, 1 * target::kWordSize));
825 __ Bind(normal_ir_body);
828void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
829 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
832void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
833 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
836void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
837 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
840void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
841 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
845void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
846 Label* normal_ir_body) {
849 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
851 __ b(normal_ir_body,
NE);
856 __ ldr(
R0, Address(
SP, 1 * target::kWordSize));
864 __ Bind(normal_ir_body);
867void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
868 Label* normal_ir_body) {
871 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
873 __ b(normal_ir_body,
NE);
883 __ Bind(normal_ir_body);
886void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
887 Label* normal_ir_body) {
888 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
897void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
898 Label* normal_ir_body) {
899 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
901 __ LoadFieldFromOffset(
R1,
R0, target::Double::value_offset());
902 __ LoadFieldFromOffset(
R2,
R0,
903 target::Double::value_offset() + target::kWordSize);
906 __ cmp(
R1, Operand(0));
908 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
NE));
911 __ AndImmediate(
R2,
R2, 0x7FFFFFFF);
913 __ CompareImmediate(
R2, 0x7FF00000);
915 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
NE));
920void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
921 Label* normal_ir_body) {
922 Label is_false, is_true, is_zero;
923 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
943 __ tst(
R1, Operand(1));
948void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
949 Label* normal_ir_body) {
950 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
951 __ ldr(
R1, Address(
SP, 1 * target::kWordSize));
958static void JumpIfInteger(Assembler* assembler,
966static void JumpIfNotInteger(Assembler* assembler,
974static void JumpIfString(Assembler* assembler,
978 assembler->RangeCheck(
cid, tmp, kOneByteStringCid, kTwoByteStringCid,
982static void JumpIfNotString(Assembler* assembler,
986 assembler->RangeCheck(
cid, tmp, kOneByteStringCid, kTwoByteStringCid,
990static void JumpIfNotList(Assembler* assembler,
994 assembler->RangeCheck(
cid, tmp, kArrayCid, kGrowableObjectArrayCid,
998static void JumpIfType(Assembler* assembler,
1003 (kRecordTypeCid == kTypeCid + 2));
1004 assembler->RangeCheck(
cid, tmp, kTypeCid, kRecordTypeCid,
1008static void JumpIfNotType(Assembler* assembler,
1013 (kRecordTypeCid == kTypeCid + 2));
1014 assembler->RangeCheck(
cid, tmp, kTypeCid, kRecordTypeCid,
1019void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
1020 Label* normal_ir_body) {
1021 Label use_declaration_type, not_double, not_integer, not_string;
1022 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
1023 __ LoadClassIdMayBeSmi(
R1,
R0);
1025 __ CompareImmediate(
R1, kClosureCid);
1026 __ b(normal_ir_body,
EQ);
1028 __ CompareImmediate(
R1, kRecordCid);
1029 __ b(normal_ir_body,
EQ);
1032 __ b(&use_declaration_type,
HI);
1034 __ LoadIsolateGroup(
R2);
1035 __ LoadFromOffset(
R2,
R2, target::IsolateGroup::object_store_offset());
1037 __ CompareImmediate(
R1, kDoubleCid);
1038 __ b(¬_double,
NE);
1039 __ LoadFromOffset(
R0,
R2, target::ObjectStore::double_type_offset());
1042 __ Bind(¬_double);
1043 JumpIfNotInteger(assembler,
R1,
R0, ¬_integer);
1044 __ LoadFromOffset(
R0,
R2, target::ObjectStore::int_type_offset());
1047 __ Bind(¬_integer);
1048 JumpIfNotString(assembler,
R1,
R0, ¬_string);
1049 __ LoadFromOffset(
R0,
R2, target::ObjectStore::string_type_offset());
1052 __ Bind(¬_string);
1053 JumpIfNotType(assembler,
R1,
R0, &use_declaration_type);
1054 __ LoadFromOffset(
R0,
R2, target::ObjectStore::type_type_offset());
1057 __ Bind(&use_declaration_type);
1058 __ LoadClassById(
R2,
R1);
1059 __ ldrh(
R3, FieldAddress(
R2, target::Class::num_type_arguments_offset()));
1060 __ CompareImmediate(
R3, 0);
1061 __ b(normal_ir_body,
NE);
1063 __ ldr(
R0, FieldAddress(
R2, target::Class::declaration_type_offset()));
1065 __ b(normal_ir_body,
EQ);
1068 __ Bind(normal_ir_body);
1075static void EquivalentClassIds(Assembler* assembler,
1076 Label* normal_ir_body,
1077 Label* equal_may_be_generic,
1078 Label* equal_not_generic,
1083 bool testing_instance_cids) {
1084 Label not_integer, not_integer_or_string, not_integer_or_string_or_list;
1087 __ CompareImmediate(cid1, kClosureCid);
1088 __ b(normal_ir_body,
EQ);
1091 __ CompareImmediate(cid1, kRecordCid);
1092 __ b(normal_ir_body,
EQ);
1097 __ cmp(cid1, Operand(cid2));
1098 __ b(equal_may_be_generic,
EQ);
1104 __ b(not_equal,
HI);
1107 JumpIfNotInteger(assembler, cid1, scratch, ¬_integer);
1110 JumpIfInteger(assembler, cid2, scratch, equal_not_generic);
1114 __ Bind(¬_integer);
1116 JumpIfNotString(assembler, cid1, scratch,
1117 testing_instance_cids ? ¬_integer_or_string : not_equal);
1120 JumpIfString(assembler, cid2, scratch, equal_not_generic);
1124 if (testing_instance_cids) {
1125 __ Bind(¬_integer_or_string);
1127 JumpIfNotList(assembler, cid1, scratch, ¬_integer_or_string_or_list);
1130 JumpIfNotList(assembler, cid2, scratch, not_equal);
1131 ASSERT(compiler::target::Array::type_arguments_offset() ==
1132 compiler::target::GrowableObjectArray::type_arguments_offset());
1133 __ b(equal_may_be_generic);
1135 __ Bind(¬_integer_or_string_or_list);
1139 JumpIfNotType(assembler, cid1, scratch, not_equal);
1142 JumpIfType(assembler, cid2, scratch, equal_not_generic);
1148void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
1149 Label* normal_ir_body) {
1151 __ LoadClassIdMayBeSmi(
R1,
R1);
1152 __ LoadClassIdMayBeSmi(
R2,
R2);
1154 Label equal_may_be_generic,
equal, not_equal;
1155 EquivalentClassIds(assembler, normal_ir_body, &equal_may_be_generic, &
equal,
1159 __ Bind(&equal_may_be_generic);
1163 __ LoadClassById(
R0,
R1);
1168 target::Class::host_type_arguments_field_offset_in_words_offset()));
1169 __ CompareImmediate(
R0, target::Class::kNoTypeArguments);
1175 __ ldr(
R1, Address(
R1,
R0,
LSL, target::kWordSizeLog2));
1177 __ ldr(
R2, Address(
R2,
R0,
LSL, target::kWordSizeLog2));
1179 __ b(normal_ir_body,
NE);
1186 __ Bind(¬_equal);
1190 __ Bind(normal_ir_body);
1193void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1194 Label* normal_ir_body) {
1195 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
1196 __ ldr(
R0, FieldAddress(
R0, target::String::hash_offset()));
1197 __ cmp(
R0, Operand(0));
1198 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
NE));
1199 __ Bind(normal_ir_body);
1202void AsmIntrinsifier::Type_equality(Assembler* assembler,
1203 Label* normal_ir_body) {
1204 Label
equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
1212 __ LoadClassIdMayBeSmi(
R0,
R1);
1213 __ CompareImmediate(
R0, kTypeCid);
1214 __ b(normal_ir_body,
NE);
1217 __ LoadTypeClassId(
R3,
R1);
1218 __ LoadTypeClassId(
R4,
R2);
1220 EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
1221 &equiv_cids, ¬_equal,
R3,
R4,
R0,
1224 __ Bind(&equiv_cids_may_be_generic);
1226 __ ldr(
R3, FieldAddress(
R1, target::Type::arguments_offset()));
1227 __ ldr(
R4, FieldAddress(
R2, target::Type::arguments_offset()));
1229 __ b(normal_ir_body,
NE);
1233 __ Bind(&equiv_cids);
1234 __ LoadAbstractTypeNullability(
R1,
R1);
1235 __ LoadAbstractTypeNullability(
R2,
R2);
1237 __ b(&check_legacy,
NE);
1247 ASSERT(target::Nullability::kNullable < target::Nullability::kNonNullable &&
1248 target::Nullability::kNonNullable < target::Nullability::kLegacy);
1249 __ Bind(&check_legacy);
1250 __ CompareImmediate(
R1, target::Nullability::kNonNullable);
1251 __ b(¬_equal,
LT);
1252 __ CompareImmediate(
R2, target::Nullability::kNonNullable);
1255 __ Bind(¬_equal);
1259 __ Bind(normal_ir_body);
1262void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1263 Label* normal_ir_body) {
1264 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
1265 __ ldr(
R0, FieldAddress(
R0, target::AbstractType::hash_offset()));
1266 __ cmp(
R0, Operand(0));
1267 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
NE));
1268 __ Bind(normal_ir_body);
1271void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1272 Label* normal_ir_body) {
1275 __ b(normal_ir_body,
NE);
1280 __ Bind(normal_ir_body);
1283void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1284 intptr_t receiver_cid,
1287 Label* return_false) {
1289 __ ldr(
R8, FieldAddress(
R0, target::String::length_offset()));
1292 FieldAddress(
R2, target::String::length_offset()));
1296 __ cmp(
R9, Operand(0));
1297 __ b(return_true,
EQ);
1300 __ cmp(
R1, Operand(0));
1301 __ b(return_false,
LT);
1306 __ b(return_false,
GT);
1308 if (receiver_cid == kOneByteStringCid) {
1312 ASSERT(receiver_cid == kTwoByteStringCid);
1317 if (other_cid == kOneByteStringCid) {
1320 ASSERT(other_cid == kTwoByteStringCid);
1325 __ LoadImmediate(
R3, 0);
1331 if (receiver_cid == kOneByteStringCid) {
1332 __ ldrb(
R4, Address(
R0, 0));
1334 __ ldrh(
R4, Address(
R0, 0));
1336 if (other_cid == kOneByteStringCid) {
1342 __ b(return_false,
NE);
1345 __ AddImmediate(
R3, 1);
1346 __ AddImmediate(
R0, receiver_cid == kOneByteStringCid ? 1 : 2);
1347 __ AddImmediate(
R2, other_cid == kOneByteStringCid ? 1 : 2);
1357void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1358 Label* normal_ir_body) {
1359 Label return_true, return_false, try_two_byte;
1360 __ ldr(
R0, Address(
SP, 2 * target::kWordSize));
1361 __ ldr(
R1, Address(
SP, 1 * target::kWordSize));
1362 __ ldr(
R2, Address(
SP, 0 * target::kWordSize));
1366 __ b(normal_ir_body,
NE);
1368 __ CompareClassId(
R2, kOneByteStringCid,
R3);
1369 __ b(normal_ir_body,
NE);
1371 __ CompareClassId(
R0, kOneByteStringCid,
R3);
1372 __ b(&try_two_byte,
NE);
1374 GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
1375 kOneByteStringCid, &return_true,
1378 __ Bind(&try_two_byte);
1379 __ CompareClassId(
R0, kTwoByteStringCid,
R3);
1380 __ b(normal_ir_body,
NE);
1382 GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
1383 kOneByteStringCid, &return_true,
1386 __ Bind(&return_true);
1391 __ Bind(&return_false);
1396 __ Bind(normal_ir_body);
1400void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1401 Label* normal_ir_body) {
1405void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1406 Label* normal_ir_body) {
1407 Label try_two_byte_string;
1409 __ ldr(
R1, Address(
SP, 0 * target::kWordSize));
1410 __ ldr(
R0, Address(
SP, 1 * target::kWordSize));
1412 __ b(normal_ir_body,
NE);
1414 __ ldr(
R2, FieldAddress(
R0, target::String::length_offset()));
1416 __ b(normal_ir_body,
CS);
1418 __ CompareClassId(
R0, kOneByteStringCid,
R3);
1419 __ b(&try_two_byte_string,
NE);
1423 __ CompareImmediate(
R1, target::Symbols::kNumberOfOneCharCodeSymbols);
1424 __ b(normal_ir_body,
GE);
1425 __ ldr(
R0, Address(
THR, target::Thread::predefined_symbols_address_offset()));
1427 R0, target::Symbols::kNullCharCodeSymbolOffset * target::kWordSize);
1431 __ Bind(&try_two_byte_string);
1432 __ CompareClassId(
R0, kTwoByteStringCid,
R3);
1433 __ b(normal_ir_body,
NE);
1437 __ CompareImmediate(
R1, target::Symbols::kNumberOfOneCharCodeSymbols);
1438 __ b(normal_ir_body,
GE);
1439 __ ldr(
R0, Address(
THR, target::Thread::predefined_symbols_address_offset()));
1441 R0, target::Symbols::kNullCharCodeSymbolOffset * target::kWordSize);
1445 __ Bind(normal_ir_body);
1448void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1449 Label* normal_ir_body) {
1450 __ ldr(
R0, Address(
SP, 0 * target::kWordSize));
1451 __ ldr(
R0, FieldAddress(
R0, target::String::length_offset()));
1458void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1459 Label* normal_ir_body) {
1460 __ ldr(
R1, Address(
SP, 0 * target::kWordSize));
1461 __ ldr(
R0, FieldAddress(
R1, target::String::hash_offset()));
1462 __ cmp(
R0, Operand(0));
1463 READS_RETURN_ADDRESS_FROM_LR(
__ bx(
LR,
NE));
1464 __ ldr(
R2, FieldAddress(
R1, target::String::length_offset()));
1466 __ mov(
R3, Operand(0));
1484 __ add(
R3,
R3, Operand(1));
1485 __ add(
R8,
R8, Operand(1));
1491 __ FinalizeHashForSize(target::String::kHashBits,
R0);
1493 __ StoreIntoSmiField(FieldAddress(
R1, target::String::hash_offset()),
R0);
1500static void TryAllocateString(Assembler* assembler,
1502 intptr_t max_elements,
1505 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1508 __ BranchIfNotSmi(length_reg, failure);
1515 __ mov(
R8, Operand(length_reg));
1516 if (
cid == kOneByteStringCid) {
1517 __ SmiUntag(length_reg);
1521 const intptr_t fixed_size_plus_alignment_padding =
1522 target::String::InstanceSize() +
1524 __ AddImmediate(length_reg, fixed_size_plus_alignment_padding);
1525 __ bic(length_reg, length_reg,
1528 __ ldr(
R0, Address(
THR, target::Thread::top_offset()));
1531 __ adds(
R1,
R0, Operand(length_reg));
1538 __ ldr(
TMP, Address(
THR, target::Thread::end_offset()));
1541 __ CheckAllocationCanary(
R0);
1545 __ str(
R1, Address(
THR, target::Thread::top_offset()));
1550 __ LoadImmediate(
TMP, 0);
1551 __ str(
TMP, Address(
R1, -1 * target::kWordSize));
1552 __ str(
TMP, Address(
R1, -2 * target::kWordSize));
1559 const intptr_t shift = target::UntaggedObject::kTagBitsSizeTagPos -
1562 __ CompareImmediate(
R2, target::UntaggedObject::kSizeTagMaxSizeTag);
1564 __ mov(
R3, Operand(0),
HI);
1570 __ LoadImmediate(
TMP, tags);
1572 __ str(
R3, FieldAddress(
R0, target::Object::tags_offset()));
1576 __ StoreIntoObjectNoBarrier(
1577 R0, FieldAddress(
R0, target::String::length_offset()),
R8);
1579 __ LoadImmediate(
TMP, 0);
1580 __ StoreIntoObjectNoBarrier(
1581 R0, FieldAddress(
R0, target::String::hash_offset()),
TMP);
1590void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1591 Label* normal_ir_body) {
1592 const intptr_t kStringOffset = 2 * target::kWordSize;
1593 const intptr_t kStartIndexOffset = 1 * target::kWordSize;
1594 const intptr_t kEndIndexOffset = 0 * target::kWordSize;
1597 __ ldr(
R2, Address(
SP, kEndIndexOffset));
1598 __ ldr(
TMP, Address(
SP, kStartIndexOffset));
1601 __ b(normal_ir_body,
NE);
1604 TryAllocateString(assembler, kOneByteStringCid,
1605 target::OneByteString::kMaxNewSpaceElements, &
ok,
1610 __ ldr(
R3, Address(
SP, kStringOffset));
1611 __ ldr(
R1, Address(
SP, kStartIndexOffset));
1615 __ AddImmediate(
R3, target::OneByteString::data_offset() - 1);
1619 __ ldr(
R2, Address(
SP, kEndIndexOffset));
1630 __ cmp(
R2, Operand(0));
1636 __ sub(
R2,
R2, Operand(1));
1637 __ cmp(
R2, Operand(0));
1638 __ strb(
TMP, FieldAddress(
R1, target::OneByteString::data_offset()));
1639 __ add(
R1,
R1, Operand(1));
1644 __ Bind(normal_ir_body);
1647void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1648 Label* normal_ir_body) {
1649 __ ldr(
R2, Address(
SP, 0 * target::kWordSize));
1650 __ ldr(
R1, Address(
SP, 1 * target::kWordSize));
1651 __ ldr(
R0, Address(
SP, 2 * target::kWordSize));
1660void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1661 Label* normal_ir_body) {
1662 __ ldr(
R2, Address(
SP, 0 * target::kWordSize));
1663 __ ldr(
R1, Address(
SP, 1 * target::kWordSize));
1664 __ ldr(
R0, Address(
SP, 2 * target::kWordSize));
1673void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1674 Label* normal_ir_body) {
1675 __ ldr(
R2, Address(
SP, 0 * target::kWordSize));
1677 TryAllocateString(assembler, kOneByteStringCid,
1678 target::OneByteString::kMaxNewSpaceElements, &
ok,
1684 __ Bind(normal_ir_body);
1687void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1688 Label* normal_ir_body) {
1689 __ ldr(
R2, Address(
SP, 0 * target::kWordSize));
1691 TryAllocateString(assembler, kTwoByteStringCid,
1692 target::TwoByteString::kMaxNewSpaceElements, &
ok,
1698 __ Bind(normal_ir_body);
1701void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1702 Label* normal_ir_body) {
1703 __ ldr(
R0, Address(
SP, 1 * target::kWordSize));
1704 __ ldr(
R1, Address(
SP, 0 * target::kWordSize));
1706 StringEquality(assembler,
R0,
R1,
R2,
R3,
R0, normal_ir_body,
1710void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1711 Label* normal_ir_body) {
1712 __ ldr(
R0, Address(
SP, 1 * target::kWordSize));
1713 __ ldr(
R1, Address(
SP, 0 * target::kWordSize));
1715 StringEquality(assembler,
R0,
R1,
R2,
R3,
R0, normal_ir_body,
1719void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1720 Label* normal_ir_body,
1722 if (FLAG_interpret_irregexp)
return;
1724 const intptr_t kRegExpParamOffset = 2 * target::kWordSize;
1725 const intptr_t kStringParamOffset = 1 * target::kWordSize;
1735 __ ldr(
R2, Address(
SP, kRegExpParamOffset));
1736 __ ldr(
R1, Address(
SP, kStringParamOffset));
1738 __ AddImmediate(
R1, -kOneByteStringCid);
1739 __ add(
R1,
R2, Operand(
R1,
LSL, target::kWordSizeLog2));
1741 kOneByteStringCid, sticky)));
1749 __ Branch(FieldAddress(
FUNCTION_REG, target::Function::entry_point_offset()));
1752void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
1753 Label* normal_ir_body) {
1755 __ ldr(
R0, Address(
R0, target::Isolate::default_tag_offset()));
1759void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
1760 Label* normal_ir_body) {
1762 __ ldr(
R0, Address(
R0, target::Isolate::current_tag_offset()));
1766void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
1767 Label* normal_ir_body) {
1768#if !defined(SUPPORT_TIMELINE)
1773 __ ldr(
R0, Address(
THR, target::Thread::dart_stream_offset()));
1775 __ ldr(
R0, Address(
R0, target::TimelineStream::enabled_offset()));
1776 __ cmp(
R0, Operand(0));
1783void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
1784 Label* normal_ir_body) {
1785#if !defined(SUPPORT_TIMELINE)
1789 __ ldr(
R1, Address(
THR, target::Thread::next_task_id_offset()));
1790 __ ldr(
R2, Address(
THR, target::Thread::next_task_id_offset() + 4));
1792 __ adds(
R1,
R1, Operand(1));
1793 __ adcs(
R2,
R2, Operand(0));
1794 __ str(
R1, Address(
THR, target::Thread::next_task_id_offset()));
1795 __ str(
R2, 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)
#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()
const Class & MintClass()
static bool CompareIntegers(Token::Kind kind, const Integer &left, const Integer &right)
uint32_t CombineHashes(uint32_t hash, uint32_t other_hash)
const Register FUNCTION_REG
const intptr_t kBytesPerBigIntDigit
static constexpr intptr_t kObjectAlignmentLog2
static constexpr intptr_t kObjectAlignment
#define NOT_IN_PRODUCT(code)