12#if defined(TARGET_ARCH_IA32)
14#define SHOULD_NOT_INCLUDE_RUNTIME
36static void TestBothArgumentsSmis(Assembler* assembler, Label* not_smi) {
37 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
38 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
44void AsmIntrinsifier::Integer_shl(Assembler* assembler, Label* normal_ir_body) {
48 TestBothArgumentsSmis(assembler, normal_ir_body);
55 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
71 __ cmpl(
EBX, Immediate(0));
85 __ movl(FieldAddress(
EAX, target::Mint::value_offset()),
EBX);
86 __ movl(FieldAddress(
EAX, target::Mint::value_offset() + target::kWordSize),
89 __ Bind(normal_ir_body);
92static void Push64SmiOrMint(Assembler* assembler,
95 Label* not_smi_or_mint) {
102 __ sarl(tmp, Immediate(31));
107 __ CompareClassId(reg, kMintCid, tmp);
110 __ pushl(FieldAddress(reg, target::Mint::value_offset() + target::kWordSize));
111 __ pushl(FieldAddress(reg, target::Mint::value_offset()));
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);
121 __ cmpl(Address(
ESP, +2 * target::kWordSize),
EAX);
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;
149 __ Bind(&try_mint_smi);
153 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
155 Push64SmiOrMint(assembler,
EBX,
EDI, normal_ir_body);
157 Push64SmiOrMint(assembler,
EAX,
EDI, &drop_two_fall_through);
170 __ Bind(&drop_two_fall_through);
172 __ Bind(normal_ir_body);
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;
201 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
202 __ cmpl(
EAX, Address(
ESP, +2 * target::kWordSize));
204 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
211 __ Bind(&true_label);
216 Label receiver_not_smi;
217 __ Bind(&check_for_mint);
218 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
225 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
226 __ CompareClassId(
EAX, kDoubleCid,
EDI);
232 __ Bind(&receiver_not_smi);
234 __ CompareClassId(
EAX, kMintCid,
EDI);
237 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
244 __ Bind(normal_ir_body);
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) {
256 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
259 __ sarl(
ECX, Immediate(31));
269void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {
277 __ movl(
EDI, Address(
ESP, 5 * target::kWordSize));
278 __ movl(
ECX, Address(
ESP, 3 * target::kWordSize));
280 __ movl(
EBX, Address(
ESP, 2 * target::kWordSize));
282 __ sarl(
ESI, Immediate(5));
284 FieldAddress(
EBX,
ESI,
TIMES_4, target::TypedData::payload_offset()));
285 __ movl(
ESI, Address(
ESP, 4 * target::kWordSize));
290 FieldAddress(
EDI,
ESI,
TIMES_4, target::TypedData::payload_offset()));
294 __ cmpl(
ESI, Immediate(0));
299 __ movl(
EDX, FieldAddress(
316void AsmIntrinsifier::Bigint_rsh(Assembler* assembler, Label* normal_ir_body) {
324 __ movl(
EDI, Address(
ESP, 5 * target::kWordSize));
325 __ movl(
ECX, Address(
ESP, 3 * target::kWordSize));
327 __ movl(
EBX, Address(
ESP, 2 * target::kWordSize));
329 __ sarl(
EDX, Immediate(5));
330 __ movl(
ESI, Address(
ESP, 4 * target::kWordSize));
335 FieldAddress(
EDI,
ESI,
TIMES_4, target::TypedData::payload_offset()));
339 FieldAddress(
EBX,
ESI,
TIMES_4, target::TypedData::payload_offset()));
343 __ cmpl(
ESI, Immediate(0));
363void AsmIntrinsifier::Bigint_absAdd(Assembler* assembler,
364 Label* normal_ir_body) {
373 __ movl(
EDI, Address(
ESP, 6 * target::kWordSize));
374 __ movl(
EAX, Address(
ESP, 5 * target::kWordSize));
376 __ movl(
ESI, Address(
ESP, 4 * target::kWordSize));
377 __ movl(
ECX, Address(
ESP, 3 * target::kWordSize));
379 __ movl(
EBX, Address(
ESP, 2 * target::kWordSize));
391 FieldAddress(
EDI,
EDX,
TIMES_4, target::TypedData::payload_offset()));
393 FieldAddress(
ESI,
EDX,
TIMES_4, target::TypedData::payload_offset()));
394 __ movl(FieldAddress(
EBX,
EDX,
TIMES_4, target::TypedData::payload_offset()),
406 __ Bind(&carry_loop);
409 FieldAddress(
EDI,
EDX,
TIMES_4, target::TypedData::payload_offset()));
410 __ adcl(
EAX, Immediate(0));
411 __ movl(FieldAddress(
EBX,
EDX,
TIMES_4, target::TypedData::payload_offset()),
417 __ Bind(&last_carry);
418 __ movl(
EAX, Immediate(0));
419 __ adcl(
EAX, Immediate(0));
420 __ movl(FieldAddress(
EBX,
EDX,
TIMES_4, target::TypedData::payload_offset()),
429void AsmIntrinsifier::Bigint_absSub(Assembler* assembler,
430 Label* normal_ir_body) {
439 __ movl(
EDI, Address(
ESP, 6 * target::kWordSize));
440 __ movl(
EAX, Address(
ESP, 5 * target::kWordSize));
442 __ movl(
ESI, Address(
ESP, 4 * target::kWordSize));
443 __ movl(
ECX, Address(
ESP, 3 * target::kWordSize));
445 __ movl(
EBX, Address(
ESP, 2 * target::kWordSize));
457 FieldAddress(
EDI,
EDX,
TIMES_4, target::TypedData::payload_offset()));
459 FieldAddress(
ESI,
EDX,
TIMES_4, target::TypedData::payload_offset()));
460 __ movl(FieldAddress(
EBX,
EDX,
TIMES_4, target::TypedData::payload_offset()),
472 __ Bind(&carry_loop);
475 FieldAddress(
EDI,
EDX,
TIMES_4, target::TypedData::payload_offset()));
476 __ sbbl(
EAX, Immediate(0));
477 __ movl(FieldAddress(
EBX,
EDX,
TIMES_4, target::TypedData::payload_offset()),
490void AsmIntrinsifier::Bigint_mulAdd(Assembler* assembler,
491 Label* normal_ir_body) {
521 __ movl(
ECX, Address(
ESP, 7 * target::kWordSize));
522 __ movl(
EAX, Address(
ESP, 6 * target::kWordSize));
524 FieldAddress(
ECX,
EAX,
TIMES_2, target::TypedData::payload_offset()));
529 __ movl(
EDX, Address(
ESP, 1 * target::kWordSize));
538 __ movl(
EDI, Address(
ESP, 6 * target::kWordSize));
539 __ movl(
EAX, Address(
ESP, 5 * target::kWordSize));
541 FieldAddress(
EDI,
EAX,
TIMES_2, target::TypedData::payload_offset()));
544 __ movl(
ESI, Address(
ESP, 4 * target::kWordSize));
545 __ movl(
EAX, Address(
ESP, 3 * target::kWordSize));
547 FieldAddress(
ESI,
EAX,
TIMES_2, target::TypedData::payload_offset()));
551 Address n_addr = Address(
ESP, 0 * target::kWordSize);
557 __ Bind(&muladd_loop);
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) {
642 __ movl(
EDI, Address(
ESP, 4 * target::kWordSize));
643 __ movl(
EAX, Address(
ESP, 3 * target::kWordSize));
645 FieldAddress(
EDI,
EAX,
TIMES_2, target::TypedData::payload_offset()));
650 __ cmpl(
EBX, Immediate(0));
659 __ movl(
ESI, Address(
ESP, 3 * target::kWordSize));
661 FieldAddress(
ESI,
EAX,
TIMES_4, target::TypedData::payload_offset()));
667 __ adcl(
EDX, Immediate(0));
674 __ movl(
EAX, Address(
ESP, 2 * target::kWordSize));
675 __ subl(
EAX, Address(
ESP, 4 * target::kWordSize));
681 __ pushl(Immediate(0));
684 Address n_addr = Address(
ESP, 2 * target::kWordSize);
685 Address ch_addr = Address(
ESP, 1 * target::kWordSize);
686 Address cl_addr = Address(
ESP, 0 * target::kWordSize);
698 __ decl(Address(
ESP, 2 * target::kWordSize));
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) {
767 __ movl(
EDI, Address(
ESP, 3 * target::kWordSize));
770 __ movl(
ECX, FieldAddress(
EDI, target::TypedData::payload_offset() +
774 __ movl(
EBX, Address(
ESP, 2 * target::kWordSize));
775 __ movl(
EAX, Address(
ESP, 1 * target::kWordSize));
777 FieldAddress(
EBX,
EAX,
TIMES_2, target::TypedData::payload_offset()));
783 __ movl(
EAX, Immediate(-1));
798 __ movl(FieldAddress(
EDI, target::TypedData::payload_offset() +
806void AsmIntrinsifier::Montgomery_mulMod(Assembler* assembler,
807 Label* normal_ir_body) {
818 __ movl(
EDI, Address(
ESP, 3 * target::kWordSize));
821 __ movl(
ECX, FieldAddress(
EDI, target::TypedData::payload_offset() +
825 __ movl(
EBX, Address(
ESP, 2 * target::kWordSize));
826 __ movl(
EAX, Address(
ESP, 1 * target::kWordSize));
828 FieldAddress(
EBX,
EAX,
TIMES_2, target::TypedData::payload_offset()));
834 __ movl(FieldAddress(
EDI, target::TypedData::payload_offset() +
845static void TestLastArgumentIsDouble(Assembler* assembler,
847 Label* not_double_smi) {
848 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
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);
866 __ movsd(
XMM1, FieldAddress(
EAX, target::Double::value_offset()));
868 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
869 __ movsd(
XMM0, FieldAddress(
EAX, target::Double::value_offset()));
884 __ Bind(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);
925 __ movsd(
XMM1, FieldAddress(
EAX, target::Double::value_offset()));
927 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
928 __ movsd(
XMM0, FieldAddress(
EAX, target::Double::value_offset()));
949 __ movsd(FieldAddress(
EAX, target::Double::value_offset()),
XMM0);
955 __ Bind(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) {
978 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
984 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
985 __ movsd(
XMM0, FieldAddress(
EAX, target::Double::value_offset()));
991 __ movsd(FieldAddress(
EAX, target::Double::value_offset()),
XMM0);
993 __ Bind(normal_ir_body);
996void AsmIntrinsifier::DoubleFromInteger(Assembler* assembler,
997 Label* normal_ir_body) {
998 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1008 __ movsd(FieldAddress(
EAX, target::Double::value_offset()),
XMM0);
1010 __ Bind(normal_ir_body);
1013void AsmIntrinsifier::Double_getIsNaN(Assembler* assembler,
1014 Label* normal_ir_body) {
1016 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1017 __ movsd(
XMM0, FieldAddress(
EAX, target::Double::value_offset()));
1027void AsmIntrinsifier::Double_getIsInfinite(Assembler* assembler,
1028 Label* normal_ir_body) {
1030 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1031 __ movl(
EBX, FieldAddress(
EAX, target::Double::value_offset()));
1034 __ cmpl(
EBX, Immediate(0));
1037 __ movl(
EBX, FieldAddress(
1038 EAX, target::Double::value_offset() + target::kWordSize));
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;
1055 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1056 __ movsd(
XMM0, FieldAddress(
EAX, target::Double::value_offset()));
1071 __ testl(
EAX, Immediate(1));
1077void AsmIntrinsifier::ObjectEquals(Assembler* assembler,
1078 Label* normal_ir_body) {
1080 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1081 __ cmpl(
EAX, Address(
ESP, +2 * target::kWordSize));
1090static void JumpIfInteger(Assembler* assembler,
Register cid, Label* target) {
1095static void JumpIfNotInteger(Assembler* assembler,
1102static void JumpIfString(Assembler* assembler,
Register cid, Label* target) {
1103 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1107static void JumpIfNotString(Assembler* assembler,
Register cid, Label* target) {
1108 assembler->RangeCheck(
cid,
kNoRegister, kOneByteStringCid, kTwoByteStringCid,
1112static void JumpIfNotList(Assembler* assembler,
Register cid, Label* target) {
1113 assembler->RangeCheck(
cid,
kNoRegister, kArrayCid, kGrowableObjectArrayCid,
1117static void JumpIfType(Assembler* assembler,
Register cid, Label* target) {
1119 (kRecordTypeCid == kTypeCid + 2));
1120 assembler->RangeCheck(
cid,
kNoRegister, kTypeCid, kRecordTypeCid,
1124static void JumpIfNotType(Assembler* assembler,
Register cid, Label* target) {
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;
1135 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1138 __ cmpl(
EDI, Immediate(kClosureCid));
1141 __ cmpl(
EDI, Immediate(kRecordCid));
1145 __ j(
ABOVE, &use_declaration_type);
1148 __ cmpl(
EDI, Immediate(kDoubleCid));
1151 __ LoadIsolateGroup(
EAX);
1152 __ movl(
EAX, Address(
EAX, target::IsolateGroup::object_store_offset()));
1153 __ movl(
EAX, Address(
EAX, target::ObjectStore::double_type_offset()));
1156 __ Bind(¬_double);
1159 JumpIfNotInteger(assembler,
EAX, ¬_integer);
1161 __ LoadIsolateGroup(
EAX);
1162 __ movl(
EAX, Address(
EAX, target::IsolateGroup::object_store_offset()));
1163 __ movl(
EAX, Address(
EAX, target::ObjectStore::int_type_offset()));
1166 __ Bind(¬_integer);
1170 JumpIfNotString(assembler,
EAX, ¬_string);
1172 __ LoadIsolateGroup(
EAX);
1173 __ movl(
EAX, Address(
EAX, target::IsolateGroup::object_store_offset()));
1174 __ movl(
EAX, Address(
EAX, target::ObjectStore::string_type_offset()));
1177 __ Bind(¬_string);
1180 JumpIfNotType(assembler,
EAX, &use_declaration_type);
1182 __ LoadIsolateGroup(
EAX);
1183 __ movl(
EAX, Address(
EAX, target::IsolateGroup::object_store_offset()));
1184 __ movl(
EAX, Address(
EAX, target::ObjectStore::type_type_offset()));
1188 __ Bind(&use_declaration_type);
1190 __ movzxw(
EDI, FieldAddress(
EBX, target::Class::num_type_arguments_offset()));
1191 __ cmpl(
EDI, Immediate(0));
1193 __ movl(
EAX, FieldAddress(
EBX, target::Class::declaration_type_offset()));
1198 __ Bind(normal_ir_body);
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);
1246 __ Bind(¬_integer);
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);
1267 ASSERT(compiler::target::Array::type_arguments_offset() ==
1268 compiler::target::GrowableObjectArray::type_arguments_offset());
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) {
1288 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1291 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
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);
1308 target::Class::host_type_arguments_field_offset_in_words_offset()));
1309 __ cmpl(
EAX, Immediate(target::Class::kNoTypeArguments));
1313 __ movl(
EDI, Address(
ESP, +1 * target::kWordSize));
1314 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
1325 __ Bind(¬_equal);
1329 __ Bind(normal_ir_body);
1332void AsmIntrinsifier::String_getHashCode(Assembler* assembler,
1333 Label* normal_ir_body) {
1334 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1335 __ movl(
EAX, FieldAddress(
EAX, target::String::hash_offset()));
1336 __ cmpl(
EAX, Immediate(0));
1339 __ Bind(normal_ir_body);
1343void AsmIntrinsifier::Type_equality(Assembler* assembler,
1344 Label* normal_ir_body) {
1345 Label
equal, not_equal, equiv_cids_may_be_generic, equiv_cids, check_legacy;
1347 __ movl(
EDI, Address(
ESP, +1 * target::kWordSize));
1348 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
1355 __ cmpl(
EAX, Immediate(kTypeCid));
1362 EquivalentClassIds(assembler, normal_ir_body, &equiv_cids_may_be_generic,
1366 __ Bind(&equiv_cids_may_be_generic);
1368 __ movl(
ECX, FieldAddress(
EDI, target::Type::arguments_offset()));
1369 __ movl(
EDX, FieldAddress(
EBX, target::Type::arguments_offset()));
1375 __ Bind(&equiv_cids);
1376 __ LoadAbstractTypeNullability(
EDI,
EDI);
1377 __ LoadAbstractTypeNullability(
EBX,
EBX);
1389 ASSERT(target::Nullability::kNullable < target::Nullability::kNonNullable &&
1390 target::Nullability::kNonNullable < target::Nullability::kLegacy);
1391 __ Bind(&check_legacy);
1392 __ cmpl(
EDI, Immediate(target::Nullability::kNonNullable));
1394 __ cmpl(
EBX, Immediate(target::Nullability::kNonNullable));
1397 __ Bind(¬_equal);
1401 __ Bind(normal_ir_body);
1404void AsmIntrinsifier::AbstractType_getHashCode(Assembler* assembler,
1405 Label* normal_ir_body) {
1406 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1407 __ movl(
EAX, FieldAddress(
EAX, target::AbstractType::hash_offset()));
1411 __ Bind(normal_ir_body);
1415void AsmIntrinsifier::AbstractType_equality(Assembler* assembler,
1416 Label* normal_ir_body) {
1417 __ movl(
EDI, Address(
ESP, +1 * target::kWordSize));
1418 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
1425 __ Bind(normal_ir_body);
1429void AsmIntrinsifier::StringBaseSubstringMatches(Assembler* assembler,
1430 Label* normal_ir_body) {
1434void AsmIntrinsifier::Object_getHash(Assembler* assembler,
1435 Label* normal_ir_body) {
1439void AsmIntrinsifier::StringBaseCharAt(Assembler* assembler,
1440 Label* normal_ir_body) {
1441 Label try_two_byte_string;
1442 __ movl(
EBX, Address(
ESP, +1 * target::kWordSize));
1443 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
1447 __ cmpl(
EBX, FieldAddress(
EAX, target::String::length_offset()));
1450 __ CompareClassId(
EAX, kOneByteStringCid,
EDI);
1454 target::OneByteString::data_offset()));
1455 __ cmpl(
EBX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
1457 __ movl(
EAX, Immediate(SymbolsPredefinedAddress()));
1459 target::Symbols::kNullCharCodeSymbolOffset *
1460 target::kWordSize));
1463 __ Bind(&try_two_byte_string);
1464 __ CompareClassId(
EAX, kTwoByteStringCid,
EDI);
1468 target::TwoByteString::data_offset()));
1469 __ cmpl(
EBX, Immediate(target::Symbols::kNumberOfOneCharCodeSymbols));
1471 __ movl(
EAX, Immediate(SymbolsPredefinedAddress()));
1473 target::Symbols::kNullCharCodeSymbolOffset *
1474 target::kWordSize));
1477 __ Bind(normal_ir_body);
1480void AsmIntrinsifier::StringBaseIsEmpty(Assembler* assembler,
1481 Label* normal_ir_body) {
1484 __ movl(
EAX, Address(
ESP, +1 * target::kWordSize));
1485 __ movl(
EAX, FieldAddress(
EAX, target::String::length_offset()));
1495void AsmIntrinsifier::OneByteString_getHashCode(Assembler* assembler,
1496 Label* normal_ir_body) {
1498 __ movl(
EBX, Address(
ESP, +1 * target::kWordSize));
1499 __ movl(
EAX, FieldAddress(
EBX, target::String::hash_offset()));
1500 __ cmpl(
EAX, Immediate(0));
1504 __ Bind(&compute_hash);
1506 __ movl(
ECX, FieldAddress(
EBX, target::String::length_offset()));
1521 target::OneByteString::data_offset()));
1530 __ FinalizeHashForSize(target::String::kHashBits,
EAX,
EDX);
1532 __ StoreIntoSmiField(FieldAddress(
EBX, target::String::hash_offset()),
EAX);
1539static void TryAllocateString(Assembler* assembler,
1541 intptr_t max_elements,
1545 ASSERT(
cid == kOneByteStringCid ||
cid == kTwoByteStringCid);
1547 __ BranchIfNotSmi(length_reg, failure);
1554 if (length_reg !=
EDI) {
1555 __ movl(
EDI, length_reg);
1559 if (
cid == kOneByteStringCid) {
1564 const intptr_t fixed_size_plus_alignment_padding =
1565 target::String::InstanceSize() +
1568 fixed_size_plus_alignment_padding));
1571 __ movl(
EAX, Address(
THR, target::Thread::top_offset()));
1582 __ cmpl(
EBX, Address(
THR, target::Thread::end_offset()));
1584 __ CheckAllocationCanary(
EAX);
1588 __ movl(Address(
THR, target::Thread::top_offset()),
EBX);
1593 ASSERT(target::kWordSize == 4);
1594 __ movl(Address(
EBX, -1 * target::kWordSize), Immediate(0));
1595 __ movl(Address(
EBX, -2 * target::kWordSize), Immediate(0));
1601 Label size_tag_overflow,
done;
1602 __ cmpl(
EDI, Immediate(target::UntaggedObject::kSizeTagMaxSizeTag));
1604 __ shll(
EDI, Immediate(target::UntaggedObject::kTagBitsSizeTagPos -
1608 __ Bind(&size_tag_overflow);
1615 __ orl(
EDI, Immediate(tags));
1616 __ movl(FieldAddress(
EAX, target::Object::tags_offset()),
EDI);
1621 __ StoreIntoObjectNoBarrier(
1622 EAX, FieldAddress(
EAX, target::String::length_offset()),
EDI);
1624 __ ZeroInitSmiField(FieldAddress(
EAX, target::String::hash_offset()));
1627 __ Bind(&pop_and_fail);
1636void AsmIntrinsifier::OneByteString_substringUnchecked(Assembler* assembler,
1637 Label* normal_ir_body) {
1638 const intptr_t kStringOffset = 3 * target::kWordSize;
1639 const intptr_t kStartIndexOffset = 2 * target::kWordSize;
1640 const intptr_t kEndIndexOffset = 1 * target::kWordSize;
1642 __ movl(
EAX, Address(
ESP, +kStartIndexOffset));
1643 __ movl(
EDI, Address(
ESP, +kEndIndexOffset));
1648 __ subl(
EDI, Address(
ESP, +kStartIndexOffset));
1649 TryAllocateString(assembler, kOneByteStringCid,
1650 target::OneByteString::kMaxNewSpaceElements, &
ok,
1651 normal_ir_body,
EDI);
1655 __ movl(
EDI, Address(
ESP, +kStringOffset));
1656 __ movl(
EBX, Address(
ESP, +kStartIndexOffset));
1659 target::OneByteString::data_offset()));
1662 __ movl(
ECX, Address(
ESP, +kEndIndexOffset));
1675 __ movb(FieldAddress(
EAX,
EDX,
TIMES_1, target::OneByteString::data_offset()),
1682 __ Bind(normal_ir_body);
1685void AsmIntrinsifier::WriteIntoOneByteString(Assembler* assembler,
1686 Label* normal_ir_body) {
1687 __ movl(
ECX, Address(
ESP, +1 * target::kWordSize));
1688 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
1689 __ movl(
EAX, Address(
ESP, +3 * target::kWordSize));
1692 __ movb(FieldAddress(
EAX,
EBX,
TIMES_1, target::OneByteString::data_offset()),
1697void AsmIntrinsifier::WriteIntoTwoByteString(Assembler* assembler,
1698 Label* normal_ir_body) {
1699 __ movl(
ECX, Address(
ESP, +1 * target::kWordSize));
1700 __ movl(
EBX, Address(
ESP, +2 * target::kWordSize));
1701 __ movl(
EAX, Address(
ESP, +3 * target::kWordSize));
1704 __ movw(FieldAddress(
EAX,
EBX,
TIMES_1, target::TwoByteString::data_offset()),
1709void AsmIntrinsifier::AllocateOneByteString(Assembler* assembler,
1710 Label* normal_ir_body) {
1711 __ movl(
EDI, Address(
ESP, +1 * target::kWordSize));
1713 TryAllocateString(assembler, kOneByteStringCid,
1714 target::OneByteString::kMaxNewSpaceElements, &
ok,
1715 normal_ir_body,
EDI);
1721 __ Bind(normal_ir_body);
1724void AsmIntrinsifier::AllocateTwoByteString(Assembler* assembler,
1725 Label* normal_ir_body) {
1726 __ movl(
EDI, Address(
ESP, +1 * target::kWordSize));
1728 TryAllocateString(assembler, kTwoByteStringCid,
1729 target::TwoByteString::kMaxNewSpaceElements, &
ok,
1730 normal_ir_body,
EDI);
1736 __ Bind(normal_ir_body);
1739void AsmIntrinsifier::OneByteString_equality(Assembler* assembler,
1740 Label* normal_ir_body) {
1741 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
1742 __ movl(
EBX, Address(
ESP, +1 * target::kWordSize));
1748void AsmIntrinsifier::TwoByteString_equality(Assembler* assembler,
1749 Label* normal_ir_body) {
1750 __ movl(
EAX, Address(
ESP, +2 * target::kWordSize));
1751 __ movl(
EBX, Address(
ESP, +1 * target::kWordSize));
1757void AsmIntrinsifier::IntrinsifyRegExpExecuteMatch(Assembler* assembler,
1758 Label* normal_ir_body,
1760 if (FLAG_interpret_irregexp)
return;
1762 const intptr_t kRegExpParamOffset = 3 * target::kWordSize;
1763 const intptr_t kStringParamOffset = 2 * target::kWordSize;
1773 __ movl(
EBX, Address(
ESP, kRegExpParamOffset));
1774 __ movl(
EDI, Address(
ESP, kStringParamOffset));
1776 __ SubImmediate(
EDI, Immediate(kOneByteStringCid));
1778 target::RegExp::function_offset(
1779 kOneByteStringCid, sticky)));
1786 __ jmp(FieldAddress(
FUNCTION_REG, target::Function::entry_point_offset()));
1789void AsmIntrinsifier::UserTag_defaultTag(Assembler* assembler,
1790 Label* normal_ir_body) {
1791 __ LoadIsolate(
EAX);
1792 __ movl(
EAX, Address(
EAX, target::Isolate::default_tag_offset()));
1796void AsmIntrinsifier::Profiler_getCurrentTag(Assembler* assembler,
1797 Label* normal_ir_body) {
1798 __ LoadIsolate(
EAX);
1799 __ movl(
EAX, Address(
EAX, target::Isolate::current_tag_offset()));
1803void AsmIntrinsifier::Timeline_isDartStreamEnabled(Assembler* assembler,
1804 Label* normal_ir_body) {
1805#if !defined(SUPPORT_TIMELINE)
1811 __ movl(
EAX, Address(
THR, target::Thread::dart_stream_offset()));
1813 __ movl(
EAX, Address(
EAX, target::TimelineStream::enabled_offset()));
1814 __ cmpl(
EAX, Immediate(0));
1820 __ Bind(&true_label);
1826void AsmIntrinsifier::Timeline_getNextTaskId(Assembler* assembler,
1827 Label* normal_ir_body) {
1828#if !defined(SUPPORT_TIMELINE)
1832 __ movl(
EBX, Address(
THR, target::Thread::next_task_id_offset()));
1833 __ movl(
ECX, Address(
THR, target::Thread::next_task_id_offset() + 4));
1836 __ addl(
EBX, Immediate(1));
1837 __ adcl(
ECX, Immediate(0));
1838 __ movl(Address(
THR, target::Thread::next_task_id_offset()),
EBX);
1839 __ movl(Address(
THR, target::Thread::next_task_id_offset() + 4),
ECX);
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()
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
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
#define NOT_IN_PRODUCT(code)