Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Side by Side Diff: runtime/vm/intrinsifier_mips.cc

Issue 593363003: Expands the use of Immediate and Operand wrappers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/intrinsifier_arm64.cc ('k') | runtime/vm/object_arm64_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_MIPS.
6 #if defined(TARGET_ARCH_MIPS) 6 #if defined(TARGET_ARCH_MIPS)
7 7
8 #include "vm/intrinsifier.h" 8 #include "vm/intrinsifier.h"
9 9
10 #include "vm/assembler.h" 10 #include "vm/assembler.h"
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { 207 void Intrinsifier::GrowableArraySetData(Assembler* assembler) {
208 if (FLAG_enable_type_checks) { 208 if (FLAG_enable_type_checks) {
209 return; 209 return;
210 } 210 }
211 Label fall_through; 211 Label fall_through;
212 __ lw(T1, Address(SP, 0 * kWordSize)); // Data. 212 __ lw(T1, Address(SP, 0 * kWordSize)); // Data.
213 // Check that data is an ObjectArray. 213 // Check that data is an ObjectArray.
214 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 214 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
215 __ beq(CMPRES1, ZR, &fall_through); // Data is Smi. 215 __ beq(CMPRES1, ZR, &fall_through); // Data is Smi.
216 __ LoadClassId(CMPRES1, T1); 216 __ LoadClassId(CMPRES1, T1);
217 __ BranchNotEqual(CMPRES1, kArrayCid, &fall_through); 217 __ BranchNotEqual(CMPRES1, Immediate(kArrayCid), &fall_through);
218 __ lw(T0, Address(SP, 1 * kWordSize)); // Growable array. 218 __ lw(T0, Address(SP, 1 * kWordSize)); // Growable array.
219 __ StoreIntoObject(T0, 219 __ StoreIntoObject(T0,
220 FieldAddress(T0, GrowableObjectArray::data_offset()), 220 FieldAddress(T0, GrowableObjectArray::data_offset()),
221 T1); 221 T1);
222 __ Ret(); 222 __ Ret();
223 __ Bind(&fall_through); 223 __ Bind(&fall_through);
224 } 224 }
225 225
226 226
227 // Add an element to growable array if it doesn't need to grow, otherwise 227 // Add an element to growable array if it doesn't need to grow, otherwise
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 259
260 260
261 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ 261 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \
262 Label fall_through; \ 262 Label fall_through; \
263 const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ 263 const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \
264 __ lw(T2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \ 264 __ lw(T2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \
265 /* Check that length is a positive Smi. */ \ 265 /* Check that length is a positive Smi. */ \
266 /* T2: requested array length argument. */ \ 266 /* T2: requested array length argument. */ \
267 __ andi(CMPRES1, T2, Immediate(kSmiTagMask)); \ 267 __ andi(CMPRES1, T2, Immediate(kSmiTagMask)); \
268 __ bne(CMPRES1, ZR, &fall_through); \ 268 __ bne(CMPRES1, ZR, &fall_through); \
269 __ BranchSignedLess(T2, 0, &fall_through); \ 269 __ BranchSignedLess(T2, Immediate(0), &fall_through); \
270 __ SmiUntag(T2); \ 270 __ SmiUntag(T2); \
271 /* Check for maximum allowed length. */ \ 271 /* Check for maximum allowed length. */ \
272 /* T2: untagged array length. */ \ 272 /* T2: untagged array length. */ \
273 __ BranchSignedGreater(T2, max_len, &fall_through); \ 273 __ BranchSignedGreater(T2, Immediate(max_len), &fall_through); \
274 __ sll(T2, T2, scale_shift); \ 274 __ sll(T2, T2, scale_shift); \
275 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ 275 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \
276 __ AddImmediate(T2, fixed_size); \ 276 __ AddImmediate(T2, fixed_size); \
277 __ LoadImmediate(TMP, -kObjectAlignment); \ 277 __ LoadImmediate(TMP, -kObjectAlignment); \
278 __ and_(T2, T2, TMP); \ 278 __ and_(T2, T2, TMP); \
279 Heap* heap = Isolate::Current()->heap(); \ 279 Heap* heap = Isolate::Current()->heap(); \
280 Heap::Space space = heap->SpaceForAllocation(cid); \ 280 Heap::Space space = heap->SpaceForAllocation(cid); \
281 __ LoadImmediate(V0, heap->TopAddress(space)); \ 281 __ LoadImmediate(V0, heap->TopAddress(space)); \
282 __ lw(V0, Address(V0, 0)); \ 282 __ lw(V0, Address(V0, 0)); \
283 \ 283 \
(...skipping 14 matching lines...) Expand all
298 __ LoadImmediate(T3, heap->TopAddress(space)); \ 298 __ LoadImmediate(T3, heap->TopAddress(space)); \
299 __ sw(T1, Address(T3, 0)); \ 299 __ sw(T1, Address(T3, 0)); \
300 __ AddImmediate(V0, kHeapObjectTag); \ 300 __ AddImmediate(V0, kHeapObjectTag); \
301 __ UpdateAllocationStatsWithSize(cid, T2, T4, space); \ 301 __ UpdateAllocationStatsWithSize(cid, T2, T4, space); \
302 /* Initialize the tags. */ \ 302 /* Initialize the tags. */ \
303 /* V0: new object start as a tagged pointer. */ \ 303 /* V0: new object start as a tagged pointer. */ \
304 /* T1: new object end address. */ \ 304 /* T1: new object end address. */ \
305 /* T2: allocation size. */ \ 305 /* T2: allocation size. */ \
306 { \ 306 { \
307 Label size_tag_overflow, done; \ 307 Label size_tag_overflow, done; \
308 __ BranchUnsignedGreater(T2, RawObject::SizeTag::kMaxSizeTag, \ 308 __ BranchUnsignedGreater(T2, Immediate(RawObject::SizeTag::kMaxSizeTag), \
309 &size_tag_overflow); \ 309 &size_tag_overflow); \
310 __ b(&done); \ 310 __ b(&done); \
311 __ delay_slot()->sll(T2, T2, \ 311 __ delay_slot()->sll(T2, T2, \
312 RawObject::kSizeTagPos - kObjectAlignmentLog2); \ 312 RawObject::kSizeTagPos - kObjectAlignmentLog2); \
313 \ 313 \
314 __ Bind(&size_tag_overflow); \ 314 __ Bind(&size_tag_overflow); \
315 __ mov(T2, ZR); \ 315 __ mov(T2, ZR); \
316 __ Bind(&done); \ 316 __ Bind(&done); \
317 \ 317 \
318 /* Get the class index and insert it into the tags. */ \ 318 /* Get the class index and insert it into the tags. */ \
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 533
534 TestBothArgumentsSmis(assembler, &fall_through); 534 TestBothArgumentsSmis(assembler, &fall_through);
535 __ beq(T0, ZR, &fall_through); // If b is 0, fall through. 535 __ beq(T0, ZR, &fall_through); // If b is 0, fall through.
536 536
537 __ SmiUntag(T0); 537 __ SmiUntag(T0);
538 __ SmiUntag(T1); 538 __ SmiUntag(T1);
539 __ div(T1, T0); // LO <- T1 / T0 539 __ div(T1, T0); // LO <- T1 / T0
540 __ mflo(V0); // V0 <- LO 540 __ mflo(V0); // V0 <- LO
541 // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we 541 // Check the corner case of dividing the 'MIN_SMI' with -1, in which case we
542 // cannot tag the result. 542 // cannot tag the result.
543 __ BranchEqual(V0, 0x40000000, &fall_through); 543 __ BranchEqual(V0, Immediate(0x40000000), &fall_through);
544 __ Ret(); 544 __ Ret();
545 __ delay_slot()->SmiTag(V0); 545 __ delay_slot()->SmiTag(V0);
546 __ Bind(&fall_through); 546 __ Bind(&fall_through);
547 } 547 }
548 548
549 549
550 void Intrinsifier::Integer_negate(Assembler* assembler) { 550 void Intrinsifier::Integer_negate(Assembler* assembler) {
551 Label fall_through; 551 Label fall_through;
552 552
553 __ lw(T0, Address(SP, + 0 * kWordSize)); // Grabs first argument. 553 __ lw(T0, Address(SP, + 0 * kWordSize)); // Grabs first argument.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 Integer_bitXorFromInteger(assembler); 604 Integer_bitXorFromInteger(assembler);
605 } 605 }
606 606
607 607
608 void Intrinsifier::Integer_shl(Assembler* assembler) { 608 void Intrinsifier::Integer_shl(Assembler* assembler) {
609 ASSERT(kSmiTagShift == 1); 609 ASSERT(kSmiTagShift == 1);
610 ASSERT(kSmiTag == 0); 610 ASSERT(kSmiTag == 0);
611 Label fall_through, overflow; 611 Label fall_through, overflow;
612 612
613 TestBothArgumentsSmis(assembler, &fall_through); 613 TestBothArgumentsSmis(assembler, &fall_through);
614 __ BranchUnsignedGreater(T0, Smi::RawValue(Smi::kBits), &fall_through); 614 __ BranchUnsignedGreater(
615 T0, Immediate(Smi::RawValue(Smi::kBits)), &fall_through);
615 __ SmiUntag(T0); 616 __ SmiUntag(T0);
616 617
617 // Check for overflow by shifting left and shifting back arithmetically. 618 // Check for overflow by shifting left and shifting back arithmetically.
618 // If the result is different from the original, there was overflow. 619 // If the result is different from the original, there was overflow.
619 __ sllv(TMP, T1, T0); 620 __ sllv(TMP, T1, T0);
620 __ srav(CMPRES1, TMP, T0); 621 __ srav(CMPRES1, TMP, T0);
621 __ bne(CMPRES1, T1, &overflow); 622 __ bne(CMPRES1, T1, &overflow);
622 623
623 // No overflow, result in V0. 624 // No overflow, result in V0.
624 __ Ret(); 625 __ Ret();
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 __ bne(CMPRES1, ZR, &not_smi); 666 __ bne(CMPRES1, ZR, &not_smi);
666 __ SmiUntag(reg); 667 __ SmiUntag(reg);
667 668
668 // Sign extend to 64 bit 669 // Sign extend to 64 bit
669 __ mov(res_lo, reg); 670 __ mov(res_lo, reg);
670 __ b(&done); 671 __ b(&done);
671 __ delay_slot()->sra(res_hi, reg, 31); 672 __ delay_slot()->sra(res_hi, reg, 31);
672 673
673 __ Bind(&not_smi); 674 __ Bind(&not_smi);
674 __ LoadClassId(CMPRES1, reg); 675 __ LoadClassId(CMPRES1, reg);
675 __ BranchNotEqual(CMPRES1, kMintCid, not_smi_or_mint); 676 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), not_smi_or_mint);
676 677
677 // Mint. 678 // Mint.
678 __ lw(res_lo, FieldAddress(reg, Mint::value_offset())); 679 __ lw(res_lo, FieldAddress(reg, Mint::value_offset()));
679 __ lw(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize)); 680 __ lw(res_hi, FieldAddress(reg, Mint::value_offset() + kWordSize));
680 __ Bind(&done); 681 __ Bind(&done);
681 return; 682 return;
682 } 683 }
683 684
684 685
685 static void CompareIntegers(Assembler* assembler, Condition true_condition) { 686 static void CompareIntegers(Assembler* assembler, Condition true_condition) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
805 __ Bind(&check_for_mint); 806 __ Bind(&check_for_mint);
806 807
807 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 808 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
808 __ bne(CMPRES1, ZR, &receiver_not_smi); // Check receiver. 809 __ bne(CMPRES1, ZR, &receiver_not_smi); // Check receiver.
809 810
810 // Left (receiver) is Smi, return false if right is not Double. 811 // Left (receiver) is Smi, return false if right is not Double.
811 // Note that an instance of Mint or Bigint never contains a value that can be 812 // Note that an instance of Mint or Bigint never contains a value that can be
812 // represented by Smi. 813 // represented by Smi.
813 814
814 __ LoadClassId(CMPRES1, T0); 815 __ LoadClassId(CMPRES1, T0);
815 __ BranchEqual(CMPRES1, kDoubleCid, &fall_through); 816 __ BranchEqual(CMPRES1, Immediate(kDoubleCid), &fall_through);
816 __ LoadObject(V0, Bool::False()); // Smi == Mint -> false. 817 __ LoadObject(V0, Bool::False()); // Smi == Mint -> false.
817 __ Ret(); 818 __ Ret();
818 819
819 __ Bind(&receiver_not_smi); 820 __ Bind(&receiver_not_smi);
820 // T1:: receiver. 821 // T1:: receiver.
821 822
822 __ LoadClassId(CMPRES1, T1); 823 __ LoadClassId(CMPRES1, T1);
823 __ BranchNotEqual(CMPRES1, kMintCid, &fall_through); 824 __ BranchNotEqual(CMPRES1, Immediate(kMintCid), &fall_through);
824 // Receiver is Mint, return false if right is Smi. 825 // Receiver is Mint, return false if right is Smi.
825 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); 826 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
826 __ bne(CMPRES1, ZR, &fall_through); 827 __ bne(CMPRES1, ZR, &fall_through);
827 __ LoadObject(V0, Bool::False()); 828 __ LoadObject(V0, Bool::False());
828 __ Ret(); 829 __ Ret();
829 // TODO(srdjan): Implement Mint == Mint comparison. 830 // TODO(srdjan): Implement Mint == Mint comparison.
830 831
831 __ Bind(&fall_through); 832 __ Bind(&fall_through);
832 } 833 }
833 834
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 // Check if the last argument is a double, jump to label 'is_smi' if smi 929 // Check if the last argument is a double, jump to label 'is_smi' if smi
929 // (easy to convert to double), otherwise jump to label 'not_double_smi', 930 // (easy to convert to double), otherwise jump to label 'not_double_smi',
930 // Returns the last argument in T0. 931 // Returns the last argument in T0.
931 static void TestLastArgumentIsDouble(Assembler* assembler, 932 static void TestLastArgumentIsDouble(Assembler* assembler,
932 Label* is_smi, 933 Label* is_smi,
933 Label* not_double_smi) { 934 Label* not_double_smi) {
934 __ lw(T0, Address(SP, 0 * kWordSize)); 935 __ lw(T0, Address(SP, 0 * kWordSize));
935 __ andi(CMPRES1, T0, Immediate(kSmiTagMask)); 936 __ andi(CMPRES1, T0, Immediate(kSmiTagMask));
936 __ beq(CMPRES1, ZR, is_smi); 937 __ beq(CMPRES1, ZR, is_smi);
937 __ LoadClassId(CMPRES1, T0); 938 __ LoadClassId(CMPRES1, T0);
938 __ BranchNotEqual(CMPRES1, kDoubleCid, not_double_smi); 939 __ BranchNotEqual(CMPRES1, Immediate(kDoubleCid), not_double_smi);
939 // Fall through with Double in T0. 940 // Fall through with Double in T0.
940 } 941 }
941 942
942 943
943 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown 944 // Both arguments on stack, arg0 (left) is a double, arg1 (right) is of unknown
944 // type. Return true or false object in the register V0. Any NaN argument 945 // type. Return true or false object in the register V0. Any NaN argument
945 // returns false. Any non-double arg1 causes control flow to fall through to the 946 // returns false. Any non-double arg1 causes control flow to fall through to the
946 // slow case (compiled method body). 947 // slow case (compiled method body).
947 static void CompareDoubles(Assembler* assembler, Condition true_condition) { 948 static void CompareDoubles(Assembler* assembler, Condition true_condition) {
948 Label is_smi, double_op, no_NaN, fall_through; 949 Label is_smi, double_op, no_NaN, fall_through;
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1288 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1288 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1289 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1289 1290
1290 // Checks. 1291 // Checks.
1291 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1292 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1292 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1293 __ bne(T1, ZR, &fall_through); // Index is not a Smi.
1293 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1294 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
1294 // Runtime throws exception. 1295 // Runtime throws exception.
1295 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 1296 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
1296 __ LoadClassId(CMPRES1, T0); // Class ID check. 1297 __ LoadClassId(CMPRES1, T0); // Class ID check.
1297 __ BranchNotEqual(CMPRES1, kOneByteStringCid, &try_two_byte_string); 1298 __ BranchNotEqual(
1299 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
1298 1300
1299 // Grab byte and return. 1301 // Grab byte and return.
1300 __ SmiUntag(T1); 1302 __ SmiUntag(T1);
1301 __ addu(T2, T0, T1); 1303 __ addu(T2, T0, T1);
1302 __ lbu(V0, FieldAddress(T2, OneByteString::data_offset())); 1304 __ lbu(V0, FieldAddress(T2, OneByteString::data_offset()));
1303 __ Ret(); 1305 __ Ret();
1304 __ delay_slot()->SmiTag(V0); 1306 __ delay_slot()->SmiTag(V0);
1305 1307
1306 __ Bind(&try_two_byte_string); 1308 __ Bind(&try_two_byte_string);
1307 __ BranchNotEqual(CMPRES1, kTwoByteStringCid, &fall_through); 1309 __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
1308 ASSERT(kSmiTagShift == 1); 1310 ASSERT(kSmiTagShift == 1);
1309 __ addu(T2, T0, T1); 1311 __ addu(T2, T0, T1);
1310 __ lhu(V0, FieldAddress(T2, TwoByteString::data_offset())); 1312 __ lhu(V0, FieldAddress(T2, TwoByteString::data_offset()));
1311 __ Ret(); 1313 __ Ret();
1312 __ delay_slot()->SmiTag(V0); 1314 __ delay_slot()->SmiTag(V0);
1313 1315
1314 __ Bind(&fall_through); 1316 __ Bind(&fall_through);
1315 } 1317 }
1316 1318
1317 1319
1318 void Intrinsifier::StringBaseCharAt(Assembler* assembler) { 1320 void Intrinsifier::StringBaseCharAt(Assembler* assembler) {
1319 Label fall_through, try_two_byte_string; 1321 Label fall_through, try_two_byte_string;
1320 1322
1321 __ lw(T1, Address(SP, 0 * kWordSize)); // Index. 1323 __ lw(T1, Address(SP, 0 * kWordSize)); // Index.
1322 __ lw(T0, Address(SP, 1 * kWordSize)); // String. 1324 __ lw(T0, Address(SP, 1 * kWordSize)); // String.
1323 1325
1324 // Checks. 1326 // Checks.
1325 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1327 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1326 __ bne(T1, ZR, &fall_through); // Index is not a Smi. 1328 __ bne(T1, ZR, &fall_through); // Index is not a Smi.
1327 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check. 1329 __ lw(T2, FieldAddress(T0, String::length_offset())); // Range check.
1328 // Runtime throws exception. 1330 // Runtime throws exception.
1329 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through); 1331 __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
1330 __ LoadClassId(CMPRES1, T0); // Class ID check. 1332 __ LoadClassId(CMPRES1, T0); // Class ID check.
1331 __ BranchNotEqual(CMPRES1, kOneByteStringCid, &try_two_byte_string); 1333 __ BranchNotEqual(
1334 CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
1332 1335
1333 // Grab byte and return. 1336 // Grab byte and return.
1334 __ SmiUntag(T1); 1337 __ SmiUntag(T1);
1335 __ addu(T2, T0, T1); 1338 __ addu(T2, T0, T1);
1336 __ lbu(T2, FieldAddress(T2, OneByteString::data_offset())); 1339 __ lbu(T2, FieldAddress(T2, OneByteString::data_offset()));
1337 __ BranchUnsignedGreaterEqual( 1340 __ BranchUnsignedGreaterEqual(
1338 T2, Symbols::kNumberOfOneCharCodeSymbols, &fall_through); 1341 T2, Immediate(Symbols::kNumberOfOneCharCodeSymbols), &fall_through);
1339 __ LoadImmediate( 1342 __ LoadImmediate(
1340 V0, reinterpret_cast<uword>(Symbols::PredefinedAddress())); 1343 V0, reinterpret_cast<uword>(Symbols::PredefinedAddress()));
1341 __ AddImmediate(V0, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1344 __ AddImmediate(V0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1342 __ sll(T2, T2, 2); 1345 __ sll(T2, T2, 2);
1343 __ addu(T2, T2, V0); 1346 __ addu(T2, T2, V0);
1344 __ Ret(); 1347 __ Ret();
1345 __ delay_slot()->lw(V0, Address(T2)); 1348 __ delay_slot()->lw(V0, Address(T2));
1346 1349
1347 __ Bind(&try_two_byte_string); 1350 __ Bind(&try_two_byte_string);
1348 __ BranchNotEqual(CMPRES1, kTwoByteStringCid, &fall_through); 1351 __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
1349 ASSERT(kSmiTagShift == 1); 1352 ASSERT(kSmiTagShift == 1);
1350 __ addu(T2, T0, T1); 1353 __ addu(T2, T0, T1);
1351 __ lhu(T2, FieldAddress(T2, TwoByteString::data_offset())); 1354 __ lhu(T2, FieldAddress(T2, TwoByteString::data_offset()));
1352 __ BranchUnsignedGreaterEqual( 1355 __ BranchUnsignedGreaterEqual(
1353 T2, Symbols::kNumberOfOneCharCodeSymbols, &fall_through); 1356 T2, Immediate(Symbols::kNumberOfOneCharCodeSymbols), &fall_through);
1354 __ LoadImmediate(V0, 1357 __ LoadImmediate(V0,
1355 reinterpret_cast<uword>(Symbols::PredefinedAddress())); 1358 reinterpret_cast<uword>(Symbols::PredefinedAddress()));
1356 __ AddImmediate(V0, Symbols::kNullCharCodeSymbolOffset * kWordSize); 1359 __ AddImmediate(V0, Symbols::kNullCharCodeSymbolOffset * kWordSize);
1357 __ sll(T2, T2, 2); 1360 __ sll(T2, T2, 2);
1358 __ addu(T2, T2, V0); 1361 __ addu(T2, T2, V0);
1359 __ Ret(); 1362 __ Ret();
1360 __ delay_slot()->lw(V0, Address(T2)); 1363 __ delay_slot()->lw(V0, Address(T2));
1361 1364
1362 __ Bind(&fall_through); 1365 __ Bind(&fall_through);
1363 } 1366 }
(...skipping 20 matching lines...) Expand all
1384 __ lw(T1, Address(SP, 0 * kWordSize)); 1387 __ lw(T1, Address(SP, 0 * kWordSize));
1385 __ lw(V0, FieldAddress(T1, String::hash_offset())); 1388 __ lw(V0, FieldAddress(T1, String::hash_offset()));
1386 __ beq(V0, ZR, &no_hash); 1389 __ beq(V0, ZR, &no_hash);
1387 __ Ret(); // Return if already computed. 1390 __ Ret(); // Return if already computed.
1388 __ Bind(&no_hash); 1391 __ Bind(&no_hash);
1389 1392
1390 __ lw(T2, FieldAddress(T1, String::length_offset())); 1393 __ lw(T2, FieldAddress(T1, String::length_offset()));
1391 1394
1392 Label done; 1395 Label done;
1393 // If the string is empty, set the hash to 1, and return. 1396 // If the string is empty, set the hash to 1, and return.
1394 __ BranchEqual(T2, Smi::RawValue(0), &done); 1397 __ BranchEqual(T2, Immediate(Smi::RawValue(0)), &done);
1395 __ delay_slot()->mov(V0, ZR); 1398 __ delay_slot()->mov(V0, ZR);
1396 1399
1397 __ SmiUntag(T2); 1400 __ SmiUntag(T2);
1398 __ AddImmediate(T3, T1, OneByteString::data_offset() - kHeapObjectTag); 1401 __ AddImmediate(T3, T1, OneByteString::data_offset() - kHeapObjectTag);
1399 __ addu(T4, T3, T2); 1402 __ addu(T4, T3, T2);
1400 // V0: Hash code, untagged integer. 1403 // V0: Hash code, untagged integer.
1401 // T1: Instance of OneByteString. 1404 // T1: Instance of OneByteString.
1402 // T2: String length, untagged integer. 1405 // T2: String length, untagged integer.
1403 // T3: String data start. 1406 // T3: String data start.
1404 // T4: String data end. 1407 // T4: String data end.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1488 __ UpdateAllocationStatsWithSize(cid, T2, T3, space); 1491 __ UpdateAllocationStatsWithSize(cid, T2, T3, space);
1489 1492
1490 // Initialize the tags. 1493 // Initialize the tags.
1491 // V0: new object start as a tagged pointer. 1494 // V0: new object start as a tagged pointer.
1492 // T1: new object end address. 1495 // T1: new object end address.
1493 // T2: allocation size. 1496 // T2: allocation size.
1494 { 1497 {
1495 Label overflow, done; 1498 Label overflow, done;
1496 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 1499 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
1497 1500
1498 __ BranchUnsignedGreater(T2, RawObject::SizeTag::kMaxSizeTag, &overflow); 1501 __ BranchUnsignedGreater(
1502 T2, Immediate(RawObject::SizeTag::kMaxSizeTag), &overflow);
1499 __ b(&done); 1503 __ b(&done);
1500 __ delay_slot()->sll(T2, T2, shift); 1504 __ delay_slot()->sll(T2, T2, shift);
1501 __ Bind(&overflow); 1505 __ Bind(&overflow);
1502 __ mov(T2, ZR); 1506 __ mov(T2, ZR);
1503 __ Bind(&done); 1507 __ Bind(&done);
1504 1508
1505 // Get the class index and insert it into the tags. 1509 // Get the class index and insert it into the tags.
1506 // T2: size and bit tags. 1510 // T2: size and bit tags.
1507 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid)); 1511 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid));
1508 __ or_(T2, T2, TMP); 1512 __ or_(T2, T2, TMP);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1608 __ lw(T0, Address(SP, 1 * kWordSize)); // This. 1612 __ lw(T0, Address(SP, 1 * kWordSize)); // This.
1609 __ lw(T1, Address(SP, 0 * kWordSize)); // Other. 1613 __ lw(T1, Address(SP, 0 * kWordSize)); // Other.
1610 1614
1611 // Are identical? 1615 // Are identical?
1612 __ beq(T0, T1, &is_true); 1616 __ beq(T0, T1, &is_true);
1613 1617
1614 // Is other OneByteString? 1618 // Is other OneByteString?
1615 __ andi(CMPRES1, T1, Immediate(kSmiTagMask)); 1619 __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
1616 __ beq(CMPRES1, ZR, &fall_through); // Other is Smi. 1620 __ beq(CMPRES1, ZR, &fall_through); // Other is Smi.
1617 __ LoadClassId(CMPRES1, T1); // Class ID check. 1621 __ LoadClassId(CMPRES1, T1); // Class ID check.
1618 __ BranchNotEqual(CMPRES1, string_cid, &fall_through); 1622 __ BranchNotEqual(CMPRES1, Immediate(string_cid), &fall_through);
1619 1623
1620 // Have same length? 1624 // Have same length?
1621 __ lw(T2, FieldAddress(T0, String::length_offset())); 1625 __ lw(T2, FieldAddress(T0, String::length_offset()));
1622 __ lw(T3, FieldAddress(T1, String::length_offset())); 1626 __ lw(T3, FieldAddress(T1, String::length_offset()));
1623 __ bne(T2, T3, &is_false); 1627 __ bne(T2, T3, &is_false);
1624 1628
1625 // Check contents, no fall-through possible. 1629 // Check contents, no fall-through possible.
1626 ASSERT((string_cid == kOneByteStringCid) || 1630 ASSERT((string_cid == kOneByteStringCid) ||
1627 (string_cid == kTwoByteStringCid)); 1631 (string_cid == kTwoByteStringCid));
1628 __ SmiUntag(T2); 1632 __ SmiUntag(T2);
1629 __ Bind(&loop); 1633 __ Bind(&loop);
1630 __ AddImmediate(T2, -1); 1634 __ AddImmediate(T2, -1);
1631 __ BranchSignedLess(T2, 0, &is_true); 1635 __ BranchSignedLess(T2, Immediate(0), &is_true);
1632 if (string_cid == kOneByteStringCid) { 1636 if (string_cid == kOneByteStringCid) {
1633 __ lbu(V0, FieldAddress(T0, OneByteString::data_offset())); 1637 __ lbu(V0, FieldAddress(T0, OneByteString::data_offset()));
1634 __ lbu(V1, FieldAddress(T1, OneByteString::data_offset())); 1638 __ lbu(V1, FieldAddress(T1, OneByteString::data_offset()));
1635 __ AddImmediate(T0, 1); 1639 __ AddImmediate(T0, 1);
1636 __ AddImmediate(T1, 1); 1640 __ AddImmediate(T1, 1);
1637 } else if (string_cid == kTwoByteStringCid) { 1641 } else if (string_cid == kTwoByteStringCid) {
1638 __ lhu(V0, FieldAddress(T0, OneByteString::data_offset())); 1642 __ lhu(V0, FieldAddress(T0, OneByteString::data_offset()));
1639 __ lhu(V1, FieldAddress(T1, OneByteString::data_offset())); 1643 __ lhu(V1, FieldAddress(T1, OneByteString::data_offset()));
1640 __ AddImmediate(T0, 2); 1644 __ AddImmediate(T0, 2);
1641 __ AddImmediate(T1, 2); 1645 __ AddImmediate(T1, 2);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 Isolate* isolate = Isolate::Current(); 1704 Isolate* isolate = Isolate::Current();
1701 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate)); 1705 __ LoadImmediate(V0, reinterpret_cast<uword>(isolate));
1702 // Set return value. 1706 // Set return value.
1703 __ Ret(); 1707 __ Ret();
1704 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset())); 1708 __ delay_slot()->lw(V0, Address(V0, Isolate::current_tag_offset()));
1705 } 1709 }
1706 1710
1707 } // namespace dart 1711 } // namespace dart
1708 1712
1709 #endif // defined TARGET_ARCH_MIPS 1713 #endif // defined TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « runtime/vm/intrinsifier_arm64.cc ('k') | runtime/vm/object_arm64_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698