12#if defined(TARGET_ARCH_IA32)
14#define SHOULD_NOT_INCLUDE_RUNTIME
36static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
44void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
48 TestBothArgumentsSmis(assembler, normal_ir_body);
71 __ cmpl(
EBX, Immediate(0));
92static void Push64SmiOrMint(Assembler* assembler,
95 Label* not_smi_or_mint) {
102 __ sarl(tmp, Immediate(31));
107 __ CompareClassId(reg, kMintCid, tmp);
116 Label* normal_ir_body,
118 Label try_mint_smi, is_true, is_false, drop_two_fall_through, fall_through;
119 TestBothArgumentsSmis(assembler, &try_mint_smi);
131 Condition hi_true_cond, hi_false_cond, lo_false_cond;
132 switch (true_condition) {
142 hi_false_cond =
LESS;
147 hi_true_cond = hi_false_cond = lo_false_cond =
OVERFLOW;
155 Push64SmiOrMint(assembler,
EBX,
EDI, normal_ir_body);
157 Push64SmiOrMint(assembler,
EAX,
EDI, &drop_two_fall_through);
170 __ Bind(&drop_two_fall_through);
175void AsmIntrinsifier::Integer_lessThan(Assembler* assembler,
176 Label* normal_ir_body) {
180void AsmIntrinsifier::Integer_greaterThan(Assembler* assembler,
181 Label* normal_ir_body) {
185void AsmIntrinsifier::Integer_lessEqualThan(Assembler* assembler,
186 Label* normal_ir_body) {
190void AsmIntrinsifier::Integer_greaterEqualThan(Assembler* assembler,
191 Label* normal_ir_body) {
197void AsmIntrinsifier::Integer_equalToInteger(Assembler* assembler,
198 Label* normal_ir_body) {
199 Label true_label, check_for_mint;
216 Label receiver_not_smi;
226 __ CompareClassId(
EAX, kDoubleCid,
EDI);
232 __ Bind(&receiver_not_smi);
234 __ CompareClassId(
EAX, kMintCid,
EDI);
247void AsmIntrinsifier::Integer_equal(Assembler* assembler,
248 Label* normal_ir_body) {
249 Integer_equalToInteger(assembler, normal_ir_body);
253void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
254 Label* normal_ir_body) {
259 __ sarl(
ECX, Immediate(31));
269void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
282 __ sarl(
ESI, Immediate(5));
294 __ cmpl(
ESI, Immediate(0));
299 __ movl(
EDX, FieldAddress(
316void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
329 __ sarl(
EDX, Immediate(5));
343 __ cmpl(
ESI, Immediate(0));
363void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
364 Label* normal_ir_body) {
410 __ adcl(
EAX, Immediate(0));
418 __ movl(
EAX, Immediate(0));
419 __ adcl(
EAX, Immediate(0));
429void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
430 Label* normal_ir_body) {
476 __ sbbl(
EAX, Immediate(0));
490void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
491 Label* normal_ir_body) {
572 __ adcl(
EDX, Immediate(0));
576 __ adcl(
EDX, Immediate(0));
597 Label propagate_carry_loop;
598 __ Bind(&propagate_carry_loop);
600 __ incl(Address(
ESI, 0));
613void AsmIntrinsifier::Bigint_sqrAdd(Assembler* assembler,
614 Label* normal_ir_body) {
650 __ cmpl(
EBX, Immediate(0));
667 __ adcl(
EDX, Immediate(0));
681 __ pushl(Immediate(0));
710 __ shll(
EAX, Immediate(1));
712 __ adcl(
EDX, Immediate(0));
713 __ adcl(
ECX, Immediate(0));
714 __ addl(
EAX, cl_addr);
715 __ adcl(
EDX, ch_addr);
716 __ adcl(
ECX, Immediate(0));
723 __ movl(cl_addr,
EDX);
724 __ movl(ch_addr,
ECX);
730 __ movl(
EAX, cl_addr);
731 __ movl(
EDX, ch_addr);
733 __ adcl(
EDX, Immediate(0));
748void AsmIntrinsifier::Bigint_estimateQuotientDigit(Assembler* assembler,
749 Label* normal_ir_body) {
783 __ movl(
EAX, Immediate(-1));
806void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
807 Label* normal_ir_body) {
845static void TestLastArgumentIsDouble(Assembler* assembler,
847 Label* not_double_smi) {
851 __ CompareClassId(
EAX, kDoubleCid,
EBX);
860static void CompareDoubles(Assembler* assembler,
861 Label* normal_ir_body,
863 Label is_false, is_true, is_smi, double_op;
864 TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
888void AsmIntrinsifier::Double_greaterThan(Assembler* assembler,
889 Label* normal_ir_body) {
890 CompareDoubles(assembler, normal_ir_body,
ABOVE);
894void AsmIntrinsifier::Double_greaterEqualThan(Assembler* assembler,
895 Label* normal_ir_body) {
896 CompareDoubles(assembler, normal_ir_body,
ABOVE_EQUAL);
900void AsmIntrinsifier::Double_lessThan(Assembler* assembler,
901 Label* normal_ir_body) {
902 CompareDoubles(assembler, normal_ir_body,
BELOW);
906void AsmIntrinsifier::Double_equal(Assembler* assembler,
907 Label* normal_ir_body) {
908 CompareDoubles(assembler, normal_ir_body,
EQUAL);
912void AsmIntrinsifier::Double_lessEqualThan(Assembler* assembler,
913 Label* normal_ir_body) {
914 CompareDoubles(assembler, normal_ir_body,
BELOW_EQUAL);
919static void DoubleArithmeticOperations(Assembler* assembler,
920 Label* normal_ir_body,
922 Label is_smi, double_op;
923 TestLastArgumentIsDouble(assembler, &is_smi, normal_ir_body);
958void AsmIntrinsifier::Double_add(Assembler* assembler, Label* normal_ir_body) {
959 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kADD);
962void AsmIntrinsifier::Double_mul(Assembler* assembler, Label* normal_ir_body) {
963 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kMUL);
966void AsmIntrinsifier::Double_sub(Assembler* assembler, Label* normal_ir_body) {
967 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kSUB);
970void AsmIntrinsifier::Double_div(Assembler* assembler, Label* normal_ir_body) {
971 DoubleArithmeticOperations(assembler, normal_ir_body, Token::kDIV);
975void AsmIntrinsifier::Double_mulFromInteger(Assembler* assembler,
976 Label* normal_ir_body) {
996void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
997 Label* normal_ir_body) {
1013void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
1014 Label* normal_ir_body) {
1027void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
1028 Label* normal_ir_body) {
1034 __ cmpl(
EBX, Immediate(0));
1037 __ movl(
EBX, FieldAddress(
1040 __ andl(
EBX, Immediate(0x7FFFFFFF));
1042 __ cmpl(
EBX, Immediate(0x7FF00000));
1052void AsmIntrinsifier::Double_getIsNegative(Assembler* assembler,
1053 Label* normal_ir_body) {
1054 Label is_false, is_true, is_zero;
1071 __ testl(
EAX, Immediate(1));
1077void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
1078 Label* normal_ir_body) {
1095static void JumpIfNotInteger(Assembler* assembler,
1103 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1108 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1113 assembler->RangeCheck(
cid,
kNoRegister, kArrayCid, kGrowableObjectArrayCid,
1119 (kRecordTypeCid == kTypeCid + 2));
1120 assembler->RangeCheck(
cid,
kNoRegister, kTypeCid, kRecordTypeCid,
1126 (kRecordTypeCid == kTypeCid + 2));
1127 assembler->RangeCheck(
cid,
kNoRegister, kTypeCid, kRecordTypeCid,
1132void AsmIntrinsifier::ObjectRuntimeType(Assembler* assembler,
1133 Label* normal_ir_body) {
1134 Label use_declaration_type, not_double, not_integer, not_string;
1138 __ cmpl(
EDI, Immediate(kClosureCid));
1141 __ cmpl(
EDI, Immediate(kRecordCid));
1145 __ j(
ABOVE, &use_declaration_type);
1148 __ cmpl(
EDI, Immediate(kDoubleCid));
1151 __ LoadIsolateGroup(
EAX);
1159 JumpIfNotInteger(assembler,
EAX, ¬_integer);
1161 __ LoadIsolateGroup(
EAX);
1170 JumpIfNotString(assembler,
EAX, ¬_string);
1172 __ LoadIsolateGroup(
EAX);
1180 JumpIfNotType(assembler,
EAX, &use_declaration_type);
1182 __ LoadIsolateGroup(
EAX);
1188 __ Bind(&use_declaration_type);
1191 __ cmpl(
EDI, Immediate(0));
1205static void EquivalentClassIds(Assembler* assembler,
1206 Label* normal_ir_body,
1207 Label* equal_may_be_generic,
1208 Label* equal_not_generic,
1213 bool testing_instance_cids) {
1214 Label not_integer, not_integer_or_string, not_integer_or_string_or_list;
1217 __ cmpl(cid1, Immediate(kClosureCid));
1221 __ cmpl(cid1, Immediate(kRecordCid));
1227 __ cmpl(cid1, cid2);
1228 __ j(
EQUAL, equal_may_be_generic);
1237 __ movl(scratch, cid1);
1238 JumpIfNotInteger(assembler, scratch, ¬_integer);
1241 __ movl(scratch, cid2);
1242 JumpIfInteger(assembler, scratch, equal_not_generic);
1248 __ movl(scratch, cid1);
1249 JumpIfNotString(assembler, scratch,
1250 testing_instance_cids ? ¬_integer_or_string : not_equal);
1253 __ movl(scratch, cid2);
1254 JumpIfString(assembler, scratch, equal_not_generic);
1258 if (testing_instance_cids) {
1259 __ Bind(¬_integer_or_string);
1261 __ movl(scratch, cid1);
1262 JumpIfNotList(assembler, scratch, ¬_integer_or_string_or_list);
1265 __ movl(scratch, cid2);
1266 JumpIfNotList(assembler, scratch, not_equal);
1269 __ jmp(equal_may_be_generic);
1271 __ Bind(¬_integer_or_string_or_list);
1275 __ movl(scratch, cid1);
1276 JumpIfNotType(assembler, scratch, not_equal);
1279 __ movl(scratch, cid2);
1280 JumpIfType(assembler, scratch, equal_not_generic);
1286void AsmIntrinsifier::ObjectHaveSameRuntimeType(Assembler* assembler,
1287 Label* normal_ir_body) {
1294 Label equal_may_be_generic,
equal, not_equal;
1295 EquivalentClassIds(assembler, normal_ir_body, &equal_may_be_generic, &
equal,
1299 __ Bind(&equal_may_be_generic);
1332void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1333 Label* normal_ir_body) {
1336 __ cmpl(
EAX, Immediate(0));
1343void AsmIntrinsifier::Type_equality(Assembler* assembler,
1344 Label* normal_ir_body) {
1345 Label
equal, not_equal, equiv_cids_may_be_generic, equiv_cids;
1355 __ cmpl(
EAX, Immediate(kTypeCid));
1362 EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
1366 __ Bind(&equiv_cids_may_be_generic);
1376 __ LoadAbstractTypeNullability(
EDI,
EDI);
1377 __ LoadAbstractTypeNullability(
EBX,
EBX);
1393void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1394 Label* normal_ir_body) {
1404void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1405 Label* normal_ir_body) {
1418void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1419 Label* normal_ir_body) {
1423void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1424 Label* normal_ir_body) {
1428void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1429 Label* normal_ir_body) {
1430 Label try_two_byte_string;
1439 __ CompareClassId(
EAX, kOneByteStringCid,
EDI);
1446 __ movl(
EAX, Immediate(SymbolsPredefinedAddress()));
1452 __ Bind(&try_two_byte_string);
1453 __ CompareClassId(
EAX, kTwoByteStringCid,
EDI);
1460 __ movl(
EAX, Immediate(SymbolsPredefinedAddress()));
1469void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1470 Label* normal_ir_body) {
1484void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1485 Label* normal_ir_body) {
1489 __ cmpl(
EAX, Immediate(0));
1528static void TryAllocateString(Assembler* assembler,
1530 intptr_t max_elements,
1534 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1536 __ BranchIfNotSmi(length_reg, failure);
1543 if (length_reg !=
EDI) {
1544 __ movl(
EDI, length_reg);
1548 if (
cid == kOneByteStringCid) {
1553 const intptr_t fixed_size_plus_alignment_padding =
1557 fixed_size_plus_alignment_padding));
1573 __ CheckAllocationCanary(
EAX);
1590 Label size_tag_overflow,
done;
1597 __ Bind(&size_tag_overflow);
1604 __ orl(
EDI, Immediate(tags));
1610 __ StoreIntoObjectNoBarrier(
1625void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1626 Label* normal_ir_body) {
1631 __ movl(
EAX, Address(
ESP, +kStartIndexOffset));
1632 __ movl(
EDI, Address(
ESP, +kEndIndexOffset));
1637 __ subl(
EDI, Address(
ESP, +kStartIndexOffset));
1638 TryAllocateString(assembler, kOneByteStringCid,
1640 normal_ir_body,
EDI);
1644 __ movl(
EDI, Address(
ESP, +kStringOffset));
1645 __ movl(
EBX, Address(
ESP, +kStartIndexOffset));
1651 __ movl(
ECX, Address(
ESP, +kEndIndexOffset));
1674void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1675 Label* normal_ir_body) {
1686void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1687 Label* normal_ir_body) {
1698void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1699 Label* normal_ir_body) {
1702 TryAllocateString(assembler, kOneByteStringCid,
1704 normal_ir_body,
EDI);
1713void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1714 Label* normal_ir_body) {
1717 TryAllocateString(assembler, kTwoByteStringCid,
1719 normal_ir_body,
EDI);
1728void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1729 Label* normal_ir_body) {
1737void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1738 Label* normal_ir_body) {
1746void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1747 Label* normal_ir_body,
1749 if (FLAG_interpret_irregexp)
return;
1762 __ movl(
EBX, Address(
ESP, kRegExpParamOffset));
1763 __ movl(
EDI, Address(
ESP, kStringParamOffset));
1765 __ SubImmediate(
EDI, Immediate(kOneByteStringCid));
1768 kOneByteStringCid, sticky)));
1778void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
1779 Label* normal_ir_body) {
1780 __ LoadIsolate(
EAX);
1785void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
1786 Label* normal_ir_body) {
1787 __ LoadIsolate(
EAX);
1792void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
1793 Label* normal_ir_body) {
1794#if !defined(SUPPORT_TIMELINE)
1803 __ cmpl(
EAX, Immediate(0));
1815void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
1816 Label* normal_ir_body) {
1817#if !defined(SUPPORT_TIMELINE)
1825 __ addl(
EBX, Immediate(1));
1826 __ adcl(
ECX, Immediate(0));
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 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 value_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 dart_stream_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 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()
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
NOT_IN_PRODUCT(LibraryPtr ReloadTestScript(const char *script))
COMPILE_ASSERT(kUnreachableReference==WeakTable::kNoValue)
static bool Bind(PassBindingsCacheMTL &pass, ShaderStage stage, size_t bind_index, const BufferView &view)
SIN Vec< N, uint16_t > mull(const Vec< N, uint8_t > &x, const Vec< N, uint8_t > &y)
static constexpr intptr_t kObjectAlignmentLog2
static constexpr intptr_t kObjectAlignment