6#if defined(TARGET_ARCH_X64)
8#define SHOULD_NOT_INCLUDE_RUNTIME
31static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
32 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
33 __ movq(
RCX, Address(
RSP, +2 * target::kWordSize));
39void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
43 TestBothArgumentsSmis(assembler, normal_ir_body);
50 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
67 __ Bind(normal_ir_body);
71 Label* normal_ir_body,
74 TestBothArgumentsSmis(assembler, normal_ir_body);
76 __ OBJ(cmp)(Address(
RSP, +2 * target::kWordSize),
RAX);
83 __ Bind(normal_ir_body);
86void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
87 Label* normal_ir_body) {
91void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
92 Label* normal_ir_body) {
96void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
97 Label* normal_ir_body) {
101void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
102 Label* normal_ir_body) {
108void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
109 Label* normal_ir_body) {
110 Label true_label, check_for_mint;
111 const intptr_t kReceiverOffset = 2;
112 const intptr_t kArgumentOffset = 1;
115 __ movq(
RAX, Address(
RSP, +kArgumentOffset * target::kWordSize));
116 __ movq(
RCX, Address(
RSP, +kReceiverOffset * target::kWordSize));
125 __ Bind(&true_label);
130 Label receiver_not_smi;
131 __ Bind(&check_for_mint);
132 __ movq(
RAX, Address(
RSP, +kReceiverOffset * target::kWordSize));
139 __ movq(
RAX, Address(
RSP, +kArgumentOffset * target::kWordSize));
140 __ CompareClassId(
RAX, kDoubleCid);
145 __ Bind(&receiver_not_smi);
147 __ CompareClassId(
RAX, kMintCid);
150 __ movq(
RAX, Address(
RSP, +kArgumentOffset * target::kWordSize));
158 __ Bind(normal_ir_body);
161void AsmIntrinsifier::Integer_equal(Assembler* assembler,
162 Label* normal_ir_body) {
163 Integer_equalToInteger(assembler, normal_ir_body);
166void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
167 Label* normal_ir_body) {
169 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
170#if defined(DART_COMPRESSED_POINTERS)
175 __ sarq(
RCX, Immediate(63));
185void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
189 __ movq(
RDI, Address(
RSP, 4 * target::kWordSize));
190 __ movq(
R8, Address(
RSP, 3 * target::kWordSize));
191#if defined(DART_COMPRESSED_POINTERS)
194 __ subq(
R8, Immediate(2));
195 __ sarq(
R8, Immediate(2));
196 __ movq(
RCX, Address(
RSP, 2 * target::kWordSize));
197#if defined(DART_COMPRESSED_POINTERS)
201 __ movq(
RBX, Address(
RSP, 1 * target::kWordSize));
203 __ sarq(
RSI, Immediate(6));
205 FieldAddress(
RBX,
RSI,
TIMES_8, target::TypedData::payload_offset()));
208 FieldAddress(
RDI,
R8,
TIMES_8, target::TypedData::payload_offset()));
212 __ cmpq(
R8, Immediate(0));
218 target::TypedData::payload_offset() -
231void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
235 __ movq(
RDI, Address(
RSP, 4 * target::kWordSize));
236 __ movq(
RCX, Address(
RSP, 2 * target::kWordSize));
237#if defined(DART_COMPRESSED_POINTERS)
241 __ movq(
RBX, Address(
RSP, 1 * target::kWordSize));
243 __ sarq(
RDX, Immediate(6));
244 __ movq(
RSI, Address(
RSP, 3 * target::kWordSize));
245#if defined(DART_COMPRESSED_POINTERS)
248 __ subq(
RSI, Immediate(2));
249 __ sarq(
RSI, Immediate(2));
251 FieldAddress(
RDI,
RSI,
TIMES_8, target::TypedData::payload_offset()));
254 FieldAddress(
RBX,
RSI,
TIMES_8, target::TypedData::payload_offset()));
258 __ cmpq(
RSI, Immediate(0));
275void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
276 Label* normal_ir_body) {
281 __ movq(
RDI, Address(
RSP, 5 * target::kWordSize));
282 __ movq(
R8, Address(
RSP, 4 * target::kWordSize));
283#if defined(DART_COMPRESSED_POINTERS)
286 __ addq(
R8, Immediate(2));
287 __ sarq(
R8, Immediate(2));
288 __ movq(
RSI, Address(
RSP, 3 * target::kWordSize));
289 __ movq(
RCX, Address(
RSP, 2 * target::kWordSize));
290#if defined(DART_COMPRESSED_POINTERS)
293 __ addq(
RCX, Immediate(2));
294 __ sarq(
RCX, Immediate(2));
295 __ movq(
RBX, Address(
RSP, 1 * target::kWordSize));
306 FieldAddress(
RDI,
RDX,
TIMES_8, target::TypedData::payload_offset()));
308 FieldAddress(
RSI,
RDX,
TIMES_8, target::TypedData::payload_offset()));
309 __ movq(FieldAddress(
RBX,
RDX,
TIMES_8, target::TypedData::payload_offset()),
320 __ Bind(&carry_loop);
323 FieldAddress(
RDI,
RDX,
TIMES_8, target::TypedData::payload_offset()));
324 __ adcq(
RAX, Immediate(0));
325 __ movq(FieldAddress(
RBX,
RDX,
TIMES_8, target::TypedData::payload_offset()),
331 __ Bind(&last_carry);
334 __ movq(FieldAddress(
RBX,
RDX,
TIMES_8, target::TypedData::payload_offset()),
342void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
343 Label* normal_ir_body) {
348 __ movq(
RDI, Address(
RSP, 5 * target::kWordSize));
349 __ movq(
R8, Address(
RSP, 4 * target::kWordSize));
350#if defined(DART_COMPRESSED_POINTERS)
353 __ addq(
R8, Immediate(2));
354 __ sarq(
R8, Immediate(2));
355 __ movq(
RSI, Address(
RSP, 3 * target::kWordSize));
356 __ movq(
RCX, Address(
RSP, 2 * target::kWordSize));
357#if defined(DART_COMPRESSED_POINTERS)
360 __ addq(
RCX, Immediate(2));
361 __ sarq(
RCX, Immediate(2));
362 __ movq(
RBX, Address(
RSP, 1 * target::kWordSize));
373 FieldAddress(
RDI,
RDX,
TIMES_8, target::TypedData::payload_offset()));
375 FieldAddress(
RSI,
RDX,
TIMES_8, target::TypedData::payload_offset()));
376 __ movq(FieldAddress(
RBX,
RDX,
TIMES_8, target::TypedData::payload_offset()),
387 __ Bind(&carry_loop);
390 FieldAddress(
RDI,
RDX,
TIMES_8, target::TypedData::payload_offset()));
391 __ sbbq(
RAX, Immediate(0));
392 __ movq(FieldAddress(
RBX,
RDX,
TIMES_8, target::TypedData::payload_offset()),
403void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
404 Label* normal_ir_body) {
435 __ movq(
RCX, Address(
RSP, 7 * target::kWordSize));
436 __ movq(
RAX, Address(
RSP, 6 * target::kWordSize));
437#if defined(DART_COMPRESSED_POINTERS)
441 FieldAddress(
RCX,
RAX,
TIMES_2, target::TypedData::payload_offset()));
446 __ movq(
R8, Address(
RSP, 1 * target::kWordSize));
447#if defined(DART_COMPRESSED_POINTERS)
450 __ addq(
R8, Immediate(2));
451 __ sarq(
R8, Immediate(2));
455 __ movq(
RDI, Address(
RSP, 5 * target::kWordSize));
456 __ movq(
RAX, Address(
RSP, 4 * target::kWordSize));
457#if defined(DART_COMPRESSED_POINTERS)
461 FieldAddress(
RDI,
RAX,
TIMES_2, target::TypedData::payload_offset()));
464 __ movq(
RSI, Address(
RSP, 3 * target::kWordSize));
465 __ movq(
RAX, Address(
RSP, 2 * target::kWordSize));
466#if defined(DART_COMPRESSED_POINTERS)
470 FieldAddress(
RSI,
RAX,
TIMES_2, target::TypedData::payload_offset()));
476 __ Bind(&muladd_loop);
491 __ adcq(
RDX, Immediate(0));
495 __ adcq(
RDX, Immediate(0));
515 Label propagate_carry_loop;
516 __ Bind(&propagate_carry_loop);
518 __ incq(Address(
RSI, 0));
526void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
527 Label* normal_ir_body) {
555 __ movq(
RDI, Address(
RSP, 4 * target::kWordSize));
556 __ movq(
RAX, Address(
RSP, 3 * target::kWordSize));
557#if defined(DART_COMPRESSED_POINTERS)
561 FieldAddress(
RDI,
RAX,
TIMES_2, target::TypedData::payload_offset()));
566 __ cmpq(
RBX, Immediate(0));
571 __ movq(
RSI, Address(
RSP, 2 * target::kWordSize));
573 FieldAddress(
RSI,
RAX,
TIMES_4, target::TypedData::payload_offset()));
579 __ adcq(
RDX, Immediate(0));
586 __ OBJ(mov)(
R8, Address(
RSP, 1 * target::kWordSize));
587 __ OBJ(sub)(
R8, Address(
RSP, 3 * target::kWordSize));
588 __ addq(
R8, Immediate(2));
589 __ sarq(
R8, Immediate(2));
618 __ shlq(
RAX, Immediate(1));
620 __ adcq(
RDX, Immediate(0));
621 __ adcq(
RCX, Immediate(0));
624 __ adcq(
RCX, Immediate(0));
639 __ adcq(
R13, Immediate(0));
651void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
652 Label* normal_ir_body) {
670 __ movq(
RDI, Address(
RSP, 3 * target::kWordSize));
673 __ movq(
RCX, FieldAddress(
RDI, target::TypedData::payload_offset()));
676 __ movq(
RBX, Address(
RSP, 2 * target::kWordSize));
677 __ movq(
RAX, Address(
RSP, 1 * target::kWordSize));
678#if defined(DART_COMPRESSED_POINTERS)
681 __ leaq(
RBX, FieldAddress(
689 __ movq(
RAX, Immediate(-1));
704 __ movq(FieldAddress(
RDI, target::TypedData::payload_offset() +
712void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
713 Label* normal_ir_body) {
724 __ movq(
RDI, Address(
RSP, 3 * target::kWordSize));
727 __ movq(
RCX, FieldAddress(
RDI, target::TypedData::payload_offset() +
731 __ movq(
RBX, Address(
RSP, 2 * target::kWordSize));
732 __ movq(
RAX, Address(
RSP, 1 * target::kWordSize));
733#if defined(DART_COMPRESSED_POINTERS)
737 FieldAddress(
RBX,
RAX,
TIMES_2, target::TypedData::payload_offset()));
743 __ movq(FieldAddress(
RDI, target::TypedData::payload_offset() +
754static void TestLastArgumentIsDouble(Assembler* assembler,
756 Label* not_double_smi) {
757 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
760 __ CompareClassId(
RAX, kDoubleCid);
769static void CompareDoubles(Assembler* assembler,
770 Label* normal_ir_body,
772 Label is_false, is_true, is_smi, double_op;
773 TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
775 __ movsd(
XMM1, FieldAddress(
RAX, target::Double::value_offset()));
777 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
778 __ movsd(
XMM0, FieldAddress(
RAX, target::Double::value_offset()));
793 __ Bind(normal_ir_body);
796void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
797 Label* normal_ir_body) {
798 CompareDoubles(assembler, normal_ir_body,
ABOVE);
801void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
802 Label* normal_ir_body) {
803 CompareDoubles(assembler, normal_ir_body,
ABOVE_EQUAL);
806void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
807 Label* normal_ir_body) {
808 CompareDoubles(assembler, normal_ir_body,
BELOW);
811void AsmIntrinsifier::Double_equal(Assembler* assembler,
812 Label* normal_ir_body) {
813 CompareDoubles(assembler, normal_ir_body,
EQUAL);
816void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
817 Label* normal_ir_body) {
818 CompareDoubles(assembler, normal_ir_body,
BELOW_EQUAL);
823static void DoubleArithmeticOperations(Assembler* assembler,
824 Label* normal_ir_body,
826 Label is_smi, double_op;
827 TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
829 __ movsd(
XMM1, FieldAddress(
RAX, target::Double::value_offset()));
831 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
832 __ movsd(
XMM0, FieldAddress(
RAX, target::Double::value_offset()));
853 __ movsd(FieldAddress(
RAX, target::Double::value_offset()),
XMM0);
859 __ Bind(normal_ir_body);
862void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
863 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
866void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
867 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
870void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
871 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
874void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
875 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
878void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
879 Label* normal_ir_body) {
881 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
887 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
888 __ movsd(
XMM0, FieldAddress(
RAX, target::Double::value_offset()));
894 __ movsd(FieldAddress(
RAX, target::Double::value_offset()),
XMM0);
896 __ Bind(normal_ir_body);
900void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
901 Label* normal_ir_body) {
902 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
912 __ movsd(FieldAddress(
RAX, target::Double::value_offset()),
XMM0);
914 __ Bind(normal_ir_body);
917void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
918 Label* normal_ir_body) {
920 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
921 __ movsd(
XMM0, FieldAddress(
RAX, target::Double::value_offset()));
931void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
932 Label* normal_ir_body) {
934 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
935 __ movq(
RAX, FieldAddress(
RAX, target::Double::value_offset()));
937 __ AndImmediate(
RAX, Immediate(0x7FFFFFFFFFFFFFFFLL));
939 __ CompareImmediate(
RAX, Immediate(0x7FF0000000000000LL));
951void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
952 Label* normal_ir_body) {
953 Label is_false, is_true, is_zero;
954 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
955 __ movsd(
XMM0, FieldAddress(
RAX, target::Double::value_offset()));
970 __ testq(
RAX, Immediate(1));
976void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
977 Label* normal_ir_body) {
979 const intptr_t kReceiverOffset = 2;
980 const intptr_t kArgumentOffset = 1;
982 __ movq(
RAX, Address(
RSP, +kArgumentOffset * target::kWordSize));
983 __ OBJ(cmp)(
RAX, Address(
RSP, +kReceiverOffset * target::kWordSize));
992static void JumpIfInteger(Assembler* assembler,
Register cid, Label* target) {
997static void JumpIfNotInteger(Assembler* assembler,
1004static void JumpIfString(Assembler* assembler,
Register cid, Label* target) {
1005 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1009static void JumpIfNotString(Assembler* assembler,
Register cid, Label* target) {
1010 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1014static void JumpIfNotList(Assembler* assembler,
Register cid, Label* target) {
1015 assembler->RangeCheck(
cid,
kNoRegister, kArrayCid, kGrowableObjectArrayCid,
1019static void JumpIfType(Assembler* assembler,
Register cid, Label* target) {
1021 (kRecordTypeCid == kTypeCid + 2));
1022 assembler->RangeCheck(
cid,
kNoRegister, kTypeCid, kRecordTypeCid,
1026static void JumpIfNotType(Assembler* assembler,
Register cid, Label* target) {
1028 (kRecordTypeCid == kTypeCid + 2));
1029 assembler->RangeCheck(
cid,
kNoRegister, kTypeCid, kRecordTypeCid,
1034void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
1035 Label* normal_ir_body) {
1036 Label use_declaration_type, not_integer, not_double, not_string;
1037 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
1041 __ cmpq(
RCX, Immediate(kClosureCid));
1044 __ cmpq(
RCX, Immediate(kRecordCid));
1048 __ j(
ABOVE, &use_declaration_type);
1051 __ cmpl(
RCX, Immediate(kDoubleCid));
1054 __ LoadIsolateGroup(
RAX);
1055 __ movq(
RAX, Address(
RAX, target::IsolateGroup::object_store_offset()));
1056 __ movq(
RAX, Address(
RAX, target::ObjectStore::double_type_offset()));
1059 __ Bind(¬_double);
1062 JumpIfNotInteger(assembler,
RAX, ¬_integer);
1064 __ LoadIsolateGroup(
RAX);
1065 __ movq(
RAX, Address(
RAX, target::IsolateGroup::object_store_offset()));
1066 __ movq(
RAX, Address(
RAX, target::ObjectStore::int_type_offset()));
1069 __ Bind(¬_integer);
1073 JumpIfNotString(assembler,
RAX, ¬_string);
1075 __ LoadIsolateGroup(
RAX);
1076 __ movq(
RAX, Address(
RAX, target::IsolateGroup::object_store_offset()));
1077 __ movq(
RAX, Address(
RAX, target::ObjectStore::string_type_offset()));
1080 __ Bind(¬_string);
1083 JumpIfNotType(assembler,
RAX, &use_declaration_type);
1085 __ LoadIsolateGroup(
RAX);
1086 __ movq(
RAX, Address(
RAX, target::IsolateGroup::object_store_offset()));
1087 __ movq(
RAX, Address(
RAX, target::ObjectStore::type_type_offset()));
1091 __ Bind(&use_declaration_type);
1093 __ movzxw(
RCX, FieldAddress(
RDI, target::Class::num_type_arguments_offset()));
1094 __ cmpq(
RCX, Immediate(0));
1097 RAX, FieldAddress(
RDI, target::Class::declaration_type_offset()));
1102 __ Bind(normal_ir_body);
1109static void EquivalentClassIds(Assembler* assembler,
1110 Label* normal_ir_body,
1111 Label* equal_may_be_generic,
1112 Label* equal_not_generic,
1117 bool testing_instance_cids) {
1118 Label not_integer, not_integer_or_string, not_integer_or_string_or_list;
1121 __ cmpq(cid1, Immediate(kClosureCid));
1125 __ cmpq(cid1, Immediate(kRecordCid));
1131 __ cmpq(cid1, cid2);
1132 __ j(
EQUAL, equal_may_be_generic);
1141 __ movq(scratch, cid1);
1142 JumpIfNotInteger(assembler, scratch, ¬_integer);
1145 __ movq(scratch, cid2);
1146 JumpIfInteger(assembler, scratch, equal_not_generic);
1150 __ Bind(¬_integer);
1152 __ movq(scratch, cid1);
1153 JumpIfNotString(assembler, scratch,
1154 testing_instance_cids ? ¬_integer_or_string : not_equal);
1157 __ movq(scratch, cid2);
1158 JumpIfString(assembler, scratch, equal_not_generic);
1162 if (testing_instance_cids) {
1163 __ Bind(¬_integer_or_string);
1165 __ movq(scratch, cid1);
1166 JumpIfNotList(assembler, scratch, ¬_integer_or_string_or_list);
1169 __ movq(scratch, cid2);
1170 JumpIfNotList(assembler, scratch, not_equal);
1171 ASSERT(compiler::target::Array::type_arguments_offset() ==
1172 compiler::target::GrowableObjectArray::type_arguments_offset());
1173 __ jmp(equal_may_be_generic);
1175 __ Bind(¬_integer_or_string_or_list);
1179 __ movq(scratch, cid1);
1180 JumpIfNotType(assembler, scratch, not_equal);
1183 __ movq(scratch, cid2);
1184 JumpIfType(assembler, scratch, equal_not_generic);
1190void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
1191 Label* normal_ir_body) {
1192 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
1195 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
1198 Label equal_may_be_generic,
equal, not_equal;
1199 EquivalentClassIds(assembler, normal_ir_body, &equal_may_be_generic, &
equal,
1203 __ Bind(&equal_may_be_generic);
1212 target::Class::host_type_arguments_field_offset_in_words_offset()));
1213 __ cmpl(
RAX, Immediate(target::Class::kNoTypeArguments));
1217 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1218 __ movq(
RDX, Address(
RSP, +2 * target::kWordSize));
1229 __ Bind(¬_equal);
1233 __ Bind(normal_ir_body);
1236void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1237 Label* normal_ir_body) {
1238 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
1239 __ movl(
RAX, FieldAddress(
RAX, target::String::hash_offset()));
1245 __ Bind(normal_ir_body);
1249void AsmIntrinsifier::Type_equality(Assembler* assembler,
1250 Label* normal_ir_body) {
1251 Label
equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
1253 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1254 __ movq(
RDX, Address(
RSP, +2 * target::kWordSize));
1261 __ cmpq(
RAX, Immediate(kTypeCid));
1268 EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
1272 __ Bind(&equiv_cids_may_be_generic);
1274 __ LoadCompressed(
RDI, FieldAddress(
RCX, target::Type::arguments_offset()));
1275 __ LoadCompressed(
RSI, FieldAddress(
RDX, target::Type::arguments_offset()));
1281 __ Bind(&equiv_cids);
1282 __ LoadAbstractTypeNullability(
RCX,
RCX);
1283 __ LoadAbstractTypeNullability(
RDX,
RDX);
1295 ASSERT(target::Nullability::kNullable < target::Nullability::kNonNullable &&
1296 target::Nullability::kNonNullable < target::Nullability::kLegacy);
1297 __ Bind(&check_legacy);
1298 __ cmpq(
RCX, Immediate(target::Nullability::kNonNullable));
1300 __ cmpq(
RDX, Immediate(target::Nullability::kNonNullable));
1303 __ Bind(¬_equal);
1307 __ Bind(normal_ir_body);
1310void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1311 Label* normal_ir_body) {
1312 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
1313 __ LoadCompressedSmi(
RAX,
1314 FieldAddress(
RAX, target::AbstractType::hash_offset()));
1320 __ Bind(normal_ir_body);
1324void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1325 Label* normal_ir_body) {
1326 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1327 __ movq(
RDX, Address(
RSP, +2 * target::kWordSize));
1334 __ Bind(normal_ir_body);
1341void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1342 Label* normal_ir_body) {
1343 Label not_yet_computed;
1344 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
1345 __ movl(
RAX, FieldAddress(
RAX, target::Object::tags_offset() +
1346 target::UntaggedObject::kHashTagPos /
1348 __ cmpl(
RAX, Immediate(0));
1353 __ Bind(¬_yet_computed);
1354 __ movq(
RCX, Address(
THR, target::Thread::random_offset()));
1356 __ andq(
RCX, Immediate(0xffffffff));
1357 __ shrq(
RBX, Immediate(32));
1358 __ imulq(
RCX, Immediate(0xffffda61));
1360 __ movq(Address(
THR, target::Thread::random_offset()),
RCX);
1361 __ andq(
RCX, Immediate(0x3fffffff));
1362 __ cmpl(
RCX, Immediate(0));
1363 __ j(
EQUAL, ¬_yet_computed);
1365 __ movq(
RBX, Address(
RSP, +1 * target::kWordSize));
1367 __ shlq(
RDX, Immediate(32));
1369 Label retry, success, already_in_rax;
1373 __ movq(
RAX, FieldAddress(
RBX, 0));
1374 __ TestImmediate(
RAX, Immediate(0xffffffff00000000));
1378 __ LockCmpxchgq(FieldAddress(
RBX, 0),
RSI);
1386 __ Bind(&already_in_rax);
1387 __ shrq(
RAX, Immediate(32));
1392void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1393 intptr_t receiver_cid,
1396 Label* return_false) {
1398 __ LoadCompressedSmi(
R8, FieldAddress(
RAX, target::String::length_offset()));
1400 __ LoadCompressedSmi(
R9, FieldAddress(
RCX, target::String::length_offset()));
1409 __ j(
SIGN, return_false);
1417 __ LoadImmediate(
R11, Immediate(0));
1427 if (receiver_cid == kOneByteStringCid) {
1429 target::OneByteString::data_offset()));
1431 ASSERT(receiver_cid == kTwoByteStringCid);
1433 target::TwoByteString::data_offset()));
1436 if (other_cid == kOneByteStringCid) {
1438 target::OneByteString::data_offset()));
1440 ASSERT(other_cid == kTwoByteStringCid);
1442 target::TwoByteString::data_offset()));
1448 __ addq(
R11, Immediate(1));
1452 __ jmp(return_true);
1458void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1459 Label* normal_ir_body) {
1460 Label return_true, return_false, try_two_byte;
1461 __ movq(
RAX, Address(
RSP, +3 * target::kWordSize));
1462 __ movq(
RBX, Address(
RSP, +2 * target::kWordSize));
1463 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1468 __ CompareClassId(
RCX, kOneByteStringCid);
1471 __ CompareClassId(
RAX, kOneByteStringCid);
1474 GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
1475 kOneByteStringCid, &return_true,
1478 __ Bind(&try_two_byte);
1479 __ CompareClassId(
RAX, kTwoByteStringCid);
1482 GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
1483 kOneByteStringCid, &return_true,
1486 __ Bind(&return_true);
1490 __ Bind(&return_false);
1494 __ Bind(normal_ir_body);
1497void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1498 Label* normal_ir_body) {
1499 Label try_two_byte_string;
1500 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1501 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
1505 __ OBJ(cmp)(
RCX, FieldAddress(
RAX, target::String::length_offset()));
1508 __ CompareClassId(
RAX, kOneByteStringCid);
1512 target::OneByteString::data_offset()));
1513 __ cmpq(
RCX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
1516 Address(
THR, target::Thread::predefined_symbols_address_offset()));
1518 target::Symbols::kNullCharCodeSymbolOffset *
1519 target::kWordSize));
1522 __ Bind(&try_two_byte_string);
1523 __ CompareClassId(
RAX, kTwoByteStringCid);
1526#if defined(DART_COMPRESSED_POINTERS)
1533 target::OneByteString::data_offset()));
1534 __ cmpq(
RCX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
1537 Address(
THR, target::Thread::predefined_symbols_address_offset()));
1539 target::Symbols::kNullCharCodeSymbolOffset *
1540 target::kWordSize));
1543 __ Bind(normal_ir_body);
1546void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1547 Label* normal_ir_body) {
1550 __ movq(
RAX, Address(
RSP, +1 * target::kWordSize));
1551 __ LoadCompressedSmi(
RAX, FieldAddress(
RAX, target::String::length_offset()));
1561void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1562 Label* normal_ir_body) {
1566 Address(
RSP, +1 * target::kWordSize));
1567 __ movl(
RAX, FieldAddress(
RBX, target::String::hash_offset()));
1568 __ cmpq(
RAX, Immediate(0));
1573 __ Bind(&compute_hash);
1575 __ LoadCompressedSmi(
RCX, FieldAddress(
RBX, target::String::length_offset()));
1590 target::OneByteString::data_offset()));
1599 __ FinalizeHashForSize(target::String::kHashBits,
RAX);
1600 __ shlq(
RAX, Immediate(target::UntaggedObject::kHashTagPos));
1603 __ orq(FieldAddress(
RBX, target::Object::tags_offset()),
RAX);
1604 __ sarq(
RAX, Immediate(target::UntaggedObject::kHashTagPos));
1612static void TryAllocateString(Assembler* assembler,
1614 intptr_t max_elements,
1618 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1620 __ BranchIfNotSmi(length_reg, failure);
1627 if (length_reg !=
RDI) {
1628 __ movq(
RDI, length_reg);
1630 Label pop_and_fail, not_zero_length;
1632 if (
cid == kOneByteStringCid) {
1639 const intptr_t fixed_size_plus_alignment_padding =
1640 target::String::InstanceSize() +
1642 __ addq(
RDI, Immediate(fixed_size_plus_alignment_padding));
1645 __ movq(
RAX, Address(
THR, target::Thread::top_offset()));
1656 __ cmpq(
RCX, Address(
THR, target::Thread::end_offset()));
1658 __ CheckAllocationCanary(
RAX);
1662 __ movq(Address(
THR, target::Thread::top_offset()),
RCX);
1667 ASSERT(target::kWordSize == 8);
1668 __ movq(Address(
RCX, -1 * target::kWordSize), Immediate(0));
1669 __ movq(Address(
RCX, -2 * target::kWordSize), Immediate(0));
1675 Label size_tag_overflow,
done;
1676 __ cmpq(
RDI, Immediate(target::UntaggedObject::kSizeTagMaxSizeTag));
1678 __ shlq(
RDI, Immediate(target::UntaggedObject::kTagBitsSizeTagPos -
1682 __ Bind(&size_tag_overflow);
1690 __ orq(
RDI, Immediate(tags));
1691 __ movq(FieldAddress(
RAX, target::Object::tags_offset()),
RDI);
1696#if DART_COMPRESSED_POINTERS
1698 __ movq(FieldAddress(
RAX, target::String::length_offset()),
1699 compiler::Immediate(0));
1701 __ StoreCompressedIntoObjectNoBarrier(
1702 RAX, FieldAddress(
RAX, target::String::length_offset()),
RDI);
1705 __ Bind(&pop_and_fail);
1714void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1715 Label* normal_ir_body) {
1716 const intptr_t kStringOffset = 3 * target::kWordSize;
1717 const intptr_t kStartIndexOffset = 2 * target::kWordSize;
1718 const intptr_t kEndIndexOffset = 1 * target::kWordSize;
1720 __ movq(
RSI, Address(
RSP, +kStartIndexOffset));
1721 __ movq(
RDI, Address(
RSP, +kEndIndexOffset));
1726 __ subq(
RDI, Address(
RSP, +kStartIndexOffset));
1727 TryAllocateString(assembler, kOneByteStringCid,
1728 target::OneByteString::kMaxNewSpaceElements, &
ok,
1729 normal_ir_body,
RDI);
1733 __ movq(
RSI, Address(
RSP, +kStringOffset));
1734 __ movq(
RBX, Address(
RSP, +kStartIndexOffset));
1737 target::OneByteString::data_offset()));
1740 __ movq(
RCX, Address(
RSP, +kEndIndexOffset));
1753 __ movb(FieldAddress(
RAX,
RDX,
TIMES_1, target::OneByteString::data_offset()),
1760 __ Bind(normal_ir_body);
1763void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1764 Label* normal_ir_body) {
1765 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1766 __ movq(
RBX, Address(
RSP, +2 * target::kWordSize));
1767 __ movq(
RAX, Address(
RSP, +3 * target::kWordSize));
1770 __ movb(FieldAddress(
RAX,
RBX,
TIMES_1, target::OneByteString::data_offset()),
1775void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1776 Label* normal_ir_body) {
1777 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1778 __ movq(
RBX, Address(
RSP, +2 * target::kWordSize));
1779 __ movq(
RAX, Address(
RSP, +3 * target::kWordSize));
1782#if defined(DART_COMPRESSED_POINTERS)
1788 __ movw(FieldAddress(
RAX,
RBX,
TIMES_1, target::TwoByteString::data_offset()),
1793void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1794 Label* normal_ir_body) {
1795 __ movq(
RDI, Address(
RSP, +1 * target::kWordSize));
1796#if defined(DART_COMPRESSED_POINTERS)
1800 TryAllocateString(assembler, kOneByteStringCid,
1801 target::OneByteString::kMaxNewSpaceElements, &
ok,
1802 normal_ir_body,
RDI);
1808 __ Bind(normal_ir_body);
1811void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1812 Label* normal_ir_body) {
1813 __ movq(
RDI, Address(
RSP, +1 * target::kWordSize));
1814#if defined(DART_COMPRESSED_POINTERS)
1818 TryAllocateString(assembler, kTwoByteStringCid,
1819 target::TwoByteString::kMaxNewSpaceElements, &
ok,
1820 normal_ir_body,
RDI);
1826 __ Bind(normal_ir_body);
1829void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1830 Label* normal_ir_body) {
1831 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
1832 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1838void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1839 Label* normal_ir_body) {
1840 __ movq(
RAX, Address(
RSP, +2 * target::kWordSize));
1841 __ movq(
RCX, Address(
RSP, +1 * target::kWordSize));
1847void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1848 Label* normal_ir_body,
1850 if (FLAG_interpret_irregexp)
return;
1852 const intptr_t kRegExpParamOffset = 3 * target::kWordSize;
1853 const intptr_t kStringParamOffset = 2 * target::kWordSize;
1863 __ movq(
RBX, Address(
RSP, kRegExpParamOffset));
1864 __ movq(
RDI, Address(
RSP, kStringParamOffset));
1866 __ SubImmediate(
RDI, Immediate(kOneByteStringCid));
1867#if !defined(DART_COMPRESSED_POINTERS)
1869 target::RegExp::function_offset(
1870 kOneByteStringCid, sticky)));
1873 target::RegExp::function_offset(
1874 kOneByteStringCid, sticky)));
1885 FieldAddress(
FUNCTION_REG, target::Function::entry_point_offset()));
1889void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
1890 Label* normal_ir_body) {
1891 __ LoadIsolate(
RAX);
1892 __ movq(
RAX, Address(
RAX, target::Isolate::default_tag_offset()));
1896void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
1897 Label* normal_ir_body) {
1898 __ LoadIsolate(
RAX);
1899 __ movq(
RAX, Address(
RAX, target::Isolate::current_tag_offset()));
1903void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
1904 Label* normal_ir_body) {
1905#if !defined(SUPPORT_TIMELINE)
1911 __ movq(
RAX, Address(
THR, target::Thread::dart_stream_offset()));
1913 __ movq(
RAX, Address(
RAX, target::TimelineStream::enabled_offset()));
1914 __ cmpq(
RAX, Immediate(0));
1920 __ Bind(&true_label);
1926void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
1927 Label* normal_ir_body) {
1928#if !defined(SUPPORT_TIMELINE)
1932 __ movq(
RAX, Address(
THR, target::Thread::next_task_id_offset()));
1935 __ movq(Address(
THR, target::Thread::next_task_id_offset()),
RBX);
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
static bool equal(const SkBitmap &a, const SkBitmap &b)
#define check(reporter, ref, unref, make, kill)
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()
@ TIMES_COMPRESSED_WORD_SIZE
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
ByteRegister ByteRegisterOf(Register reg)
static constexpr intptr_t kObjectAlignmentLog2
static constexpr intptr_t kObjectAlignment
#define NOT_IN_PRODUCT(code)