6#if defined(TARGET_ARCH_X64)
8#define SHOULD_NOT_INCLUDE_RUNTIME
31static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
39void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
43 TestBothArgumentsSmis(assembler, normal_ir_body);
71 Label* normal_ir_body,
74 TestBothArgumentsSmis(assembler, 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;
130 Label receiver_not_smi;
140 __ CompareClassId(
RAX, kDoubleCid);
145 __ Bind(&receiver_not_smi);
147 __ CompareClassId(
RAX, kMintCid);
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) {
170#if defined(DART_COMPRESSED_POINTERS)
175 __ sarq(
RCX, Immediate(63));
185void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
191#if defined(DART_COMPRESSED_POINTERS)
194 __ subq(
R8, Immediate(2));
195 __ sarq(
R8, Immediate(2));
197#if defined(DART_COMPRESSED_POINTERS)
203 __ sarq(
RSI, Immediate(6));
212 __ cmpq(
R8, Immediate(0));
231void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
237#if defined(DART_COMPRESSED_POINTERS)
243 __ sarq(
RDX, Immediate(6));
245#if defined(DART_COMPRESSED_POINTERS)
248 __ subq(
RSI, Immediate(2));
249 __ sarq(
RSI, Immediate(2));
258 __ cmpq(
RSI, Immediate(0));
275void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
276 Label* normal_ir_body) {
283#if defined(DART_COMPRESSED_POINTERS)
286 __ addq(
R8, Immediate(2));
287 __ sarq(
R8, Immediate(2));
290#if defined(DART_COMPRESSED_POINTERS)
293 __ addq(
RCX, Immediate(2));
294 __ sarq(
RCX, Immediate(2));
324 __ adcq(
RAX, Immediate(0));
342void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
343 Label* normal_ir_body) {
350#if defined(DART_COMPRESSED_POINTERS)
353 __ addq(
R8, Immediate(2));
354 __ sarq(
R8, Immediate(2));
357#if defined(DART_COMPRESSED_POINTERS)
360 __ addq(
RCX, Immediate(2));
361 __ sarq(
RCX, Immediate(2));
391 __ sbbq(
RAX, Immediate(0));
403void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
404 Label* normal_ir_body) {
437#if defined(DART_COMPRESSED_POINTERS)
447#if defined(DART_COMPRESSED_POINTERS)
450 __ addq(
R8, Immediate(2));
451 __ sarq(
R8, Immediate(2));
457#if defined(DART_COMPRESSED_POINTERS)
466#if defined(DART_COMPRESSED_POINTERS)
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) {
557#if defined(DART_COMPRESSED_POINTERS)
566 __ cmpq(
RBX, Immediate(0));
579 __ adcq(
RDX, Immediate(0));
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) {
678#if defined(DART_COMPRESSED_POINTERS)
681 __ leaq(
RBX, FieldAddress(
689 __ movq(
RAX, Immediate(-1));
712void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
713 Label* normal_ir_body) {
733#if defined(DART_COMPRESSED_POINTERS)
754static void TestLastArgumentIsDouble(Assembler* assembler,
756 Label* not_double_smi) {
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);
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);
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) {
900void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
901 Label* normal_ir_body) {
917void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
918 Label* normal_ir_body) {
931void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
932 Label* normal_ir_body) {
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;
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;
997static void JumpIfNotInteger(Assembler* assembler,
1005 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1010 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1015 assembler->RangeCheck(
cid,
kNoRegister, kArrayCid, kGrowableObjectArrayCid,
1021 (kRecordTypeCid == kTypeCid + 2));
1022 assembler->RangeCheck(
cid,
kNoRegister, kTypeCid, kRecordTypeCid,
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;
1041 __ cmpq(
RCX, Immediate(kClosureCid));
1044 __ cmpq(
RCX, Immediate(kRecordCid));
1048 __ j(
ABOVE, &use_declaration_type);
1051 __ cmpl(
RCX, Immediate(kDoubleCid));
1054 __ LoadIsolateGroup(
RAX);
1062 JumpIfNotInteger(assembler,
RAX, ¬_integer);
1064 __ LoadIsolateGroup(
RAX);
1073 JumpIfNotString(assembler,
RAX, ¬_string);
1075 __ LoadIsolateGroup(
RAX);
1083 JumpIfNotType(assembler,
RAX, &use_declaration_type);
1085 __ LoadIsolateGroup(
RAX);
1091 __ Bind(&use_declaration_type);
1094 __ cmpq(
RCX, Immediate(0));
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);
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);
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) {
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);
1236void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1237 Label* 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;
1261 __ cmpq(
RAX, Immediate(kTypeCid));
1268 EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
1272 __ Bind(&equiv_cids_may_be_generic);
1282 __ LoadAbstractTypeNullability(
RCX,
RCX);
1283 __ LoadAbstractTypeNullability(
RDX,
RDX);
1299void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1300 Label* normal_ir_body) {
1302 __ LoadCompressedSmi(
RAX,
1313void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1314 Label* normal_ir_body) {
1330void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1331 Label* normal_ir_body) {
1332 Label not_yet_computed;
1337 __ cmpl(
RAX, Immediate(0));
1342 __ Bind(¬_yet_computed);
1345 __ andq(
RCX, Immediate(0xffffffff));
1346 __ shrq(
RBX, Immediate(32));
1347 __ imulq(
RCX, Immediate(0xffffda61));
1350 __ andq(
RCX, Immediate(0x3fffffff));
1351 __ cmpl(
RCX, Immediate(0));
1352 __ j(
EQUAL, ¬_yet_computed);
1356 __ shlq(
RDX, Immediate(32));
1358 Label retry, success, already_in_rax;
1362 __ movq(
RAX, FieldAddress(
RBX, 0));
1363 __ TestImmediate(
RAX, Immediate(0xffffffff00000000));
1367 __ LockCmpxchgq(FieldAddress(
RBX, 0),
RSI);
1375 __ Bind(&already_in_rax);
1376 __ shrq(
RAX, Immediate(32));
1381void GenerateSubstringMatchesSpecialization(Assembler* assembler,
1382 intptr_t receiver_cid,
1385 Label* return_false) {
1398 __ j(
SIGN, return_false);
1406 __ LoadImmediate(
R11, Immediate(0));
1416 if (receiver_cid == kOneByteStringCid) {
1420 ASSERT(receiver_cid == kTwoByteStringCid);
1425 if (other_cid == kOneByteStringCid) {
1429 ASSERT(other_cid == kTwoByteStringCid);
1437 __ addq(
R11, Immediate(1));
1441 __ jmp(return_true);
1447void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1448 Label* normal_ir_body) {
1449 Label return_true, return_false, try_two_byte;
1457 __ CompareClassId(
RCX, kOneByteStringCid);
1460 __ CompareClassId(
RAX, kOneByteStringCid);
1463 GenerateSubstringMatchesSpecialization(assembler, kOneByteStringCid,
1464 kOneByteStringCid, &return_true,
1468 __ CompareClassId(
RAX, kTwoByteStringCid);
1471 GenerateSubstringMatchesSpecialization(assembler, kTwoByteStringCid,
1472 kOneByteStringCid, &return_true,
1486void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1487 Label* normal_ir_body) {
1488 Label try_two_byte_string;
1497 __ CompareClassId(
RAX, kOneByteStringCid);
1511 __ Bind(&try_two_byte_string);
1512 __ CompareClassId(
RAX, kTwoByteStringCid);
1515#if defined(DART_COMPRESSED_POINTERS)
1535void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1536 Label* normal_ir_body) {
1550void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1551 Label* normal_ir_body) {
1557 __ cmpq(
RAX, Immediate(0));
1601static void TryAllocateString(Assembler* assembler,
1603 intptr_t max_elements,
1607 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1609 __ BranchIfNotSmi(length_reg, failure);
1616 if (length_reg !=
RDI) {
1617 __ movq(
RDI, length_reg);
1619 Label pop_and_fail, not_zero_length;
1621 if (
cid == kOneByteStringCid) {
1628 const intptr_t fixed_size_plus_alignment_padding =
1631 __ addq(
RDI, Immediate(fixed_size_plus_alignment_padding));
1647 __ CheckAllocationCanary(
RAX);
1664 Label size_tag_overflow,
done;
1671 __ Bind(&size_tag_overflow);
1679 __ orq(
RDI, Immediate(tags));
1685#if DART_COMPRESSED_POINTERS
1688 compiler::Immediate(0));
1690 __ StoreCompressedIntoObjectNoBarrier(
1703void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1704 Label* normal_ir_body) {
1709 __ movq(
RSI, Address(
RSP, +kStartIndexOffset));
1710 __ movq(
RDI, Address(
RSP, +kEndIndexOffset));
1715 __ subq(
RDI, Address(
RSP, +kStartIndexOffset));
1716 TryAllocateString(assembler, kOneByteStringCid,
1718 normal_ir_body,
RDI);
1722 __ movq(
RSI, Address(
RSP, +kStringOffset));
1723 __ movq(
RBX, Address(
RSP, +kStartIndexOffset));
1729 __ movq(
RCX, Address(
RSP, +kEndIndexOffset));
1752void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1753 Label* normal_ir_body) {
1764void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1765 Label* normal_ir_body) {
1771#if defined(DART_COMPRESSED_POINTERS)
1782void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1783 Label* normal_ir_body) {
1785#if defined(DART_COMPRESSED_POINTERS)
1789 TryAllocateString(assembler, kOneByteStringCid,
1791 normal_ir_body,
RDI);
1800void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1801 Label* normal_ir_body) {
1803#if defined(DART_COMPRESSED_POINTERS)
1807 TryAllocateString(assembler, kTwoByteStringCid,
1809 normal_ir_body,
RDI);
1818void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1819 Label* normal_ir_body) {
1827void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1828 Label* normal_ir_body) {
1836void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1837 Label* normal_ir_body,
1839 if (FLAG_interpret_irregexp)
return;
1852 __ movq(
RBX, Address(
RSP, kRegExpParamOffset));
1853 __ movq(
RDI, Address(
RSP, kStringParamOffset));
1855 __ SubImmediate(
RDI, Immediate(kOneByteStringCid));
1856#if !defined(DART_COMPRESSED_POINTERS)
1859 kOneByteStringCid, sticky)));
1863 kOneByteStringCid, sticky)));
1878void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
1879 Label* normal_ir_body) {
1880 __ LoadIsolate(
RAX);
1885void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
1886 Label* normal_ir_body) {
1887 __ LoadIsolate(
RAX);
1892void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
1893 Label* normal_ir_body) {
1894#if !defined(SUPPORT_TIMELINE)
1903 __ cmpq(
RAX, Immediate(0));
1915void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
1916 Label* normal_ir_body) {
1917#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)
#define check(reporter, ref, unref, make, kill)
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)
word ToRawSmi(const dart::Object &a)
static constexpr intptr_t kWordSize
constexpr intptr_t kSmiBits
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
NOT_IN_PRODUCT(LibraryPtr ReloadTestScript(const char *script))
COMPILE_ASSERT(kUnreachableReference==WeakTable::kNoValue)
ByteRegister ByteRegisterOf(Register reg)
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
static constexpr intptr_t kObjectAlignmentLog2
static constexpr intptr_t kObjectAlignment