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

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

Issue 579243003: Fixes a bug in CheckClassInstr on arm64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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/intermediate_language_arm64.cc ('k') | runtime/vm/stub_code_arm64.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) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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_ARM64. 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM64.
6 #if defined(TARGET_ARCH_ARM64) 6 #if defined(TARGET_ARCH_ARM64)
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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 /* R2: requested array length argument. */ \ 285 /* R2: requested array length argument. */ \
286 __ tsti(R2, kSmiTagMask); \ 286 __ tsti(R2, kSmiTagMask); \
287 __ b(&fall_through, NE); \ 287 __ b(&fall_through, NE); \
288 __ CompareRegisters(R2, ZR); \ 288 __ CompareRegisters(R2, ZR); \
289 __ b(&fall_through, LT); \ 289 __ b(&fall_through, LT); \
290 __ SmiUntag(R2); \ 290 __ SmiUntag(R2); \
291 /* Check for maximum allowed length. */ \ 291 /* Check for maximum allowed length. */ \
292 /* R2: untagged array length. */ \ 292 /* R2: untagged array length. */ \
293 __ CompareImmediate(R2, max_len, kNoPP); \ 293 __ CompareImmediate(R2, max_len, kNoPP); \
294 __ b(&fall_through, GT); \ 294 __ b(&fall_through, GT); \
295 __ Lsl(R2, R2, scale_shift); \ 295 __ LslImmediate(R2, R2, scale_shift); \
296 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ 296 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \
297 __ AddImmediate(R2, R2, fixed_size, kNoPP); \ 297 __ AddImmediate(R2, R2, fixed_size, kNoPP); \
298 __ andi(R2, R2, ~(kObjectAlignment - 1)); \ 298 __ andi(R2, R2, ~(kObjectAlignment - 1)); \
299 Heap* heap = Isolate::Current()->heap(); \ 299 Heap* heap = Isolate::Current()->heap(); \
300 \ 300 \
301 __ LoadImmediate(R0, heap->TopAddress(), kNoPP); \ 301 __ LoadImmediate(R0, heap->TopAddress(), kNoPP); \
302 __ ldr(R0, Address(R0, 0)); \ 302 __ ldr(R0, Address(R0, 0)); \
303 \ 303 \
304 /* R2: allocation size. */ \ 304 /* R2: allocation size. */ \
305 __ add(R1, R0, Operand(R2)); \ 305 __ add(R1, R0, Operand(R2)); \
(...skipping 13 matching lines...) Expand all
319 __ LoadImmediate(R3, heap->TopAddress(), kNoPP); \ 319 __ LoadImmediate(R3, heap->TopAddress(), kNoPP); \
320 __ str(R1, Address(R3, 0)); \ 320 __ str(R1, Address(R3, 0)); \
321 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); \ 321 __ AddImmediate(R0, R0, kHeapObjectTag, kNoPP); \
322 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP); \ 322 __ UpdateAllocationStatsWithSize(cid, R2, kNoPP); \
323 /* Initialize the tags. */ \ 323 /* Initialize the tags. */ \
324 /* R0: new object start as a tagged pointer. */ \ 324 /* R0: new object start as a tagged pointer. */ \
325 /* R1: new object end address. */ \ 325 /* R1: new object end address. */ \
326 /* R2: allocation size. */ \ 326 /* R2: allocation size. */ \
327 { \ 327 { \
328 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); \ 328 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); \
329 __ Lsl(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \ 329 __ LslImmediate(R2, R2, RawObject::kSizeTagPos - kObjectAlignmentLog2); \
330 __ csel(R2, ZR, R2, HI); \ 330 __ csel(R2, ZR, R2, HI); \
331 \ 331 \
332 /* Get the class index and insert it into the tags. */ \ 332 /* Get the class index and insert it into the tags. */ \
333 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid), kNoPP); \ 333 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cid), kNoPP); \
334 __ orr(R2, R2, Operand(TMP)); \ 334 __ orr(R2, R2, Operand(TMP)); \
335 __ str(R2, FieldAddress(R0, type_name::tags_offset())); /* Tags. */ \ 335 __ str(R2, FieldAddress(R0, type_name::tags_offset())); /* Tags. */ \
336 } \ 336 } \
337 /* Set the length field. */ \ 337 /* Set the length field. */ \
338 /* R0: new object start as a tagged pointer. */ \ 338 /* R0: new object start as a tagged pointer. */ \
339 /* R1: new object end address. */ \ 339 /* R1: new object end address. */ \
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 // R1: Tagged left (dividend). 515 // R1: Tagged left (dividend).
516 // R0: Tagged right (divisor). 516 // R0: Tagged right (divisor).
517 // Check if modulo by zero -> exception thrown in main function. 517 // Check if modulo by zero -> exception thrown in main function.
518 __ CompareRegisters(R0, ZR); 518 __ CompareRegisters(R0, ZR);
519 __ b(&fall_through, EQ); 519 __ b(&fall_through, EQ);
520 EmitRemainderOperation(assembler); 520 EmitRemainderOperation(assembler);
521 // Untagged right in R0. Untagged remainder result in R1. 521 // Untagged right in R0. Untagged remainder result in R1.
522 522
523 __ CompareRegisters(R1, ZR); 523 __ CompareRegisters(R1, ZR);
524 __ b(&neg_remainder, LT); 524 __ b(&neg_remainder, LT);
525 __ Lsl(R0, R1, 1); // Tag and move result to R0. 525 __ SmiTag(R0, R1); // Tag and move result to R0.
526 __ ret(); 526 __ ret();
527 527
528 __ Bind(&neg_remainder); 528 __ Bind(&neg_remainder);
529 // Result is negative, adjust it. 529 // Result is negative, adjust it.
530 __ CompareRegisters(R0, ZR); 530 __ CompareRegisters(R0, ZR);
531 __ sub(TMP, R1, Operand(R0)); 531 __ sub(TMP, R1, Operand(R0));
532 __ add(TMP2, R1, Operand(R0)); 532 __ add(TMP2, R1, Operand(R0));
533 __ csel(R0, TMP2, TMP, GE); 533 __ csel(R0, TMP2, TMP, GE);
534 __ SmiTag(R0); 534 __ SmiTag(R0);
535 __ ret(); 535 __ ret();
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 const Register result = R0; 625 const Register result = R0;
626 Label fall_through; 626 Label fall_through;
627 627
628 TestBothArgumentsSmis(assembler, &fall_through); 628 TestBothArgumentsSmis(assembler, &fall_through);
629 __ CompareImmediate( 629 __ CompareImmediate(
630 right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)), PP); 630 right, reinterpret_cast<int64_t>(Smi::New(Smi::kBits)), PP);
631 __ b(&fall_through, CS); 631 __ b(&fall_through, CS);
632 632
633 // Left is not a constant. 633 // Left is not a constant.
634 // Check if count too large for handling it inlined. 634 // Check if count too large for handling it inlined.
635 __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP. 635 __ SmiUntag(TMP, right); // SmiUntag right into TMP.
636 // Overflow test (preserve left, right, and TMP); 636 // Overflow test (preserve left, right, and TMP);
637 __ lslv(temp, left, TMP); 637 __ lslv(temp, left, TMP);
638 __ asrv(TMP2, temp, TMP); 638 __ asrv(TMP2, temp, TMP);
639 __ CompareRegisters(left, TMP2); 639 __ CompareRegisters(left, TMP2);
640 __ b(&fall_through, NE); // Overflow. 640 __ b(&fall_through, NE); // Overflow.
641 // Shift for result now we know there is no overflow. 641 // Shift for result now we know there is no overflow.
642 __ lslv(result, left, TMP); 642 __ lslv(result, left, TMP);
643 __ ret(); 643 __ ret();
644 __ Bind(&fall_through); 644 __ Bind(&fall_through);
645 } 645 }
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 988
989 __ Bind(&is_true); 989 __ Bind(&is_true);
990 __ mov(R0, true_reg); 990 __ mov(R0, true_reg);
991 991
992 __ Bind(&is_false); 992 __ Bind(&is_false);
993 __ ret(); 993 __ ret();
994 994
995 __ Bind(&is_zero); 995 __ Bind(&is_zero);
996 // Check for negative zero by looking at the sign bit. 996 // Check for negative zero by looking at the sign bit.
997 __ fmovrd(R1, V0); 997 __ fmovrd(R1, V0);
998 __ Lsr(R1, R1, 63); 998 __ LsrImmediate(R1, R1, 63);
999 __ tsti(R1, 1); 999 __ tsti(R1, 1);
1000 __ csel(R0, true_reg, false_reg, NE); // Sign bit set. 1000 __ csel(R0, true_reg, false_reg, NE); // Sign bit set.
1001 __ ret(); 1001 __ ret();
1002 } 1002 }
1003 1003
1004 1004
1005 void Intrinsifier::DoubleToInteger(Assembler* assembler) { 1005 void Intrinsifier::DoubleToInteger(Assembler* assembler) {
1006 Label fall_through; 1006 Label fall_through;
1007 1007
1008 __ ldr(R0, Address(SP, 0 * kWordSize)); 1008 __ ldr(R0, Address(SP, 0 * kWordSize));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1065 1065
1066 __ ldr(R0, Address(SP, 0 * kWordSize)); // Receiver. 1066 __ ldr(R0, Address(SP, 0 * kWordSize)); // Receiver.
1067 __ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'. 1067 __ ldr(R1, FieldAddress(R0, state_field.Offset())); // Field '_state'.
1068 1068
1069 // Addresses of _state[0]. 1069 // Addresses of _state[0].
1070 const int64_t disp = 1070 const int64_t disp =
1071 Instance::DataOffsetFor(kTypedDataUint32ArrayCid) - kHeapObjectTag; 1071 Instance::DataOffsetFor(kTypedDataUint32ArrayCid) - kHeapObjectTag;
1072 1072
1073 __ LoadImmediate(R0, a_int_value, kNoPP); 1073 __ LoadImmediate(R0, a_int_value, kNoPP);
1074 __ LoadFromOffset(R2, R1, disp, kNoPP); 1074 __ LoadFromOffset(R2, R1, disp, kNoPP);
1075 __ Lsr(R3, R2, 32); 1075 __ LsrImmediate(R3, R2, 32);
1076 __ andi(R2, R2, 0xffffffff); 1076 __ andi(R2, R2, 0xffffffff);
1077 __ mul(R2, R0, R2); 1077 __ mul(R2, R0, R2);
1078 __ add(R2, R2, Operand(R3)); 1078 __ add(R2, R2, Operand(R3));
1079 __ StoreToOffset(R2, R1, disp, kNoPP); 1079 __ StoreToOffset(R2, R1, disp, kNoPP);
1080 __ ret(); 1080 __ ret();
1081 } 1081 }
1082 1082
1083 1083
1084 void Intrinsifier::ObjectEquals(Assembler* assembler) { 1084 void Intrinsifier::ObjectEquals(Assembler* assembler) {
1085 __ ldr(R0, Address(SP, 0 * kWordSize)); 1085 __ ldr(R0, Address(SP, 0 * kWordSize));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1298 // Initialize the tags. 1298 // Initialize the tags.
1299 // R0: new object start as a tagged pointer. 1299 // R0: new object start as a tagged pointer.
1300 // R1: new object end address. 1300 // R1: new object end address.
1301 // R2: allocation size. 1301 // R2: allocation size.
1302 { 1302 {
1303 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2; 1303 const intptr_t shift = RawObject::kSizeTagPos - kObjectAlignmentLog2;
1304 const Class& cls = 1304 const Class& cls =
1305 Class::Handle(isolate->object_store()->one_byte_string_class()); 1305 Class::Handle(isolate->object_store()->one_byte_string_class());
1306 1306
1307 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP); 1307 __ CompareImmediate(R2, RawObject::SizeTag::kMaxSizeTag, kNoPP);
1308 __ Lsl(R2, R2, shift); 1308 __ LslImmediate(R2, R2, shift);
1309 __ csel(R2, R2, ZR, LS); 1309 __ csel(R2, R2, ZR, LS);
1310 1310
1311 // Get the class index and insert it into the tags. 1311 // Get the class index and insert it into the tags.
1312 // R2: size and bit tags. 1312 // R2: size and bit tags.
1313 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id()), kNoPP); 1313 __ LoadImmediate(TMP, RawObject::ClassIdTag::encode(cls.id()), kNoPP);
1314 __ orr(R2, R2, Operand(TMP)); 1314 __ orr(R2, R2, Operand(TMP));
1315 __ str(R2, FieldAddress(R0, String::tags_offset())); // Store tags. 1315 __ str(R2, FieldAddress(R0, String::tags_offset())); // Store tags.
1316 } 1316 }
1317 1317
1318 // Set the length field using the saved length (R6). 1318 // Set the length field using the saved length (R6).
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 Isolate* isolate = Isolate::Current(); 1523 Isolate* isolate = Isolate::Current();
1524 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP); 1524 __ LoadImmediate(R1, reinterpret_cast<uword>(isolate), kNoPP);
1525 // Set return value to Isolate::current_tag_. 1525 // Set return value to Isolate::current_tag_.
1526 __ ldr(R0, Address(R1, Isolate::current_tag_offset())); 1526 __ ldr(R0, Address(R1, Isolate::current_tag_offset()));
1527 __ ret(); 1527 __ ret();
1528 } 1528 }
1529 1529
1530 } // namespace dart 1530 } // namespace dart
1531 1531
1532 #endif // defined TARGET_ARCH_ARM64 1532 #endif // defined TARGET_ARCH_ARM64
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language_arm64.cc ('k') | runtime/vm/stub_code_arm64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698