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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 6794050: Revert "[Arguments] Merge (7442,7496] from bleeding_edge." (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/arguments
Patch Set: Created 9 years, 8 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 | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 Register scratch1, 495 Register scratch1,
496 Register scratch2, 496 Register scratch2,
497 Label* not_number); 497 Label* not_number);
498 }; 498 };
499 499
500 500
501 void FloatingPointHelper::LoadSmis(MacroAssembler* masm, 501 void FloatingPointHelper::LoadSmis(MacroAssembler* masm,
502 FloatingPointHelper::Destination destination, 502 FloatingPointHelper::Destination destination,
503 Register scratch1, 503 Register scratch1,
504 Register scratch2) { 504 Register scratch2) {
505 if (CpuFeatures::IsSupported(VFP3)) { 505 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
506 CpuFeatures::Scope scope(VFP3); 506 CpuFeatures::Scope scope(VFP3);
507 __ mov(scratch1, Operand(r0, ASR, kSmiTagSize)); 507 __ mov(scratch1, Operand(r0, ASR, kSmiTagSize));
508 __ vmov(d7.high(), scratch1); 508 __ vmov(d7.high(), scratch1);
509 __ vcvt_f64_s32(d7, d7.high()); 509 __ vcvt_f64_s32(d7, d7.high());
510 __ mov(scratch1, Operand(r1, ASR, kSmiTagSize)); 510 __ mov(scratch1, Operand(r1, ASR, kSmiTagSize));
511 __ vmov(d6.high(), scratch1); 511 __ vmov(d6.high(), scratch1);
512 __ vcvt_f64_s32(d6, d6.high()); 512 __ vcvt_f64_s32(d6, d6.high());
513 if (destination == kCoreRegisters) { 513 if (destination == kCoreRegisters) {
514 __ vmov(r2, r3, d7); 514 __ vmov(r2, r3, d7);
515 __ vmov(r0, r1, d6); 515 __ vmov(r0, r1, d6);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
563 Heap::kHeapNumberMapRootIndex, 563 Heap::kHeapNumberMapRootIndex,
564 "HeapNumberMap register clobbered."); 564 "HeapNumberMap register clobbered.");
565 } 565 }
566 566
567 Label is_smi, done; 567 Label is_smi, done;
568 568
569 __ JumpIfSmi(object, &is_smi); 569 __ JumpIfSmi(object, &is_smi);
570 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); 570 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
571 571
572 // Handle loading a double from a heap number. 572 // Handle loading a double from a heap number.
573 if (CpuFeatures::IsSupported(VFP3) && 573 if (Isolate::Current()->cpu_features()->IsSupported(VFP3) &&
574 destination == kVFPRegisters) { 574 destination == kVFPRegisters) {
575 CpuFeatures::Scope scope(VFP3); 575 CpuFeatures::Scope scope(VFP3);
576 // Load the double from tagged HeapNumber to double register. 576 // Load the double from tagged HeapNumber to double register.
577 __ sub(scratch1, object, Operand(kHeapObjectTag)); 577 __ sub(scratch1, object, Operand(kHeapObjectTag));
578 __ vldr(dst, scratch1, HeapNumber::kValueOffset); 578 __ vldr(dst, scratch1, HeapNumber::kValueOffset);
579 } else { 579 } else {
580 ASSERT(destination == kCoreRegisters); 580 ASSERT(destination == kCoreRegisters);
581 // Load the double from heap number to dst1 and dst2 in double format. 581 // Load the double from heap number to dst1 and dst2 in double format.
582 __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); 582 __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset));
583 } 583 }
584 __ jmp(&done); 584 __ jmp(&done);
585 585
586 // Handle loading a double from a smi. 586 // Handle loading a double from a smi.
587 __ bind(&is_smi); 587 __ bind(&is_smi);
588 if (CpuFeatures::IsSupported(VFP3)) { 588 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
589 CpuFeatures::Scope scope(VFP3); 589 CpuFeatures::Scope scope(VFP3);
590 // Convert smi to double using VFP instructions. 590 // Convert smi to double using VFP instructions.
591 __ SmiUntag(scratch1, object); 591 __ SmiUntag(scratch1, object);
592 __ vmov(dst.high(), scratch1); 592 __ vmov(dst.high(), scratch1);
593 __ vcvt_f64_s32(dst, dst.high()); 593 __ vcvt_f64_s32(dst, dst.high());
594 if (destination == kCoreRegisters) { 594 if (destination == kCoreRegisters) {
595 // Load the converted smi to dst1 and dst2 in double format. 595 // Load the converted smi to dst1 and dst2 in double format.
596 __ vmov(dst1, dst2, dst); 596 __ vmov(dst1, dst2, dst);
597 } 597 }
598 } else { 598 } else {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
669 ASSERT(!scratch1.is(object) && !scratch2.is(object)); 669 ASSERT(!scratch1.is(object) && !scratch2.is(object));
670 ASSERT(!scratch1.is(scratch2)); 670 ASSERT(!scratch1.is(scratch2));
671 ASSERT(!heap_number_map.is(object) && 671 ASSERT(!heap_number_map.is(object) &&
672 !heap_number_map.is(scratch1) && 672 !heap_number_map.is(scratch1) &&
673 !heap_number_map.is(scratch2)); 673 !heap_number_map.is(scratch2));
674 674
675 Label done, obj_is_not_smi; 675 Label done, obj_is_not_smi;
676 676
677 __ JumpIfNotSmi(object, &obj_is_not_smi); 677 __ JumpIfNotSmi(object, &obj_is_not_smi);
678 __ SmiUntag(scratch1, object); 678 __ SmiUntag(scratch1, object);
679 if (CpuFeatures::IsSupported(VFP3)) { 679 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
680 CpuFeatures::Scope scope(VFP3); 680 CpuFeatures::Scope scope(VFP3);
681 __ vmov(single_scratch, scratch1); 681 __ vmov(single_scratch, scratch1);
682 __ vcvt_f64_s32(double_dst, single_scratch); 682 __ vcvt_f64_s32(double_dst, single_scratch);
683 if (destination == kCoreRegisters) { 683 if (destination == kCoreRegisters) {
684 __ vmov(dst1, dst2, double_dst); 684 __ vmov(dst1, dst2, double_dst);
685 } 685 }
686 } else { 686 } else {
687 Label fewer_than_20_useful_bits; 687 Label fewer_than_20_useful_bits;
688 // Expected output: 688 // Expected output:
689 // | dst1 | dst2 | 689 // | dst1 | dst2 |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 737
738 __ bind(&obj_is_not_smi); 738 __ bind(&obj_is_not_smi);
739 if (FLAG_debug_code) { 739 if (FLAG_debug_code) {
740 __ AbortIfNotRootValue(heap_number_map, 740 __ AbortIfNotRootValue(heap_number_map,
741 Heap::kHeapNumberMapRootIndex, 741 Heap::kHeapNumberMapRootIndex,
742 "HeapNumberMap register clobbered."); 742 "HeapNumberMap register clobbered.");
743 } 743 }
744 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 744 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
745 745
746 // Load the number. 746 // Load the number.
747 if (CpuFeatures::IsSupported(VFP3)) { 747 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
748 CpuFeatures::Scope scope(VFP3); 748 CpuFeatures::Scope scope(VFP3);
749 // Load the double value. 749 // Load the double value.
750 __ sub(scratch1, object, Operand(kHeapObjectTag)); 750 __ sub(scratch1, object, Operand(kHeapObjectTag));
751 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset); 751 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset);
752 752
753 __ EmitVFPTruncate(kRoundToZero, 753 __ EmitVFPTruncate(kRoundToZero,
754 single_scratch, 754 single_scratch,
755 double_dst, 755 double_dst,
756 scratch1, 756 scratch1,
757 scratch2, 757 scratch2,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
811 811
812 if (FLAG_debug_code) { 812 if (FLAG_debug_code) {
813 __ AbortIfNotRootValue(heap_number_map, 813 __ AbortIfNotRootValue(heap_number_map,
814 Heap::kHeapNumberMapRootIndex, 814 Heap::kHeapNumberMapRootIndex,
815 "HeapNumberMap register clobbered."); 815 "HeapNumberMap register clobbered.");
816 } 816 }
817 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 817 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
818 818
819 // Object is a heap number. 819 // Object is a heap number.
820 // Convert the floating point value to a 32-bit integer. 820 // Convert the floating point value to a 32-bit integer.
821 if (CpuFeatures::IsSupported(VFP3)) { 821 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
822 CpuFeatures::Scope scope(VFP3); 822 CpuFeatures::Scope scope(VFP3);
823 SwVfpRegister single_scratch = double_scratch.low(); 823 SwVfpRegister single_scratch = double_scratch.low();
824 // Load the double value. 824 // Load the double value.
825 __ sub(scratch1, object, Operand(kHeapObjectTag)); 825 __ sub(scratch1, object, Operand(kHeapObjectTag));
826 __ vldr(double_scratch, scratch1, HeapNumber::kValueOffset); 826 __ vldr(double_scratch, scratch1, HeapNumber::kValueOffset);
827 827
828 __ EmitVFPTruncate(kRoundToZero, 828 __ EmitVFPTruncate(kRoundToZero,
829 single_scratch, 829 single_scratch,
830 double_scratch, 830 double_scratch,
831 scratch1, 831 scratch1,
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 __ mov(r0, Operand(NOT_EQUAL), LeaveCC, ne); 1146 __ mov(r0, Operand(NOT_EQUAL), LeaveCC, ne);
1147 } 1147 }
1148 __ Ret(ne); 1148 __ Ret(ne);
1149 } else { 1149 } else {
1150 // Smi compared non-strictly with a non-Smi non-heap-number. Call 1150 // Smi compared non-strictly with a non-Smi non-heap-number. Call
1151 // the runtime. 1151 // the runtime.
1152 __ b(ne, slow); 1152 __ b(ne, slow);
1153 } 1153 }
1154 1154
1155 // Lhs is a smi, rhs is a number. 1155 // Lhs is a smi, rhs is a number.
1156 if (CpuFeatures::IsSupported(VFP3)) { 1156 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
1157 // Convert lhs to a double in d7. 1157 // Convert lhs to a double in d7.
1158 CpuFeatures::Scope scope(VFP3); 1158 CpuFeatures::Scope scope(VFP3);
1159 __ SmiToDoubleVFPRegister(lhs, d7, r7, s15); 1159 __ SmiToDoubleVFPRegister(lhs, d7, r7, s15);
1160 // Load the double from rhs, tagged HeapNumber r0, to d6. 1160 // Load the double from rhs, tagged HeapNumber r0, to d6.
1161 __ sub(r7, rhs, Operand(kHeapObjectTag)); 1161 __ sub(r7, rhs, Operand(kHeapObjectTag));
1162 __ vldr(d6, r7, HeapNumber::kValueOffset); 1162 __ vldr(d6, r7, HeapNumber::kValueOffset);
1163 } else { 1163 } else {
1164 __ push(lr); 1164 __ push(lr);
1165 // Convert lhs to a double in r2, r3. 1165 // Convert lhs to a double in r2, r3.
1166 __ mov(r7, Operand(lhs)); 1166 __ mov(r7, Operand(lhs));
(...skipping 19 matching lines...) Expand all
1186 __ mov(r0, Operand(NOT_EQUAL), LeaveCC, ne); 1186 __ mov(r0, Operand(NOT_EQUAL), LeaveCC, ne);
1187 } 1187 }
1188 __ Ret(ne); 1188 __ Ret(ne);
1189 } else { 1189 } else {
1190 // Smi compared non-strictly with a non-smi non-heap-number. Call 1190 // Smi compared non-strictly with a non-smi non-heap-number. Call
1191 // the runtime. 1191 // the runtime.
1192 __ b(ne, slow); 1192 __ b(ne, slow);
1193 } 1193 }
1194 1194
1195 // Rhs is a smi, lhs is a heap number. 1195 // Rhs is a smi, lhs is a heap number.
1196 if (CpuFeatures::IsSupported(VFP3)) { 1196 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
1197 CpuFeatures::Scope scope(VFP3); 1197 CpuFeatures::Scope scope(VFP3);
1198 // Load the double from lhs, tagged HeapNumber r1, to d7. 1198 // Load the double from lhs, tagged HeapNumber r1, to d7.
1199 __ sub(r7, lhs, Operand(kHeapObjectTag)); 1199 __ sub(r7, lhs, Operand(kHeapObjectTag));
1200 __ vldr(d7, r7, HeapNumber::kValueOffset); 1200 __ vldr(d7, r7, HeapNumber::kValueOffset);
1201 // Convert rhs to a double in d6 . 1201 // Convert rhs to a double in d6 .
1202 __ SmiToDoubleVFPRegister(rhs, d6, r7, s13); 1202 __ SmiToDoubleVFPRegister(rhs, d6, r7, s13);
1203 } else { 1203 } else {
1204 __ push(lr); 1204 __ push(lr);
1205 // Load lhs to a double in r2, r3. 1205 // Load lhs to a double in r2, r3.
1206 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset)); 1206 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset));
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1366 (lhs.is(r1) && rhs.is(r0))); 1366 (lhs.is(r1) && rhs.is(r0)));
1367 1367
1368 __ CompareObjectType(rhs, r3, r2, HEAP_NUMBER_TYPE); 1368 __ CompareObjectType(rhs, r3, r2, HEAP_NUMBER_TYPE);
1369 __ b(ne, not_heap_numbers); 1369 __ b(ne, not_heap_numbers);
1370 __ ldr(r2, FieldMemOperand(lhs, HeapObject::kMapOffset)); 1370 __ ldr(r2, FieldMemOperand(lhs, HeapObject::kMapOffset));
1371 __ cmp(r2, r3); 1371 __ cmp(r2, r3);
1372 __ b(ne, slow); // First was a heap number, second wasn't. Go slow case. 1372 __ b(ne, slow); // First was a heap number, second wasn't. Go slow case.
1373 1373
1374 // Both are heap numbers. Load them up then jump to the code we have 1374 // Both are heap numbers. Load them up then jump to the code we have
1375 // for that. 1375 // for that.
1376 if (CpuFeatures::IsSupported(VFP3)) { 1376 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
1377 CpuFeatures::Scope scope(VFP3); 1377 CpuFeatures::Scope scope(VFP3);
1378 __ sub(r7, rhs, Operand(kHeapObjectTag)); 1378 __ sub(r7, rhs, Operand(kHeapObjectTag));
1379 __ vldr(d6, r7, HeapNumber::kValueOffset); 1379 __ vldr(d6, r7, HeapNumber::kValueOffset);
1380 __ sub(r7, lhs, Operand(kHeapObjectTag)); 1380 __ sub(r7, lhs, Operand(kHeapObjectTag));
1381 __ vldr(d7, r7, HeapNumber::kValueOffset); 1381 __ vldr(d7, r7, HeapNumber::kValueOffset);
1382 } else { 1382 } else {
1383 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset)); 1383 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset));
1384 __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset)); 1384 __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset));
1385 } 1385 }
1386 __ jmp(both_loaded_as_doubles); 1386 __ jmp(both_loaded_as_doubles);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1456 1456
1457 // Calculate the entry in the number string cache. The hash value in the 1457 // Calculate the entry in the number string cache. The hash value in the
1458 // number string cache for smis is just the smi value, and the hash for 1458 // number string cache for smis is just the smi value, and the hash for
1459 // doubles is the xor of the upper and lower words. See 1459 // doubles is the xor of the upper and lower words. See
1460 // Heap::GetNumberStringCache. 1460 // Heap::GetNumberStringCache.
1461 Isolate* isolate = masm->isolate(); 1461 Isolate* isolate = masm->isolate();
1462 Label is_smi; 1462 Label is_smi;
1463 Label load_result_from_cache; 1463 Label load_result_from_cache;
1464 if (!object_is_smi) { 1464 if (!object_is_smi) {
1465 __ JumpIfSmi(object, &is_smi); 1465 __ JumpIfSmi(object, &is_smi);
1466 if (CpuFeatures::IsSupported(VFP3)) { 1466 if (isolate->cpu_features()->IsSupported(VFP3)) {
1467 CpuFeatures::Scope scope(VFP3); 1467 CpuFeatures::Scope scope(VFP3);
1468 __ CheckMap(object, 1468 __ CheckMap(object,
1469 scratch1, 1469 scratch1,
1470 Heap::kHeapNumberMapRootIndex, 1470 Heap::kHeapNumberMapRootIndex,
1471 not_found, 1471 not_found,
1472 true); 1472 true);
1473 1473
1474 STATIC_ASSERT(8 == kDoubleSize); 1474 STATIC_ASSERT(8 == kDoubleSize);
1475 __ add(scratch1, 1475 __ add(scratch1,
1476 object, 1476 object,
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 // In cases 3 and 4 we have found out we were dealing with a number-number 1590 // In cases 3 and 4 we have found out we were dealing with a number-number
1591 // comparison. If VFP3 is supported the double values of the numbers have 1591 // comparison. If VFP3 is supported the double values of the numbers have
1592 // been loaded into d7 and d6. Otherwise, the double values have been loaded 1592 // been loaded into d7 and d6. Otherwise, the double values have been loaded
1593 // into r0, r1, r2, and r3. 1593 // into r0, r1, r2, and r3.
1594 EmitSmiNonsmiComparison(masm, lhs_, rhs_, &lhs_not_nan, &slow, strict_); 1594 EmitSmiNonsmiComparison(masm, lhs_, rhs_, &lhs_not_nan, &slow, strict_);
1595 1595
1596 __ bind(&both_loaded_as_doubles); 1596 __ bind(&both_loaded_as_doubles);
1597 // The arguments have been converted to doubles and stored in d6 and d7, if 1597 // The arguments have been converted to doubles and stored in d6 and d7, if
1598 // VFP3 is supported, or in r0, r1, r2, and r3. 1598 // VFP3 is supported, or in r0, r1, r2, and r3.
1599 Isolate* isolate = masm->isolate(); 1599 Isolate* isolate = masm->isolate();
1600 if (CpuFeatures::IsSupported(VFP3)) { 1600 if (isolate->cpu_features()->IsSupported(VFP3)) {
1601 __ bind(&lhs_not_nan); 1601 __ bind(&lhs_not_nan);
1602 CpuFeatures::Scope scope(VFP3); 1602 CpuFeatures::Scope scope(VFP3);
1603 Label no_nan; 1603 Label no_nan;
1604 // ARMv7 VFP3 instructions to implement double precision comparison. 1604 // ARMv7 VFP3 instructions to implement double precision comparison.
1605 __ VFPCompareAndSetFlags(d7, d6); 1605 __ VFPCompareAndSetFlags(d7, d6);
1606 Label nan; 1606 Label nan;
1607 __ b(vs, &nan); 1607 __ b(vs, &nan);
1608 __ mov(r0, Operand(EQUAL), LeaveCC, eq); 1608 __ mov(r0, Operand(EQUAL), LeaveCC, eq);
1609 __ mov(r0, Operand(LESS), LeaveCC, lt); 1609 __ mov(r0, Operand(LESS), LeaveCC, lt);
1610 __ mov(r0, Operand(GREATER), LeaveCC, gt); 1610 __ mov(r0, Operand(GREATER), LeaveCC, gt);
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1700 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1701 // tagged as a small integer. 1701 // tagged as a small integer.
1702 __ InvokeBuiltin(native, JUMP_JS); 1702 __ InvokeBuiltin(native, JUMP_JS);
1703 } 1703 }
1704 1704
1705 1705
1706 // This stub does not handle the inlined cases (Smis, Booleans, undefined). 1706 // This stub does not handle the inlined cases (Smis, Booleans, undefined).
1707 // The stub returns zero for false, and a non-zero value for true. 1707 // The stub returns zero for false, and a non-zero value for true.
1708 void ToBooleanStub::Generate(MacroAssembler* masm) { 1708 void ToBooleanStub::Generate(MacroAssembler* masm) {
1709 // This stub uses VFP3 instructions. 1709 // This stub uses VFP3 instructions.
1710 ASSERT(CpuFeatures::IsEnabled(VFP3)); 1710 ASSERT(Isolate::Current()->cpu_features()->IsEnabled(VFP3));
1711 1711
1712 Label false_result; 1712 Label false_result;
1713 Label not_heap_number; 1713 Label not_heap_number;
1714 Register scratch = r9.is(tos_) ? r7 : r9; 1714 Register scratch = r9.is(tos_) ? r7 : r9;
1715 1715
1716 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1716 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1717 __ cmp(tos_, ip); 1717 __ cmp(tos_, ip);
1718 __ b(eq, &false_result); 1718 __ b(eq, &false_result);
1719 1719
1720 // HeapNumber => false iff +0, -0, or NaN. 1720 // HeapNumber => false iff +0, -0, or NaN.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1787 // with the double precision floating point operands in r0 and r1 (for the 1787 // with the double precision floating point operands in r0 and r1 (for the
1788 // value in r1) and r2 and r3 (for the value in r0). 1788 // value in r1) and r2 and r3 (for the value in r0).
1789 void GenericBinaryOpStub::HandleBinaryOpSlowCases( 1789 void GenericBinaryOpStub::HandleBinaryOpSlowCases(
1790 MacroAssembler* masm, 1790 MacroAssembler* masm,
1791 Label* not_smi, 1791 Label* not_smi,
1792 Register lhs, 1792 Register lhs,
1793 Register rhs, 1793 Register rhs,
1794 const Builtins::JavaScript& builtin) { 1794 const Builtins::JavaScript& builtin) {
1795 Label slow, slow_reverse, do_the_call; 1795 Label slow, slow_reverse, do_the_call;
1796 bool use_fp_registers = 1796 bool use_fp_registers =
1797 CpuFeatures::IsSupported(VFP3) && 1797 Isolate::Current()->cpu_features()->IsSupported(VFP3) &&
1798 Token::MOD != op_; 1798 Token::MOD != op_;
1799 1799
1800 ASSERT((lhs.is(r0) && rhs.is(r1)) || (lhs.is(r1) && rhs.is(r0))); 1800 ASSERT((lhs.is(r0) && rhs.is(r1)) || (lhs.is(r1) && rhs.is(r0)));
1801 Register heap_number_map = r6; 1801 Register heap_number_map = r6;
1802 1802
1803 if (ShouldGenerateSmiCode()) { 1803 if (ShouldGenerateSmiCode()) {
1804 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 1804 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
1805 1805
1806 // Smi-smi case (overflow). 1806 // Smi-smi case (overflow).
1807 // Since both are Smis there is no heap number to overwrite, so allocate. 1807 // Since both are Smis there is no heap number to overwrite, so allocate.
1808 // The new heap number is in r5. r3 and r7 are scratch. 1808 // The new heap number is in r5. r3 and r7 are scratch.
1809 __ AllocateHeapNumber( 1809 __ AllocateHeapNumber(
1810 r5, r3, r7, heap_number_map, lhs.is(r0) ? &slow_reverse : &slow); 1810 r5, r3, r7, heap_number_map, lhs.is(r0) ? &slow_reverse : &slow);
1811 1811
1812 // If we have floating point hardware, inline ADD, SUB, MUL, and DIV, 1812 // If we have floating point hardware, inline ADD, SUB, MUL, and DIV,
1813 // using registers d7 and d6 for the double values. 1813 // using registers d7 and d6 for the double values.
1814 if (CpuFeatures::IsSupported(VFP3)) { 1814 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
1815 CpuFeatures::Scope scope(VFP3); 1815 CpuFeatures::Scope scope(VFP3);
1816 __ mov(r7, Operand(rhs, ASR, kSmiTagSize)); 1816 __ mov(r7, Operand(rhs, ASR, kSmiTagSize));
1817 __ vmov(s15, r7); 1817 __ vmov(s15, r7);
1818 __ vcvt_f64_s32(d7, s15); 1818 __ vcvt_f64_s32(d7, s15);
1819 __ mov(r7, Operand(lhs, ASR, kSmiTagSize)); 1819 __ mov(r7, Operand(lhs, ASR, kSmiTagSize));
1820 __ vmov(s13, r7); 1820 __ vmov(s13, r7);
1821 __ vcvt_f64_s32(d6, s13); 1821 __ vcvt_f64_s32(d6, s13);
1822 if (!use_fp_registers) { 1822 if (!use_fp_registers) {
1823 __ vmov(r2, r3, d7); 1823 __ vmov(r2, r3, d7);
1824 __ vmov(r0, r1, d6); 1824 __ vmov(r0, r1, d6);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 // Calling convention says that second double is in r2 and r3. 1900 // Calling convention says that second double is in r2 and r3.
1901 __ Ldrd(r2, r3, FieldMemOperand(r0, HeapNumber::kValueOffset)); 1901 __ Ldrd(r2, r3, FieldMemOperand(r0, HeapNumber::kValueOffset));
1902 } 1902 }
1903 __ jmp(&finished_loading_r0); 1903 __ jmp(&finished_loading_r0);
1904 __ bind(&r0_is_smi); 1904 __ bind(&r0_is_smi);
1905 if (mode_ == OVERWRITE_RIGHT) { 1905 if (mode_ == OVERWRITE_RIGHT) {
1906 // We can't overwrite a Smi so get address of new heap number into r5. 1906 // We can't overwrite a Smi so get address of new heap number into r5.
1907 __ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow); 1907 __ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow);
1908 } 1908 }
1909 1909
1910 if (CpuFeatures::IsSupported(VFP3)) { 1910 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
1911 CpuFeatures::Scope scope(VFP3); 1911 CpuFeatures::Scope scope(VFP3);
1912 // Convert smi in r0 to double in d7. 1912 // Convert smi in r0 to double in d7.
1913 __ mov(r7, Operand(r0, ASR, kSmiTagSize)); 1913 __ mov(r7, Operand(r0, ASR, kSmiTagSize));
1914 __ vmov(s15, r7); 1914 __ vmov(s15, r7);
1915 __ vcvt_f64_s32(d7, s15); 1915 __ vcvt_f64_s32(d7, s15);
1916 if (!use_fp_registers) { 1916 if (!use_fp_registers) {
1917 __ vmov(r2, r3, d7); 1917 __ vmov(r2, r3, d7);
1918 } 1918 }
1919 } else { 1919 } else {
1920 // Write Smi from r0 to r3 and r2 in double format. 1920 // Write Smi from r0 to r3 and r2 in double format.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1957 // Calling convention says that first double is in r0 and r1. 1957 // Calling convention says that first double is in r0 and r1.
1958 __ Ldrd(r0, r1, FieldMemOperand(r1, HeapNumber::kValueOffset)); 1958 __ Ldrd(r0, r1, FieldMemOperand(r1, HeapNumber::kValueOffset));
1959 } 1959 }
1960 __ jmp(&finished_loading_r1); 1960 __ jmp(&finished_loading_r1);
1961 __ bind(&r1_is_smi); 1961 __ bind(&r1_is_smi);
1962 if (mode_ == OVERWRITE_LEFT) { 1962 if (mode_ == OVERWRITE_LEFT) {
1963 // We can't overwrite a Smi so get address of new heap number into r5. 1963 // We can't overwrite a Smi so get address of new heap number into r5.
1964 __ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow); 1964 __ AllocateHeapNumber(r5, r4, r7, heap_number_map, &slow);
1965 } 1965 }
1966 1966
1967 if (CpuFeatures::IsSupported(VFP3)) { 1967 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
1968 CpuFeatures::Scope scope(VFP3); 1968 CpuFeatures::Scope scope(VFP3);
1969 // Convert smi in r1 to double in d6. 1969 // Convert smi in r1 to double in d6.
1970 __ mov(r7, Operand(r1, ASR, kSmiTagSize)); 1970 __ mov(r7, Operand(r1, ASR, kSmiTagSize));
1971 __ vmov(s13, r7); 1971 __ vmov(s13, r7);
1972 __ vcvt_f64_s32(d6, s13); 1972 __ vcvt_f64_s32(d6, s13);
1973 if (!use_fp_registers) { 1973 if (!use_fp_registers) {
1974 __ vmov(r0, r1, d6); 1974 __ vmov(r0, r1, d6);
1975 } 1975 }
1976 } else { 1976 } else {
1977 // Write Smi from r1 to r1 and r0 in double format. 1977 // Write Smi from r1 to r1 and r0 in double format.
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2170 __ mov(r2, Operand(r3, ASR, r2)); 2170 __ mov(r2, Operand(r3, ASR, r2));
2171 break; 2171 break;
2172 case Token::SHR: 2172 case Token::SHR:
2173 // Use only the 5 least significant bits of the shift count. 2173 // Use only the 5 least significant bits of the shift count.
2174 __ and_(r2, r2, Operand(0x1f)); 2174 __ and_(r2, r2, Operand(0x1f));
2175 __ mov(r2, Operand(r3, LSR, r2), SetCC); 2175 __ mov(r2, Operand(r3, LSR, r2), SetCC);
2176 // SHR is special because it is required to produce a positive answer. 2176 // SHR is special because it is required to produce a positive answer.
2177 // The code below for writing into heap numbers isn't capable of writing 2177 // The code below for writing into heap numbers isn't capable of writing
2178 // the register as an unsigned int so we go to slow case if we hit this 2178 // the register as an unsigned int so we go to slow case if we hit this
2179 // case. 2179 // case.
2180 if (CpuFeatures::IsSupported(VFP3)) { 2180 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
2181 __ b(mi, &result_not_a_smi); 2181 __ b(mi, &result_not_a_smi);
2182 } else { 2182 } else {
2183 __ b(mi, &slow); 2183 __ b(mi, &slow);
2184 } 2184 }
2185 break; 2185 break;
2186 case Token::SHL: 2186 case Token::SHL:
2187 // Use only the 5 least significant bits of the shift count. 2187 // Use only the 5 least significant bits of the shift count.
2188 __ and_(r2, r2, Operand(0x1f)); 2188 __ and_(r2, r2, Operand(0x1f));
2189 __ mov(r2, Operand(r3, LSL, r2)); 2189 __ mov(r2, Operand(r3, LSL, r2));
2190 break; 2190 break;
(...skipping 27 matching lines...) Expand all
2218 default: break; 2218 default: break;
2219 } 2219 }
2220 __ bind(&got_a_heap_number); 2220 __ bind(&got_a_heap_number);
2221 // r2: Answer as signed int32. 2221 // r2: Answer as signed int32.
2222 // r5: Heap number to write answer into. 2222 // r5: Heap number to write answer into.
2223 2223
2224 // Nothing can go wrong now, so move the heap number to r0, which is the 2224 // Nothing can go wrong now, so move the heap number to r0, which is the
2225 // result. 2225 // result.
2226 __ mov(r0, Operand(r5)); 2226 __ mov(r0, Operand(r5));
2227 2227
2228 if (CpuFeatures::IsSupported(VFP3)) { 2228 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
2229 // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. 2229 // Convert the int32 in r2 to the heap number in r0. r3 is corrupted.
2230 CpuFeatures::Scope scope(VFP3); 2230 CpuFeatures::Scope scope(VFP3);
2231 __ vmov(s0, r2); 2231 __ vmov(s0, r2);
2232 if (op_ == Token::SHR) { 2232 if (op_ == Token::SHR) {
2233 __ vcvt_f64_u32(d0, s0); 2233 __ vcvt_f64_u32(d0, s0);
2234 } else { 2234 } else {
2235 __ vcvt_f64_s32(d0, s0); 2235 __ vcvt_f64_s32(d0, s0);
2236 } 2236 }
2237 __ sub(r3, r0, Operand(kHeapObjectTag)); 2237 __ sub(r3, r0, Operand(kHeapObjectTag));
2238 __ vstr(d0, r3, HeapNumber::kValueOffset); 2238 __ vstr(d0, r3, HeapNumber::kValueOffset);
(...skipping 831 matching lines...) Expand 10 before | Expand all | Expand 10 after
3070 3070
3071 switch (op_) { 3071 switch (op_) {
3072 case Token::ADD: 3072 case Token::ADD:
3073 case Token::SUB: 3073 case Token::SUB:
3074 case Token::MUL: 3074 case Token::MUL:
3075 case Token::DIV: 3075 case Token::DIV:
3076 case Token::MOD: { 3076 case Token::MOD: {
3077 // Load left and right operands into d6 and d7 or r0/r1 and r2/r3 3077 // Load left and right operands into d6 and d7 or r0/r1 and r2/r3
3078 // depending on whether VFP3 is available or not. 3078 // depending on whether VFP3 is available or not.
3079 FloatingPointHelper::Destination destination = 3079 FloatingPointHelper::Destination destination =
3080 CpuFeatures::IsSupported(VFP3) && 3080 Isolate::Current()->cpu_features()->IsSupported(VFP3) &&
3081 op_ != Token::MOD ? 3081 op_ != Token::MOD ?
3082 FloatingPointHelper::kVFPRegisters : 3082 FloatingPointHelper::kVFPRegisters :
3083 FloatingPointHelper::kCoreRegisters; 3083 FloatingPointHelper::kCoreRegisters;
3084 3084
3085 // Allocate new heap number for result. 3085 // Allocate new heap number for result.
3086 Register result = r5; 3086 Register result = r5;
3087 GenerateHeapResultAllocation( 3087 GenerateHeapResultAllocation(
3088 masm, result, heap_number_map, scratch1, scratch2, gc_required); 3088 masm, result, heap_number_map, scratch1, scratch2, gc_required);
3089 3089
3090 // Load the operands. 3090 // Load the operands.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
3183 __ mov(r2, Operand(r3, ASR, r2)); 3183 __ mov(r2, Operand(r3, ASR, r2));
3184 break; 3184 break;
3185 case Token::SHR: 3185 case Token::SHR:
3186 // Use only the 5 least significant bits of the shift count. 3186 // Use only the 5 least significant bits of the shift count.
3187 __ GetLeastBitsFromInt32(r2, r2, 5); 3187 __ GetLeastBitsFromInt32(r2, r2, 5);
3188 __ mov(r2, Operand(r3, LSR, r2), SetCC); 3188 __ mov(r2, Operand(r3, LSR, r2), SetCC);
3189 // SHR is special because it is required to produce a positive answer. 3189 // SHR is special because it is required to produce a positive answer.
3190 // The code below for writing into heap numbers isn't capable of 3190 // The code below for writing into heap numbers isn't capable of
3191 // writing the register as an unsigned int so we go to slow case if we 3191 // writing the register as an unsigned int so we go to slow case if we
3192 // hit this case. 3192 // hit this case.
3193 if (CpuFeatures::IsSupported(VFP3)) { 3193 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
3194 __ b(mi, &result_not_a_smi); 3194 __ b(mi, &result_not_a_smi);
3195 } else { 3195 } else {
3196 __ b(mi, not_numbers); 3196 __ b(mi, not_numbers);
3197 } 3197 }
3198 break; 3198 break;
3199 case Token::SHL: 3199 case Token::SHL:
3200 // Use only the 5 least significant bits of the shift count. 3200 // Use only the 5 least significant bits of the shift count.
3201 __ GetLeastBitsFromInt32(r2, r2, 5); 3201 __ GetLeastBitsFromInt32(r2, r2, 5);
3202 __ mov(r2, Operand(r3, LSL, r2)); 3202 __ mov(r2, Operand(r3, LSL, r2));
3203 break; 3203 break;
(...skipping 18 matching lines...) Expand all
3222 masm, result, heap_number_map, scratch1, scratch2, gc_required); 3222 masm, result, heap_number_map, scratch1, scratch2, gc_required);
3223 } 3223 }
3224 3224
3225 // r2: Answer as signed int32. 3225 // r2: Answer as signed int32.
3226 // r5: Heap number to write answer into. 3226 // r5: Heap number to write answer into.
3227 3227
3228 // Nothing can go wrong now, so move the heap number to r0, which is the 3228 // Nothing can go wrong now, so move the heap number to r0, which is the
3229 // result. 3229 // result.
3230 __ mov(r0, Operand(r5)); 3230 __ mov(r0, Operand(r5));
3231 3231
3232 if (CpuFeatures::IsSupported(VFP3)) { 3232 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
3233 // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. As 3233 // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. As
3234 // mentioned above SHR needs to always produce a positive result. 3234 // mentioned above SHR needs to always produce a positive result.
3235 CpuFeatures::Scope scope(VFP3); 3235 CpuFeatures::Scope scope(VFP3);
3236 __ vmov(s0, r2); 3236 __ vmov(s0, r2);
3237 if (op_ == Token::SHR) { 3237 if (op_ == Token::SHR) {
3238 __ vcvt_f64_u32(d0, s0); 3238 __ vcvt_f64_u32(d0, s0);
3239 } else { 3239 } else {
3240 __ vcvt_f64_s32(d0, s0); 3240 __ vcvt_f64_s32(d0, s0);
3241 } 3241 }
3242 __ sub(r3, r0, Operand(kHeapObjectTag)); 3242 __ sub(r3, r0, Operand(kHeapObjectTag));
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
3351 switch (op_) { 3351 switch (op_) {
3352 case Token::ADD: 3352 case Token::ADD:
3353 case Token::SUB: 3353 case Token::SUB:
3354 case Token::MUL: 3354 case Token::MUL:
3355 case Token::DIV: 3355 case Token::DIV:
3356 case Token::MOD: { 3356 case Token::MOD: {
3357 // Load both operands and check that they are 32-bit integer. 3357 // Load both operands and check that they are 32-bit integer.
3358 // Jump to type transition if they are not. The registers r0 and r1 (right 3358 // Jump to type transition if they are not. The registers r0 and r1 (right
3359 // and left) are preserved for the runtime call. 3359 // and left) are preserved for the runtime call.
3360 FloatingPointHelper::Destination destination = 3360 FloatingPointHelper::Destination destination =
3361 CpuFeatures::IsSupported(VFP3) && 3361 Isolate::Current()->cpu_features()->IsSupported(VFP3) &&
3362 op_ != Token::MOD ? 3362 op_ != Token::MOD ?
3363 FloatingPointHelper::kVFPRegisters : 3363 FloatingPointHelper::kVFPRegisters :
3364 FloatingPointHelper::kCoreRegisters; 3364 FloatingPointHelper::kCoreRegisters;
3365 3365
3366 FloatingPointHelper::LoadNumberAsInt32Double(masm, 3366 FloatingPointHelper::LoadNumberAsInt32Double(masm,
3367 right, 3367 right,
3368 destination, 3368 destination,
3369 d7, 3369 d7,
3370 r2, 3370 r2,
3371 r3, 3371 r3,
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
3538 break; 3538 break;
3539 case Token::SHR: 3539 case Token::SHR:
3540 __ and_(r2, r2, Operand(0x1f)); 3540 __ and_(r2, r2, Operand(0x1f));
3541 __ mov(r2, Operand(r3, LSR, r2), SetCC); 3541 __ mov(r2, Operand(r3, LSR, r2), SetCC);
3542 // SHR is special because it is required to produce a positive answer. 3542 // SHR is special because it is required to produce a positive answer.
3543 // We only get a negative result if the shift value (r2) is 0. 3543 // We only get a negative result if the shift value (r2) is 0.
3544 // This result cannot be respresented as a signed 32-bit integer, try 3544 // This result cannot be respresented as a signed 32-bit integer, try
3545 // to return a heap number if we can. 3545 // to return a heap number if we can.
3546 // The non vfp3 code does not support this special case, so jump to 3546 // The non vfp3 code does not support this special case, so jump to
3547 // runtime if we don't support it. 3547 // runtime if we don't support it.
3548 if (CpuFeatures::IsSupported(VFP3)) { 3548 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
3549 __ b(mi, 3549 __ b(mi,
3550 (result_type_ <= TRBinaryOpIC::INT32) ? &transition 3550 (result_type_ <= TRBinaryOpIC::INT32) ? &transition
3551 : &return_heap_number); 3551 : &return_heap_number);
3552 } else { 3552 } else {
3553 __ b(mi, (result_type_ <= TRBinaryOpIC::INT32) ? &transition 3553 __ b(mi, (result_type_ <= TRBinaryOpIC::INT32) ? &transition
3554 : &call_runtime); 3554 : &call_runtime);
3555 } 3555 }
3556 break; 3556 break;
3557 case Token::SHL: 3557 case Token::SHL:
3558 __ and_(r2, r2, Operand(0x1f)); 3558 __ and_(r2, r2, Operand(0x1f));
3559 __ mov(r2, Operand(r3, LSL, r2)); 3559 __ mov(r2, Operand(r3, LSL, r2));
3560 break; 3560 break;
3561 default: 3561 default:
3562 UNREACHABLE(); 3562 UNREACHABLE();
3563 } 3563 }
3564 3564
3565 // Check if the result fits in a smi. 3565 // Check if the result fits in a smi.
3566 __ add(scratch1, r2, Operand(0x40000000), SetCC); 3566 __ add(scratch1, r2, Operand(0x40000000), SetCC);
3567 // If not try to return a heap number. (We know the result is an int32.) 3567 // If not try to return a heap number. (We know the result is an int32.)
3568 __ b(mi, &return_heap_number); 3568 __ b(mi, &return_heap_number);
3569 // Tag the result and return. 3569 // Tag the result and return.
3570 __ SmiTag(r0, r2); 3570 __ SmiTag(r0, r2);
3571 __ Ret(); 3571 __ Ret();
3572 3572
3573 __ bind(&return_heap_number); 3573 __ bind(&return_heap_number);
3574 if (CpuFeatures::IsSupported(VFP3)) { 3574 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
3575 CpuFeatures::Scope scope(VFP3); 3575 CpuFeatures::Scope scope(VFP3);
3576 heap_number_result = r5; 3576 heap_number_result = r5;
3577 GenerateHeapResultAllocation(masm, 3577 GenerateHeapResultAllocation(masm,
3578 heap_number_result, 3578 heap_number_result,
3579 heap_number_map, 3579 heap_number_map,
3580 scratch1, 3580 scratch1,
3581 scratch2, 3581 scratch2,
3582 &call_runtime); 3582 &call_runtime);
3583 3583
3584 if (op_ != Token::SHR) { 3584 if (op_ != Token::SHR) {
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
3799 3799
3800 Label input_not_smi; 3800 Label input_not_smi;
3801 Label loaded; 3801 Label loaded;
3802 Label calculate; 3802 Label calculate;
3803 Label invalid_cache; 3803 Label invalid_cache;
3804 const Register scratch0 = r9; 3804 const Register scratch0 = r9;
3805 const Register scratch1 = r7; 3805 const Register scratch1 = r7;
3806 const Register cache_entry = r0; 3806 const Register cache_entry = r0;
3807 const bool tagged = (argument_type_ == TAGGED); 3807 const bool tagged = (argument_type_ == TAGGED);
3808 3808
3809 if (CpuFeatures::IsSupported(VFP3)) { 3809 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
3810 CpuFeatures::Scope scope(VFP3); 3810 CpuFeatures::Scope scope(VFP3);
3811 if (tagged) { 3811 if (tagged) {
3812 // Argument is a number and is on stack and in r0. 3812 // Argument is a number and is on stack and in r0.
3813 // Load argument and check if it is a smi. 3813 // Load argument and check if it is a smi.
3814 __ JumpIfNotSmi(r0, &input_not_smi); 3814 __ JumpIfNotSmi(r0, &input_not_smi);
3815 3815
3816 // Input is a smi. Convert to double and load the low and high words 3816 // Input is a smi. Convert to double and load the low and high words
3817 // of the double into r2, r3. 3817 // of the double into r2, r3.
3818 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); 3818 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2);
3819 __ b(&loaded); 3819 __ b(&loaded);
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
3887 // Cache hit. Load result, cleanup and return. 3887 // Cache hit. Load result, cleanup and return.
3888 if (tagged) { 3888 if (tagged) {
3889 // Pop input value from stack and load result into r0. 3889 // Pop input value from stack and load result into r0.
3890 __ pop(); 3890 __ pop();
3891 __ mov(r0, Operand(r6)); 3891 __ mov(r0, Operand(r6));
3892 } else { 3892 } else {
3893 // Load result into d2. 3893 // Load result into d2.
3894 __ vldr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset)); 3894 __ vldr(d2, FieldMemOperand(r6, HeapNumber::kValueOffset));
3895 } 3895 }
3896 __ Ret(); 3896 __ Ret();
3897 } // if (CpuFeatures::IsSupported(VFP3)) 3897 } // if (Isolate::Current()->cpu_features()->IsSupported(VFP3))
3898 3898
3899 __ bind(&calculate); 3899 __ bind(&calculate);
3900 if (tagged) { 3900 if (tagged) {
3901 __ bind(&invalid_cache); 3901 __ bind(&invalid_cache);
3902 ExternalReference runtime_function = 3902 ExternalReference runtime_function =
3903 ExternalReference(RuntimeFunction(), masm->isolate()); 3903 ExternalReference(RuntimeFunction(), masm->isolate());
3904 __ TailCallExternalReference(runtime_function, 1, 1); 3904 __ TailCallExternalReference(runtime_function, 1, 1);
3905 } else { 3905 } else {
3906 if (!CpuFeatures::IsSupported(VFP3)) UNREACHABLE(); 3906 if (!Isolate::Current()->cpu_features()->IsSupported(VFP3)) UNREACHABLE();
3907 CpuFeatures::Scope scope(VFP3); 3907 CpuFeatures::Scope scope(VFP3);
3908 3908
3909 Label no_update; 3909 Label no_update;
3910 Label skip_cache; 3910 Label skip_cache;
3911 const Register heap_number_map = r5; 3911 const Register heap_number_map = r5;
3912 3912
3913 // Call C function to calculate the result and update the cache. 3913 // Call C function to calculate the result and update the cache.
3914 // Register r0 holds precalculated cache entry address; preserve 3914 // Register r0 holds precalculated cache entry address; preserve
3915 // it on the stack and pop it into register cache_entry after the 3915 // it on the stack and pop it into register cache_entry after the
3916 // call. 3916 // call.
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
4095 4095
4096 __ bind(&try_float); 4096 __ bind(&try_float);
4097 if (!overwrite_ == UNARY_OVERWRITE) { 4097 if (!overwrite_ == UNARY_OVERWRITE) {
4098 // Allocate a fresh heap number, but don't overwrite r0 until 4098 // Allocate a fresh heap number, but don't overwrite r0 until
4099 // we're sure we can do it without going through the slow case 4099 // we're sure we can do it without going through the slow case
4100 // that needs the value in r0. 4100 // that needs the value in r0.
4101 __ AllocateHeapNumber(r2, r3, r4, r6, &slow); 4101 __ AllocateHeapNumber(r2, r3, r4, r6, &slow);
4102 __ mov(r0, Operand(r2)); 4102 __ mov(r0, Operand(r2));
4103 } 4103 }
4104 4104
4105 if (CpuFeatures::IsSupported(VFP3)) { 4105 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
4106 // Convert the int32 in r1 to the heap number in r0. r2 is corrupted. 4106 // Convert the int32 in r1 to the heap number in r0. r2 is corrupted.
4107 CpuFeatures::Scope scope(VFP3); 4107 CpuFeatures::Scope scope(VFP3);
4108 __ vmov(s0, r1); 4108 __ vmov(s0, r1);
4109 __ vcvt_f64_s32(d0, s0); 4109 __ vcvt_f64_s32(d0, s0);
4110 __ sub(r2, r0, Operand(kHeapObjectTag)); 4110 __ sub(r2, r0, Operand(kHeapObjectTag));
4111 __ vstr(d0, r2, HeapNumber::kValueOffset); 4111 __ vstr(d0, r2, HeapNumber::kValueOffset);
4112 } else { 4112 } else {
4113 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not 4113 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not
4114 // have to set up a frame. 4114 // have to set up a frame.
4115 WriteInt32ToHeapNumberStub stub(r1, r0, r2); 4115 WriteInt32ToHeapNumberStub stub(r1, r0, r2);
(...skipping 20 matching lines...) Expand all
4136 break; 4136 break;
4137 default: 4137 default:
4138 UNREACHABLE(); 4138 UNREACHABLE();
4139 } 4139 }
4140 } 4140 }
4141 4141
4142 4142
4143 void MathPowStub::Generate(MacroAssembler* masm) { 4143 void MathPowStub::Generate(MacroAssembler* masm) {
4144 Label call_runtime; 4144 Label call_runtime;
4145 4145
4146 if (CpuFeatures::IsSupported(VFP3)) { 4146 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
4147 CpuFeatures::Scope scope(VFP3); 4147 CpuFeatures::Scope scope(VFP3);
4148 4148
4149 Label base_not_smi; 4149 Label base_not_smi;
4150 Label exponent_not_smi; 4150 Label exponent_not_smi;
4151 Label convert_exponent; 4151 Label convert_exponent;
4152 4152
4153 const Register base = r0; 4153 const Register base = r0;
4154 const Register exponent = r1; 4154 const Register exponent = r1;
4155 const Register heapnumbermap = r5; 4155 const Register heapnumbermap = r5;
4156 const Register heapnumber = r6; 4156 const Register heapnumber = r6;
(...skipping 2648 matching lines...) Expand 10 before | Expand all | Expand 10 after
6805 __ tst(r2, Operand(kSmiTagMask)); 6805 __ tst(r2, Operand(kSmiTagMask));
6806 __ b(eq, &generic_stub); 6806 __ b(eq, &generic_stub);
6807 6807
6808 __ CompareObjectType(r0, r2, r2, HEAP_NUMBER_TYPE); 6808 __ CompareObjectType(r0, r2, r2, HEAP_NUMBER_TYPE);
6809 __ b(ne, &miss); 6809 __ b(ne, &miss);
6810 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE); 6810 __ CompareObjectType(r1, r2, r2, HEAP_NUMBER_TYPE);
6811 __ b(ne, &miss); 6811 __ b(ne, &miss);
6812 6812
6813 // Inlining the double comparison and falling back to the general compare 6813 // Inlining the double comparison and falling back to the general compare
6814 // stub if NaN is involved or VFP3 is unsupported. 6814 // stub if NaN is involved or VFP3 is unsupported.
6815 if (CpuFeatures::IsSupported(VFP3)) { 6815 if (Isolate::Current()->cpu_features()->IsSupported(VFP3)) {
6816 CpuFeatures::Scope scope(VFP3); 6816 CpuFeatures::Scope scope(VFP3);
6817 6817
6818 // Load left and right operand 6818 // Load left and right operand
6819 __ sub(r2, r1, Operand(kHeapObjectTag)); 6819 __ sub(r2, r1, Operand(kHeapObjectTag));
6820 __ vldr(d0, r2, HeapNumber::kValueOffset); 6820 __ vldr(d0, r2, HeapNumber::kValueOffset);
6821 __ sub(r2, r0, Operand(kHeapObjectTag)); 6821 __ sub(r2, r0, Operand(kHeapObjectTag));
6822 __ vldr(d1, r2, HeapNumber::kValueOffset); 6822 __ vldr(d1, r2, HeapNumber::kValueOffset);
6823 6823
6824 // Compare operands 6824 // Compare operands
6825 __ VFPCompareAndSetFlags(d0, d1); 6825 __ VFPCompareAndSetFlags(d0, d1);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
6913 __ str(pc, MemOperand(sp, 0)); 6913 __ str(pc, MemOperand(sp, 0));
6914 __ Jump(target); // Call the C++ function. 6914 __ Jump(target); // Call the C++ function.
6915 } 6915 }
6916 6916
6917 6917
6918 #undef __ 6918 #undef __
6919 6919
6920 } } // namespace v8::internal 6920 } } // namespace v8::internal
6921 6921
6922 #endif // V8_TARGET_ARCH_ARM 6922 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698