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

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

Issue 12391055: Cleaned up CpuFeature scope handling. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixed nits Created 7 years, 9 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord)); 644 Operand(source_, LSR, 32 - HeapNumber::kMantissaBitsInTopWord));
645 __ Ret(); 645 __ Ret();
646 } 646 }
647 647
648 648
649 void FloatingPointHelper::LoadSmis(MacroAssembler* masm, 649 void FloatingPointHelper::LoadSmis(MacroAssembler* masm,
650 FloatingPointHelper::Destination destination, 650 FloatingPointHelper::Destination destination,
651 Register scratch1, 651 Register scratch1,
652 Register scratch2) { 652 Register scratch2) {
653 if (CpuFeatures::IsSupported(VFP2)) { 653 if (CpuFeatures::IsSupported(VFP2)) {
654 CpuFeatures::Scope scope(VFP2); 654 CpuFeatureScope scope(masm, VFP2);
655 __ mov(scratch1, Operand(r0, ASR, kSmiTagSize)); 655 __ mov(scratch1, Operand(r0, ASR, kSmiTagSize));
656 __ vmov(d7.high(), scratch1); 656 __ vmov(d7.high(), scratch1);
657 __ vcvt_f64_s32(d7, d7.high()); 657 __ vcvt_f64_s32(d7, d7.high());
658 __ mov(scratch1, Operand(r1, ASR, kSmiTagSize)); 658 __ mov(scratch1, Operand(r1, ASR, kSmiTagSize));
659 __ vmov(d6.high(), scratch1); 659 __ vmov(d6.high(), scratch1);
660 __ vcvt_f64_s32(d6, d6.high()); 660 __ vcvt_f64_s32(d6, d6.high());
661 if (destination == kCoreRegisters) { 661 if (destination == kCoreRegisters) {
662 __ vmov(r2, r3, d7); 662 __ vmov(r2, r3, d7);
663 __ vmov(r0, r1, d6); 663 __ vmov(r0, r1, d6);
664 } 664 }
(...skipping 30 matching lines...) Expand all
695 Label is_smi, done; 695 Label is_smi, done;
696 696
697 // Smi-check 697 // Smi-check
698 __ UntagAndJumpIfSmi(scratch1, object, &is_smi); 698 __ UntagAndJumpIfSmi(scratch1, object, &is_smi);
699 // Heap number check 699 // Heap number check
700 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); 700 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number);
701 701
702 // Handle loading a double from a heap number. 702 // Handle loading a double from a heap number.
703 if (CpuFeatures::IsSupported(VFP2) && 703 if (CpuFeatures::IsSupported(VFP2) &&
704 destination == kVFPRegisters) { 704 destination == kVFPRegisters) {
705 CpuFeatures::Scope scope(VFP2); 705 CpuFeatureScope scope(masm, VFP2);
706 // Load the double from tagged HeapNumber to double register. 706 // Load the double from tagged HeapNumber to double register.
707 __ sub(scratch1, object, Operand(kHeapObjectTag)); 707 __ sub(scratch1, object, Operand(kHeapObjectTag));
708 __ vldr(dst, scratch1, HeapNumber::kValueOffset); 708 __ vldr(dst, scratch1, HeapNumber::kValueOffset);
709 } else { 709 } else {
710 ASSERT(destination == kCoreRegisters); 710 ASSERT(destination == kCoreRegisters);
711 // Load the double from heap number to dst1 and dst2 in double format. 711 // Load the double from heap number to dst1 and dst2 in double format.
712 __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset)); 712 __ Ldrd(dst1, dst2, FieldMemOperand(object, HeapNumber::kValueOffset));
713 } 713 }
714 __ jmp(&done); 714 __ jmp(&done);
715 715
716 // Handle loading a double from a smi. 716 // Handle loading a double from a smi.
717 __ bind(&is_smi); 717 __ bind(&is_smi);
718 if (CpuFeatures::IsSupported(VFP2)) { 718 if (CpuFeatures::IsSupported(VFP2)) {
719 CpuFeatures::Scope scope(VFP2); 719 CpuFeatureScope scope(masm, VFP2);
720 // Convert smi to double using VFP instructions. 720 // Convert smi to double using VFP instructions.
721 __ vmov(dst.high(), scratch1); 721 __ vmov(dst.high(), scratch1);
722 __ vcvt_f64_s32(dst, dst.high()); 722 __ vcvt_f64_s32(dst, dst.high());
723 if (destination == kCoreRegisters) { 723 if (destination == kCoreRegisters) {
724 // Load the converted smi to dst1 and dst2 in double format. 724 // Load the converted smi to dst1 and dst2 in double format.
725 __ vmov(dst1, dst2, dst); 725 __ vmov(dst1, dst2, dst);
726 } 726 }
727 } else { 727 } else {
728 ASSERT(destination == kCoreRegisters); 728 ASSERT(destination == kCoreRegisters);
729 // Write smi to dst1 and dst2 double format. 729 // Write smi to dst1 and dst2 double format.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
785 Register dst_exponent, 785 Register dst_exponent,
786 Register scratch2, 786 Register scratch2,
787 SwVfpRegister single_scratch) { 787 SwVfpRegister single_scratch) {
788 ASSERT(!int_scratch.is(scratch2)); 788 ASSERT(!int_scratch.is(scratch2));
789 ASSERT(!int_scratch.is(dst_mantissa)); 789 ASSERT(!int_scratch.is(dst_mantissa));
790 ASSERT(!int_scratch.is(dst_exponent)); 790 ASSERT(!int_scratch.is(dst_exponent));
791 791
792 Label done; 792 Label done;
793 793
794 if (CpuFeatures::IsSupported(VFP2)) { 794 if (CpuFeatures::IsSupported(VFP2)) {
795 CpuFeatures::Scope scope(VFP2); 795 CpuFeatureScope scope(masm, VFP2);
796 __ vmov(single_scratch, int_scratch); 796 __ vmov(single_scratch, int_scratch);
797 __ vcvt_f64_s32(double_dst, single_scratch); 797 __ vcvt_f64_s32(double_dst, single_scratch);
798 if (destination == kCoreRegisters) { 798 if (destination == kCoreRegisters) {
799 __ vmov(dst_mantissa, dst_exponent, double_dst); 799 __ vmov(dst_mantissa, dst_exponent, double_dst);
800 } 800 }
801 } else { 801 } else {
802 Label fewer_than_20_useful_bits; 802 Label fewer_than_20_useful_bits;
803 // Expected output: 803 // Expected output:
804 // | dst_exponent | dst_mantissa | 804 // | dst_exponent | dst_mantissa |
805 // | s | exp | mantissa | 805 // | s | exp | mantissa |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
879 __ b(&done); 879 __ b(&done);
880 880
881 __ bind(&obj_is_not_smi); 881 __ bind(&obj_is_not_smi);
882 __ AssertRootValue(heap_number_map, 882 __ AssertRootValue(heap_number_map,
883 Heap::kHeapNumberMapRootIndex, 883 Heap::kHeapNumberMapRootIndex,
884 "HeapNumberMap register clobbered."); 884 "HeapNumberMap register clobbered.");
885 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); 885 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32);
886 886
887 // Load the number. 887 // Load the number.
888 if (CpuFeatures::IsSupported(VFP2)) { 888 if (CpuFeatures::IsSupported(VFP2)) {
889 CpuFeatures::Scope scope(VFP2); 889 CpuFeatureScope scope(masm, VFP2);
890 // Load the double value. 890 // Load the double value.
891 __ sub(scratch1, object, Operand(kHeapObjectTag)); 891 __ sub(scratch1, object, Operand(kHeapObjectTag));
892 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset); 892 __ vldr(double_dst, scratch1, HeapNumber::kValueOffset);
893 893
894 __ EmitVFPTruncate(kRoundToZero, 894 __ EmitVFPTruncate(kRoundToZero,
895 scratch1, 895 scratch1,
896 double_dst, 896 double_dst,
897 scratch2, 897 scratch2,
898 double_scratch, 898 double_scratch,
899 kCheckForInexactConversion); 899 kCheckForInexactConversion);
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 976
977 __ AssertRootValue(heap_number_map, 977 __ AssertRootValue(heap_number_map,
978 Heap::kHeapNumberMapRootIndex, 978 Heap::kHeapNumberMapRootIndex,
979 "HeapNumberMap register clobbered."); 979 "HeapNumberMap register clobbered.");
980 980
981 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined); 981 __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, &maybe_undefined);
982 982
983 // Object is a heap number. 983 // Object is a heap number.
984 // Convert the floating point value to a 32-bit integer. 984 // Convert the floating point value to a 32-bit integer.
985 if (CpuFeatures::IsSupported(VFP2)) { 985 if (CpuFeatures::IsSupported(VFP2)) {
986 CpuFeatures::Scope scope(VFP2); 986 CpuFeatureScope scope(masm, VFP2);
987 987
988 // Load the double value. 988 // Load the double value.
989 __ sub(scratch1, object, Operand(kHeapObjectTag)); 989 __ sub(scratch1, object, Operand(kHeapObjectTag));
990 __ vldr(double_scratch0, scratch1, HeapNumber::kValueOffset); 990 __ vldr(double_scratch0, scratch1, HeapNumber::kValueOffset);
991 991
992 __ EmitVFPTruncate(kRoundToZero, 992 __ EmitVFPTruncate(kRoundToZero,
993 dst, 993 dst,
994 double_scratch0, 994 double_scratch0,
995 scratch1, 995 scratch1,
996 double_scratch1, 996 double_scratch1,
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 1111
1112 // Assert that heap_number_result is callee-saved. 1112 // Assert that heap_number_result is callee-saved.
1113 // We currently always use r5 to pass it. 1113 // We currently always use r5 to pass it.
1114 ASSERT(heap_number_result.is(r5)); 1114 ASSERT(heap_number_result.is(r5));
1115 1115
1116 // Push the current return address before the C call. Return will be 1116 // Push the current return address before the C call. Return will be
1117 // through pop(pc) below. 1117 // through pop(pc) below.
1118 __ push(lr); 1118 __ push(lr);
1119 __ PrepareCallCFunction(0, 2, scratch); 1119 __ PrepareCallCFunction(0, 2, scratch);
1120 if (masm->use_eabi_hardfloat()) { 1120 if (masm->use_eabi_hardfloat()) {
1121 CpuFeatures::Scope scope(VFP2); 1121 CpuFeatureScope scope(masm, VFP2);
1122 __ vmov(d0, r0, r1); 1122 __ vmov(d0, r0, r1);
1123 __ vmov(d1, r2, r3); 1123 __ vmov(d1, r2, r3);
1124 } 1124 }
1125 { 1125 {
1126 AllowExternalCallThatCantCauseGC scope(masm); 1126 AllowExternalCallThatCantCauseGC scope(masm);
1127 __ CallCFunction( 1127 __ CallCFunction(
1128 ExternalReference::double_fp_operation(op, masm->isolate()), 0, 2); 1128 ExternalReference::double_fp_operation(op, masm->isolate()), 0, 2);
1129 } 1129 }
1130 // Store answer in the overwritable heap number. Double returned in 1130 // Store answer in the overwritable heap number. Double returned in
1131 // registers r0 and r1 or in d0. 1131 // registers r0 and r1 or in d0.
1132 if (masm->use_eabi_hardfloat()) { 1132 if (masm->use_eabi_hardfloat()) {
1133 CpuFeatures::Scope scope(VFP2); 1133 CpuFeatureScope scope(masm, VFP2);
1134 __ vstr(d0, 1134 __ vstr(d0,
1135 FieldMemOperand(heap_number_result, HeapNumber::kValueOffset)); 1135 FieldMemOperand(heap_number_result, HeapNumber::kValueOffset));
1136 } else { 1136 } else {
1137 __ Strd(r0, r1, FieldMemOperand(heap_number_result, 1137 __ Strd(r0, r1, FieldMemOperand(heap_number_result,
1138 HeapNumber::kValueOffset)); 1138 HeapNumber::kValueOffset));
1139 } 1139 }
1140 // Place heap_number_result in r0 and return to the pushed return address. 1140 // Place heap_number_result in r0 and return to the pushed return address.
1141 __ mov(r0, Operand(heap_number_result)); 1141 __ mov(r0, Operand(heap_number_result));
1142 __ pop(pc); 1142 __ pop(pc);
1143 } 1143 }
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1338 __ Ret(ne); 1338 __ Ret(ne);
1339 } else { 1339 } else {
1340 // Smi compared non-strictly with a non-Smi non-heap-number. Call 1340 // Smi compared non-strictly with a non-Smi non-heap-number. Call
1341 // the runtime. 1341 // the runtime.
1342 __ b(ne, slow); 1342 __ b(ne, slow);
1343 } 1343 }
1344 1344
1345 // Lhs is a smi, rhs is a number. 1345 // Lhs is a smi, rhs is a number.
1346 if (CpuFeatures::IsSupported(VFP2)) { 1346 if (CpuFeatures::IsSupported(VFP2)) {
1347 // Convert lhs to a double in d7. 1347 // Convert lhs to a double in d7.
1348 CpuFeatures::Scope scope(VFP2); 1348 CpuFeatureScope scope(masm, VFP2);
1349 __ SmiToDoubleVFPRegister(lhs, d7, r7, s15); 1349 __ SmiToDoubleVFPRegister(lhs, d7, r7, s15);
1350 // Load the double from rhs, tagged HeapNumber r0, to d6. 1350 // Load the double from rhs, tagged HeapNumber r0, to d6.
1351 __ sub(r7, rhs, Operand(kHeapObjectTag)); 1351 __ sub(r7, rhs, Operand(kHeapObjectTag));
1352 __ vldr(d6, r7, HeapNumber::kValueOffset); 1352 __ vldr(d6, r7, HeapNumber::kValueOffset);
1353 } else { 1353 } else {
1354 __ push(lr); 1354 __ push(lr);
1355 // Convert lhs to a double in r2, r3. 1355 // Convert lhs to a double in r2, r3.
1356 __ mov(r7, Operand(lhs)); 1356 __ mov(r7, Operand(lhs));
1357 ConvertToDoubleStub stub1(r3, r2, r7, r6); 1357 ConvertToDoubleStub stub1(r3, r2, r7, r6);
1358 __ Call(stub1.GetCode(masm->isolate())); 1358 __ Call(stub1.GetCode(masm->isolate()));
(...skipping 18 matching lines...) Expand all
1377 } 1377 }
1378 __ Ret(ne); 1378 __ Ret(ne);
1379 } else { 1379 } else {
1380 // Smi compared non-strictly with a non-smi non-heap-number. Call 1380 // Smi compared non-strictly with a non-smi non-heap-number. Call
1381 // the runtime. 1381 // the runtime.
1382 __ b(ne, slow); 1382 __ b(ne, slow);
1383 } 1383 }
1384 1384
1385 // Rhs is a smi, lhs is a heap number. 1385 // Rhs is a smi, lhs is a heap number.
1386 if (CpuFeatures::IsSupported(VFP2)) { 1386 if (CpuFeatures::IsSupported(VFP2)) {
1387 CpuFeatures::Scope scope(VFP2); 1387 CpuFeatureScope scope(masm, VFP2);
1388 // Load the double from lhs, tagged HeapNumber r1, to d7. 1388 // Load the double from lhs, tagged HeapNumber r1, to d7.
1389 __ sub(r7, lhs, Operand(kHeapObjectTag)); 1389 __ sub(r7, lhs, Operand(kHeapObjectTag));
1390 __ vldr(d7, r7, HeapNumber::kValueOffset); 1390 __ vldr(d7, r7, HeapNumber::kValueOffset);
1391 // Convert rhs to a double in d6 . 1391 // Convert rhs to a double in d6 .
1392 __ SmiToDoubleVFPRegister(rhs, d6, r7, s13); 1392 __ SmiToDoubleVFPRegister(rhs, d6, r7, s13);
1393 } else { 1393 } else {
1394 __ push(lr); 1394 __ push(lr);
1395 // Load lhs to a double in r2, r3. 1395 // Load lhs to a double in r2, r3.
1396 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset)); 1396 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset));
1397 // Convert rhs to a double in r0, r1. 1397 // Convert rhs to a double in r0, r1.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 // Now they are equal if and only if the lhs exponent is zero in its 1489 // Now they are equal if and only if the lhs exponent is zero in its
1490 // low 31 bits. 1490 // low 31 bits.
1491 __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize)); 1491 __ mov(r0, Operand(rhs_exponent, LSL, kSmiTagSize));
1492 __ Ret(); 1492 __ Ret();
1493 } else { 1493 } else {
1494 // Call a native function to do a comparison between two non-NaNs. 1494 // Call a native function to do a comparison between two non-NaNs.
1495 // Call C routine that may not cause GC or other trouble. 1495 // Call C routine that may not cause GC or other trouble.
1496 __ push(lr); 1496 __ push(lr);
1497 __ PrepareCallCFunction(0, 2, r5); 1497 __ PrepareCallCFunction(0, 2, r5);
1498 if (masm->use_eabi_hardfloat()) { 1498 if (masm->use_eabi_hardfloat()) {
1499 CpuFeatures::Scope scope(VFP2); 1499 CpuFeatureScope scope(masm, VFP2);
1500 __ vmov(d0, r0, r1); 1500 __ vmov(d0, r0, r1);
1501 __ vmov(d1, r2, r3); 1501 __ vmov(d1, r2, r3);
1502 } 1502 }
1503 1503
1504 AllowExternalCallThatCantCauseGC scope(masm); 1504 AllowExternalCallThatCantCauseGC scope(masm);
1505 __ CallCFunction(ExternalReference::compare_doubles(masm->isolate()), 1505 __ CallCFunction(ExternalReference::compare_doubles(masm->isolate()),
1506 0, 2); 1506 0, 2);
1507 __ pop(pc); // Return. 1507 __ pop(pc); // Return.
1508 } 1508 }
1509 } 1509 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1566 1566
1567 __ CompareObjectType(rhs, r3, r2, HEAP_NUMBER_TYPE); 1567 __ CompareObjectType(rhs, r3, r2, HEAP_NUMBER_TYPE);
1568 __ b(ne, not_heap_numbers); 1568 __ b(ne, not_heap_numbers);
1569 __ ldr(r2, FieldMemOperand(lhs, HeapObject::kMapOffset)); 1569 __ ldr(r2, FieldMemOperand(lhs, HeapObject::kMapOffset));
1570 __ cmp(r2, r3); 1570 __ cmp(r2, r3);
1571 __ b(ne, slow); // First was a heap number, second wasn't. Go slow case. 1571 __ b(ne, slow); // First was a heap number, second wasn't. Go slow case.
1572 1572
1573 // Both are heap numbers. Load them up then jump to the code we have 1573 // Both are heap numbers. Load them up then jump to the code we have
1574 // for that. 1574 // for that.
1575 if (CpuFeatures::IsSupported(VFP2)) { 1575 if (CpuFeatures::IsSupported(VFP2)) {
1576 CpuFeatures::Scope scope(VFP2); 1576 CpuFeatureScope scope(masm, VFP2);
1577 __ sub(r7, rhs, Operand(kHeapObjectTag)); 1577 __ sub(r7, rhs, Operand(kHeapObjectTag));
1578 __ vldr(d6, r7, HeapNumber::kValueOffset); 1578 __ vldr(d6, r7, HeapNumber::kValueOffset);
1579 __ sub(r7, lhs, Operand(kHeapObjectTag)); 1579 __ sub(r7, lhs, Operand(kHeapObjectTag));
1580 __ vldr(d7, r7, HeapNumber::kValueOffset); 1580 __ vldr(d7, r7, HeapNumber::kValueOffset);
1581 } else { 1581 } else {
1582 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset)); 1582 __ Ldrd(r2, r3, FieldMemOperand(lhs, HeapNumber::kValueOffset));
1583 __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset)); 1583 __ Ldrd(r0, r1, FieldMemOperand(rhs, HeapNumber::kValueOffset));
1584 } 1584 }
1585 __ jmp(both_loaded_as_doubles); 1585 __ jmp(both_loaded_as_doubles);
1586 } 1586 }
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 // Calculate the entry in the number string cache. The hash value in the 1656 // Calculate the entry in the number string cache. The hash value in the
1657 // number string cache for smis is just the smi value, and the hash for 1657 // number string cache for smis is just the smi value, and the hash for
1658 // doubles is the xor of the upper and lower words. See 1658 // doubles is the xor of the upper and lower words. See
1659 // Heap::GetNumberStringCache. 1659 // Heap::GetNumberStringCache.
1660 Isolate* isolate = masm->isolate(); 1660 Isolate* isolate = masm->isolate();
1661 Label is_smi; 1661 Label is_smi;
1662 Label load_result_from_cache; 1662 Label load_result_from_cache;
1663 if (!object_is_smi) { 1663 if (!object_is_smi) {
1664 __ JumpIfSmi(object, &is_smi); 1664 __ JumpIfSmi(object, &is_smi);
1665 if (CpuFeatures::IsSupported(VFP2)) { 1665 if (CpuFeatures::IsSupported(VFP2)) {
1666 CpuFeatures::Scope scope(VFP2); 1666 CpuFeatureScope scope(masm, VFP2);
1667 __ CheckMap(object, 1667 __ CheckMap(object,
1668 scratch1, 1668 scratch1,
1669 Heap::kHeapNumberMapRootIndex, 1669 Heap::kHeapNumberMapRootIndex,
1670 not_found, 1670 not_found,
1671 DONT_DO_SMI_CHECK); 1671 DONT_DO_SMI_CHECK);
1672 1672
1673 STATIC_ASSERT(8 == kDoubleSize); 1673 STATIC_ASSERT(8 == kDoubleSize);
1674 __ add(scratch1, 1674 __ add(scratch1,
1675 object, 1675 object,
1676 Operand(HeapNumber::kValueOffset - kHeapObjectTag)); 1676 Operand(HeapNumber::kValueOffset - kHeapObjectTag));
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1807 // been loaded into d7 and d6. Otherwise, the double values have been loaded 1807 // been loaded into d7 and d6. Otherwise, the double values have been loaded
1808 // into r0, r1, r2, and r3. 1808 // into r0, r1, r2, and r3.
1809 EmitSmiNonsmiComparison(masm, lhs, rhs, &lhs_not_nan, &slow, strict()); 1809 EmitSmiNonsmiComparison(masm, lhs, rhs, &lhs_not_nan, &slow, strict());
1810 1810
1811 __ bind(&both_loaded_as_doubles); 1811 __ bind(&both_loaded_as_doubles);
1812 // The arguments have been converted to doubles and stored in d6 and d7, if 1812 // The arguments have been converted to doubles and stored in d6 and d7, if
1813 // VFP3 is supported, or in r0, r1, r2, and r3. 1813 // VFP3 is supported, or in r0, r1, r2, and r3.
1814 Isolate* isolate = masm->isolate(); 1814 Isolate* isolate = masm->isolate();
1815 if (CpuFeatures::IsSupported(VFP2)) { 1815 if (CpuFeatures::IsSupported(VFP2)) {
1816 __ bind(&lhs_not_nan); 1816 __ bind(&lhs_not_nan);
1817 CpuFeatures::Scope scope(VFP2); 1817 CpuFeatureScope scope(masm, VFP2);
1818 Label no_nan; 1818 Label no_nan;
1819 // ARMv7 VFP3 instructions to implement double precision comparison. 1819 // ARMv7 VFP3 instructions to implement double precision comparison.
1820 __ VFPCompareAndSetFlags(d7, d6); 1820 __ VFPCompareAndSetFlags(d7, d6);
1821 Label nan; 1821 Label nan;
1822 __ b(vs, &nan); 1822 __ b(vs, &nan);
1823 __ mov(r0, Operand(EQUAL), LeaveCC, eq); 1823 __ mov(r0, Operand(EQUAL), LeaveCC, eq);
1824 __ mov(r0, Operand(LESS), LeaveCC, lt); 1824 __ mov(r0, Operand(LESS), LeaveCC, lt);
1825 __ mov(r0, Operand(GREATER), LeaveCC, gt); 1825 __ mov(r0, Operand(GREATER), LeaveCC, gt);
1826 __ Ret(); 1826 __ Ret();
1827 1827
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1987 __ Ret(lt); // the string length is OK as the return value 1987 __ Ret(lt); // the string length is OK as the return value
1988 } 1988 }
1989 1989
1990 if (types_.Contains(HEAP_NUMBER)) { 1990 if (types_.Contains(HEAP_NUMBER)) {
1991 // Heap number -> false iff +0, -0, or NaN. 1991 // Heap number -> false iff +0, -0, or NaN.
1992 Label not_heap_number; 1992 Label not_heap_number;
1993 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex); 1993 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1994 __ b(ne, &not_heap_number); 1994 __ b(ne, &not_heap_number);
1995 1995
1996 if (CpuFeatures::IsSupported(VFP2)) { 1996 if (CpuFeatures::IsSupported(VFP2)) {
1997 CpuFeatures::Scope scope(VFP2); 1997 CpuFeatureScope scope(masm, VFP2);
1998 1998
1999 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset)); 1999 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
2000 __ VFPCompareAndSetFlags(d1, 0.0); 2000 __ VFPCompareAndSetFlags(d1, 0.0);
2001 // "tos_" is a register, and contains a non zero value by default. 2001 // "tos_" is a register, and contains a non zero value by default.
2002 // Hence we only need to overwrite "tos_" with zero to return false for 2002 // Hence we only need to overwrite "tos_" with zero to return false for
2003 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. 2003 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
2004 __ mov(tos_, Operand::Zero(), LeaveCC, eq); // for FP_ZERO 2004 __ mov(tos_, Operand::Zero(), LeaveCC, eq); // for FP_ZERO
2005 __ mov(tos_, Operand::Zero(), LeaveCC, vs); // for FP_NAN 2005 __ mov(tos_, Operand::Zero(), LeaveCC, vs); // for FP_NAN
2006 } else { 2006 } else {
2007 Label done, not_nan, not_zero; 2007 Label done, not_nan, not_zero;
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
2087 2087
2088 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 2088 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
2089 // We don't allow a GC during a store buffer overflow so there is no need to 2089 // We don't allow a GC during a store buffer overflow so there is no need to
2090 // store the registers in any particular way, but we do have to store and 2090 // store the registers in any particular way, but we do have to store and
2091 // restore them. 2091 // restore them.
2092 __ stm(db_w, sp, kCallerSaved | lr.bit()); 2092 __ stm(db_w, sp, kCallerSaved | lr.bit());
2093 2093
2094 const Register scratch = r1; 2094 const Register scratch = r1;
2095 2095
2096 if (save_doubles_ == kSaveFPRegs) { 2096 if (save_doubles_ == kSaveFPRegs) {
2097 CpuFeatures::Scope scope(VFP2); 2097 CpuFeatureScope scope(masm, VFP2);
2098 // Check CPU flags for number of registers, setting the Z condition flag. 2098 // Check CPU flags for number of registers, setting the Z condition flag.
2099 __ CheckFor32DRegs(scratch); 2099 __ CheckFor32DRegs(scratch);
2100 2100
2101 __ sub(sp, sp, Operand(kDoubleSize * DwVfpRegister::kMaxNumRegisters)); 2101 __ sub(sp, sp, Operand(kDoubleSize * DwVfpRegister::kMaxNumRegisters));
2102 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; i++) { 2102 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; i++) {
2103 DwVfpRegister reg = DwVfpRegister::from_code(i); 2103 DwVfpRegister reg = DwVfpRegister::from_code(i);
2104 __ vstr(reg, MemOperand(sp, i * kDoubleSize), i < 16 ? al : ne); 2104 __ vstr(reg, MemOperand(sp, i * kDoubleSize), i < 16 ? al : ne);
2105 } 2105 }
2106 } 2106 }
2107 const int argument_count = 1; 2107 const int argument_count = 1;
2108 const int fp_argument_count = 0; 2108 const int fp_argument_count = 0;
2109 2109
2110 AllowExternalCallThatCantCauseGC scope(masm); 2110 AllowExternalCallThatCantCauseGC scope(masm);
2111 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch); 2111 __ PrepareCallCFunction(argument_count, fp_argument_count, scratch);
2112 __ mov(r0, Operand(ExternalReference::isolate_address())); 2112 __ mov(r0, Operand(ExternalReference::isolate_address()));
2113 __ CallCFunction( 2113 __ CallCFunction(
2114 ExternalReference::store_buffer_overflow_function(masm->isolate()), 2114 ExternalReference::store_buffer_overflow_function(masm->isolate()),
2115 argument_count); 2115 argument_count);
2116 if (save_doubles_ == kSaveFPRegs) { 2116 if (save_doubles_ == kSaveFPRegs) {
2117 CpuFeatures::Scope scope(VFP2); 2117 CpuFeatureScope scope(masm, VFP2);
2118 2118
2119 // Check CPU flags for number of registers, setting the Z condition flag. 2119 // Check CPU flags for number of registers, setting the Z condition flag.
2120 __ CheckFor32DRegs(scratch); 2120 __ CheckFor32DRegs(scratch);
2121 2121
2122 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; i++) { 2122 for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; i++) {
2123 DwVfpRegister reg = DwVfpRegister::from_code(i); 2123 DwVfpRegister reg = DwVfpRegister::from_code(i);
2124 __ vldr(reg, MemOperand(sp, i * kDoubleSize), i < 16 ? al : ne); 2124 __ vldr(reg, MemOperand(sp, i * kDoubleSize), i < 16 ? al : ne);
2125 } 2125 }
2126 __ add(sp, sp, Operand(kDoubleSize * DwVfpRegister::kMaxNumRegisters)); 2126 __ add(sp, sp, Operand(kDoubleSize * DwVfpRegister::kMaxNumRegisters));
2127 } 2127 }
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
2343 // converted once again. 2343 // converted once again.
2344 __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible); 2344 __ ConvertToInt32(r0, r1, r3, r4, d0, &impossible);
2345 __ mvn(r1, Operand(r1)); 2345 __ mvn(r1, Operand(r1));
2346 2346
2347 __ bind(&heapnumber_allocated); 2347 __ bind(&heapnumber_allocated);
2348 __ mov(r0, r2); // Move newly allocated heap number to r0. 2348 __ mov(r0, r2); // Move newly allocated heap number to r0.
2349 } 2349 }
2350 2350
2351 if (CpuFeatures::IsSupported(VFP2)) { 2351 if (CpuFeatures::IsSupported(VFP2)) {
2352 // Convert the int32 in r1 to the heap number in r0. r2 is corrupted. 2352 // Convert the int32 in r1 to the heap number in r0. r2 is corrupted.
2353 CpuFeatures::Scope scope(VFP2); 2353 CpuFeatureScope scope(masm, VFP2);
2354 __ vmov(s0, r1); 2354 __ vmov(s0, r1);
2355 __ vcvt_f64_s32(d0, s0); 2355 __ vcvt_f64_s32(d0, s0);
2356 __ sub(r2, r0, Operand(kHeapObjectTag)); 2356 __ sub(r2, r0, Operand(kHeapObjectTag));
2357 __ vstr(d0, r2, HeapNumber::kValueOffset); 2357 __ vstr(d0, r2, HeapNumber::kValueOffset);
2358 __ Ret(); 2358 __ Ret();
2359 } else { 2359 } else {
2360 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not 2360 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not
2361 // have to set up a frame. 2361 // have to set up a frame.
2362 WriteInt32ToHeapNumberStub stub(r1, r0, r2); 2362 WriteInt32ToHeapNumberStub stub(r1, r0, r2);
2363 __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET); 2363 __ Jump(stub.GetCode(masm->isolate()), RelocInfo::CODE_TARGET);
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
2738 masm, destination, left, d6, r0, r1, heap_number_map, 2738 masm, destination, left, d6, r0, r1, heap_number_map,
2739 scratch1, scratch2, fail); 2739 scratch1, scratch2, fail);
2740 } 2740 }
2741 } 2741 }
2742 2742
2743 // Calculate the result. 2743 // Calculate the result.
2744 if (destination == FloatingPointHelper::kVFPRegisters) { 2744 if (destination == FloatingPointHelper::kVFPRegisters) {
2745 // Using VFP registers: 2745 // Using VFP registers:
2746 // d6: Left value 2746 // d6: Left value
2747 // d7: Right value 2747 // d7: Right value
2748 CpuFeatures::Scope scope(VFP2); 2748 CpuFeatureScope scope(masm, VFP2);
2749 switch (op) { 2749 switch (op) {
2750 case Token::ADD: 2750 case Token::ADD:
2751 __ vadd(d5, d6, d7); 2751 __ vadd(d5, d6, d7);
2752 break; 2752 break;
2753 case Token::SUB: 2753 case Token::SUB:
2754 __ vsub(d5, d6, d7); 2754 __ vsub(d5, d6, d7);
2755 break; 2755 break;
2756 case Token::MUL: 2756 case Token::MUL:
2757 __ vmul(d5, d6, d7); 2757 __ vmul(d5, d6, d7);
2758 break; 2758 break;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
2870 // r2: Answer as signed int32. 2870 // r2: Answer as signed int32.
2871 // r5: Heap number to write answer into. 2871 // r5: Heap number to write answer into.
2872 2872
2873 // Nothing can go wrong now, so move the heap number to r0, which is the 2873 // Nothing can go wrong now, so move the heap number to r0, which is the
2874 // result. 2874 // result.
2875 __ mov(r0, Operand(r5)); 2875 __ mov(r0, Operand(r5));
2876 2876
2877 if (CpuFeatures::IsSupported(VFP2)) { 2877 if (CpuFeatures::IsSupported(VFP2)) {
2878 // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. As 2878 // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. As
2879 // mentioned above SHR needs to always produce a positive result. 2879 // mentioned above SHR needs to always produce a positive result.
2880 CpuFeatures::Scope scope(VFP2); 2880 CpuFeatureScope scope(masm, VFP2);
2881 __ vmov(s0, r2); 2881 __ vmov(s0, r2);
2882 if (op == Token::SHR) { 2882 if (op == Token::SHR) {
2883 __ vcvt_f64_u32(d0, s0); 2883 __ vcvt_f64_u32(d0, s0);
2884 } else { 2884 } else {
2885 __ vcvt_f64_s32(d0, s0); 2885 __ vcvt_f64_s32(d0, s0);
2886 } 2886 }
2887 __ sub(r3, r0, Operand(kHeapObjectTag)); 2887 __ sub(r3, r0, Operand(kHeapObjectTag));
2888 __ vstr(d0, r3, HeapNumber::kValueOffset); 2888 __ vstr(d0, r3, HeapNumber::kValueOffset);
2889 __ Ret(); 2889 __ Ret();
2890 } else { 2890 } else {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3062 d8, 3062 d8,
3063 r4, 3063 r4,
3064 r5, 3064 r5,
3065 heap_number_map, 3065 heap_number_map,
3066 scratch1, 3066 scratch1,
3067 scratch2, 3067 scratch2,
3068 s0, 3068 s0,
3069 &transition); 3069 &transition);
3070 3070
3071 if (destination == FloatingPointHelper::kVFPRegisters) { 3071 if (destination == FloatingPointHelper::kVFPRegisters) {
3072 CpuFeatures::Scope scope(VFP2); 3072 CpuFeatureScope scope(masm, VFP2);
3073 Label return_heap_number; 3073 Label return_heap_number;
3074 switch (op_) { 3074 switch (op_) {
3075 case Token::ADD: 3075 case Token::ADD:
3076 __ vadd(d5, d6, d7); 3076 __ vadd(d5, d6, d7);
3077 break; 3077 break;
3078 case Token::SUB: 3078 case Token::SUB:
3079 __ vsub(d5, d6, d7); 3079 __ vsub(d5, d6, d7);
3080 break; 3080 break;
3081 case Token::MUL: 3081 case Token::MUL:
3082 __ vmul(d5, d6, d7); 3082 __ vmul(d5, d6, d7);
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
3271 heap_number_result = r5; 3271 heap_number_result = r5;
3272 BinaryOpStub_GenerateHeapResultAllocation(masm, 3272 BinaryOpStub_GenerateHeapResultAllocation(masm,
3273 heap_number_result, 3273 heap_number_result,
3274 heap_number_map, 3274 heap_number_map,
3275 scratch1, 3275 scratch1,
3276 scratch2, 3276 scratch2,
3277 &call_runtime, 3277 &call_runtime,
3278 mode_); 3278 mode_);
3279 3279
3280 if (CpuFeatures::IsSupported(VFP2)) { 3280 if (CpuFeatures::IsSupported(VFP2)) {
3281 CpuFeatures::Scope scope(VFP2); 3281 CpuFeatureScope scope(masm, VFP2);
3282 if (op_ != Token::SHR) { 3282 if (op_ != Token::SHR) {
3283 // Convert the result to a floating point value. 3283 // Convert the result to a floating point value.
3284 __ vmov(double_scratch.low(), r2); 3284 __ vmov(double_scratch.low(), r2);
3285 __ vcvt_f64_s32(double_scratch, double_scratch.low()); 3285 __ vcvt_f64_s32(double_scratch, double_scratch.low());
3286 } else { 3286 } else {
3287 // The result must be interpreted as an unsigned 32-bit integer. 3287 // The result must be interpreted as an unsigned 32-bit integer.
3288 __ vmov(double_scratch.low(), r2); 3288 __ vmov(double_scratch.low(), r2);
3289 __ vcvt_f64_u32(double_scratch, double_scratch.low()); 3289 __ vcvt_f64_u32(double_scratch, double_scratch.low());
3290 } 3290 }
3291 3291
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
3474 Label input_not_smi; 3474 Label input_not_smi;
3475 Label loaded; 3475 Label loaded;
3476 Label calculate; 3476 Label calculate;
3477 Label invalid_cache; 3477 Label invalid_cache;
3478 const Register scratch0 = r9; 3478 const Register scratch0 = r9;
3479 const Register scratch1 = r7; 3479 const Register scratch1 = r7;
3480 const Register cache_entry = r0; 3480 const Register cache_entry = r0;
3481 const bool tagged = (argument_type_ == TAGGED); 3481 const bool tagged = (argument_type_ == TAGGED);
3482 3482
3483 if (CpuFeatures::IsSupported(VFP2)) { 3483 if (CpuFeatures::IsSupported(VFP2)) {
3484 CpuFeatures::Scope scope(VFP2); 3484 CpuFeatureScope scope(masm, VFP2);
3485 if (tagged) { 3485 if (tagged) {
3486 // Argument is a number and is on stack and in r0. 3486 // Argument is a number and is on stack and in r0.
3487 // Load argument and check if it is a smi. 3487 // Load argument and check if it is a smi.
3488 __ JumpIfNotSmi(r0, &input_not_smi); 3488 __ JumpIfNotSmi(r0, &input_not_smi);
3489 3489
3490 // Input is a smi. Convert to double and load the low and high words 3490 // Input is a smi. Convert to double and load the low and high words
3491 // of the double into r2, r3. 3491 // of the double into r2, r3.
3492 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); 3492 __ IntegerToDoubleConversionWithVFP3(r0, r3, r2);
3493 __ b(&loaded); 3493 __ b(&loaded);
3494 3494
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
3576 Counters* counters = masm->isolate()->counters(); 3576 Counters* counters = masm->isolate()->counters();
3577 __ IncrementCounter( 3577 __ IncrementCounter(
3578 counters->transcendental_cache_miss(), 1, scratch0, scratch1); 3578 counters->transcendental_cache_miss(), 1, scratch0, scratch1);
3579 if (tagged) { 3579 if (tagged) {
3580 __ bind(&invalid_cache); 3580 __ bind(&invalid_cache);
3581 ExternalReference runtime_function = 3581 ExternalReference runtime_function =
3582 ExternalReference(RuntimeFunction(), masm->isolate()); 3582 ExternalReference(RuntimeFunction(), masm->isolate());
3583 __ TailCallExternalReference(runtime_function, 1, 1); 3583 __ TailCallExternalReference(runtime_function, 1, 1);
3584 } else { 3584 } else {
3585 ASSERT(CpuFeatures::IsSupported(VFP2)); 3585 ASSERT(CpuFeatures::IsSupported(VFP2));
3586 CpuFeatures::Scope scope(VFP2); 3586 CpuFeatureScope scope(masm, VFP2);
3587 3587
3588 Label no_update; 3588 Label no_update;
3589 Label skip_cache; 3589 Label skip_cache;
3590 3590
3591 // Call C function to calculate the result and update the cache. 3591 // Call C function to calculate the result and update the cache.
3592 // r0: precalculated cache entry address. 3592 // r0: precalculated cache entry address.
3593 // r2 and r3: parts of the double value. 3593 // r2 and r3: parts of the double value.
3594 // Store r0, r2 and r3 on stack for later before calling C function. 3594 // Store r0, r2 and r3 on stack for later before calling C function.
3595 __ Push(r3, r2, cache_entry); 3595 __ Push(r3, r2, cache_entry);
3596 GenerateCallCFunction(masm, scratch0); 3596 GenerateCallCFunction(masm, scratch0);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3637 __ push(scratch0); 3637 __ push(scratch0);
3638 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace); 3638 __ CallRuntimeSaveDoubles(Runtime::kAllocateInNewSpace);
3639 } 3639 }
3640 __ Ret(); 3640 __ Ret();
3641 } 3641 }
3642 } 3642 }
3643 3643
3644 3644
3645 void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm, 3645 void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
3646 Register scratch) { 3646 Register scratch) {
3647 ASSERT(CpuFeatures::IsEnabled(VFP2)); 3647 ASSERT(masm->IsEnabled(VFP2));
3648 Isolate* isolate = masm->isolate(); 3648 Isolate* isolate = masm->isolate();
3649 3649
3650 __ push(lr); 3650 __ push(lr);
3651 __ PrepareCallCFunction(0, 1, scratch); 3651 __ PrepareCallCFunction(0, 1, scratch);
3652 if (masm->use_eabi_hardfloat()) { 3652 if (masm->use_eabi_hardfloat()) {
3653 __ vmov(d0, d2); 3653 __ vmov(d0, d2);
3654 } else { 3654 } else {
3655 __ vmov(r0, r1, d2); 3655 __ vmov(r0, r1, d2);
3656 } 3656 }
3657 AllowExternalCallThatCantCauseGC scope(masm); 3657 AllowExternalCallThatCantCauseGC scope(masm);
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
3698 __ TailCallRuntime(Runtime::kStackGuard, 0, 1); 3698 __ TailCallRuntime(Runtime::kStackGuard, 0, 1);
3699 } 3699 }
3700 3700
3701 3701
3702 void InterruptStub::Generate(MacroAssembler* masm) { 3702 void InterruptStub::Generate(MacroAssembler* masm) {
3703 __ TailCallRuntime(Runtime::kInterrupt, 0, 1); 3703 __ TailCallRuntime(Runtime::kInterrupt, 0, 1);
3704 } 3704 }
3705 3705
3706 3706
3707 void MathPowStub::Generate(MacroAssembler* masm) { 3707 void MathPowStub::Generate(MacroAssembler* masm) {
3708 CpuFeatures::Scope vfp2_scope(VFP2); 3708 CpuFeatureScope vfp2_scope(masm, VFP2);
3709 const Register base = r1; 3709 const Register base = r1;
3710 const Register exponent = r2; 3710 const Register exponent = r2;
3711 const Register heapnumbermap = r5; 3711 const Register heapnumbermap = r5;
3712 const Register heapnumber = r0; 3712 const Register heapnumber = r0;
3713 const DwVfpRegister double_base = d1; 3713 const DwVfpRegister double_base = d1;
3714 const DwVfpRegister double_exponent = d2; 3714 const DwVfpRegister double_exponent = d2;
3715 const DwVfpRegister double_result = d3; 3715 const DwVfpRegister double_result = d3;
3716 const DwVfpRegister double_scratch = d0; 3716 const DwVfpRegister double_scratch = d0;
3717 const SwVfpRegister single_scratch = s0; 3717 const SwVfpRegister single_scratch = s0;
3718 const Register scratch = r9; 3718 const Register scratch = r9;
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
3924 3924
3925 void CodeStub::GenerateFPStubs(Isolate* isolate) { 3925 void CodeStub::GenerateFPStubs(Isolate* isolate) {
3926 SaveFPRegsMode mode = CpuFeatures::IsSupported(VFP2) 3926 SaveFPRegsMode mode = CpuFeatures::IsSupported(VFP2)
3927 ? kSaveFPRegs 3927 ? kSaveFPRegs
3928 : kDontSaveFPRegs; 3928 : kDontSaveFPRegs;
3929 CEntryStub save_doubles(1, mode); 3929 CEntryStub save_doubles(1, mode);
3930 StoreBufferOverflowStub stub(mode); 3930 StoreBufferOverflowStub stub(mode);
3931 // These stubs might already be in the snapshot, detect that and don't 3931 // These stubs might already be in the snapshot, detect that and don't
3932 // regenerate, which would lead to code stub initialization state being messed 3932 // regenerate, which would lead to code stub initialization state being messed
3933 // up. 3933 // up.
3934 Code* save_doubles_code = NULL; 3934 Code* save_doubles_code;
3935 Code* store_buffer_overflow_code = NULL; 3935 if (!save_doubles.FindCodeInCache(&save_doubles_code, isolate)) {
3936 if (!save_doubles.FindCodeInCache(&save_doubles_code, ISOLATE)) { 3936 save_doubles_code = *save_doubles.GetCode(isolate);
3937 if (CpuFeatures::IsSupported(VFP2)) {
3938 CpuFeatures::Scope scope2(VFP2);
3939 save_doubles_code = *save_doubles.GetCode(isolate);
3940 store_buffer_overflow_code = *stub.GetCode(isolate);
3941 } else {
3942 save_doubles_code = *save_doubles.GetCode(isolate);
3943 store_buffer_overflow_code = *stub.GetCode(isolate);
3944 }
3945 save_doubles_code->set_is_pregenerated(true); 3937 save_doubles_code->set_is_pregenerated(true);
3938
3939 Code* store_buffer_overflow_code = *stub.GetCode(isolate);
3946 store_buffer_overflow_code->set_is_pregenerated(true); 3940 store_buffer_overflow_code->set_is_pregenerated(true);
3947 } 3941 }
3948 ISOLATE->set_fp_stubs_generated(true); 3942 isolate->set_fp_stubs_generated(true);
3949 } 3943 }
3950 3944
3951 3945
3952 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) { 3946 void CEntryStub::GenerateAheadOfTime(Isolate* isolate) {
3953 CEntryStub stub(1, kDontSaveFPRegs); 3947 CEntryStub stub(1, kDontSaveFPRegs);
3954 Handle<Code> code = stub.GetCode(isolate); 3948 Handle<Code> code = stub.GetCode(isolate);
3955 code->set_is_pregenerated(true); 3949 code->set_is_pregenerated(true);
3956 } 3950 }
3957 3951
3958 3952
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
4185 // [sp+0]: argv 4179 // [sp+0]: argv
4186 4180
4187 Label invoke, handler_entry, exit; 4181 Label invoke, handler_entry, exit;
4188 4182
4189 // Called from C, so do not pop argc and args on exit (preserve sp) 4183 // Called from C, so do not pop argc and args on exit (preserve sp)
4190 // No need to save register-passed args 4184 // No need to save register-passed args
4191 // Save callee-saved registers (incl. cp and fp), sp, and lr 4185 // Save callee-saved registers (incl. cp and fp), sp, and lr
4192 __ stm(db_w, sp, kCalleeSaved | lr.bit()); 4186 __ stm(db_w, sp, kCalleeSaved | lr.bit());
4193 4187
4194 if (CpuFeatures::IsSupported(VFP2)) { 4188 if (CpuFeatures::IsSupported(VFP2)) {
4195 CpuFeatures::Scope scope(VFP2); 4189 CpuFeatureScope scope(masm, VFP2);
4196 // Save callee-saved vfp registers. 4190 // Save callee-saved vfp registers.
4197 __ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg); 4191 __ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
4198 // Set up the reserved register for 0.0. 4192 // Set up the reserved register for 0.0.
4199 __ vmov(kDoubleRegZero, 0.0); 4193 __ vmov(kDoubleRegZero, 0.0);
4200 } 4194 }
4201 4195
4202 // Get address of argv, see stm above. 4196 // Get address of argv, see stm above.
4203 // r0: code entry 4197 // r0: code entry
4204 // r1: function 4198 // r1: function
4205 // r2: receiver 4199 // r2: receiver
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
4339 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); 4333 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
4340 4334
4341 // Restore callee-saved registers and return. 4335 // Restore callee-saved registers and return.
4342 #ifdef DEBUG 4336 #ifdef DEBUG
4343 if (FLAG_debug_code) { 4337 if (FLAG_debug_code) {
4344 __ mov(lr, Operand(pc)); 4338 __ mov(lr, Operand(pc));
4345 } 4339 }
4346 #endif 4340 #endif
4347 4341
4348 if (CpuFeatures::IsSupported(VFP2)) { 4342 if (CpuFeatures::IsSupported(VFP2)) {
4349 CpuFeatures::Scope scope(VFP2); 4343 CpuFeatureScope scope(masm, VFP2);
4350 // Restore callee-saved vfp registers. 4344 // Restore callee-saved vfp registers.
4351 __ vldm(ia_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg); 4345 __ vldm(ia_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
4352 } 4346 }
4353 4347
4354 __ ldm(ia_w, sp, kCalleeSaved | pc.bit()); 4348 __ ldm(ia_w, sp, kCalleeSaved | pc.bit());
4355 } 4349 }
4356 4350
4357 4351
4358 // Uses registers r0 to r4. 4352 // Uses registers r0 to r4.
4359 // Expected input (depending on whether args are in registers or on the stack): 4353 // Expected input (depending on whether args are in registers or on the stack):
(...skipping 2723 matching lines...) Expand 10 before | Expand all | Expand 10 after
7083 if (left_ == CompareIC::SMI) { 7077 if (left_ == CompareIC::SMI) {
7084 __ JumpIfNotSmi(r1, &miss); 7078 __ JumpIfNotSmi(r1, &miss);
7085 } 7079 }
7086 if (right_ == CompareIC::SMI) { 7080 if (right_ == CompareIC::SMI) {
7087 __ JumpIfNotSmi(r0, &miss); 7081 __ JumpIfNotSmi(r0, &miss);
7088 } 7082 }
7089 7083
7090 // Inlining the double comparison and falling back to the general compare 7084 // Inlining the double comparison and falling back to the general compare
7091 // stub if NaN is involved or VFP2 is unsupported. 7085 // stub if NaN is involved or VFP2 is unsupported.
7092 if (CpuFeatures::IsSupported(VFP2)) { 7086 if (CpuFeatures::IsSupported(VFP2)) {
7093 CpuFeatures::Scope scope(VFP2); 7087 CpuFeatureScope scope(masm, VFP2);
7094 7088
7095 // Load left and right operand. 7089 // Load left and right operand.
7096 Label done, left, left_smi, right_smi; 7090 Label done, left, left_smi, right_smi;
7097 __ JumpIfSmi(r0, &right_smi); 7091 __ JumpIfSmi(r0, &right_smi);
7098 __ CheckMap(r0, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1, 7092 __ CheckMap(r0, r2, Heap::kHeapNumberMapRootIndex, &maybe_undefined1,
7099 DONT_DO_SMI_CHECK); 7093 DONT_DO_SMI_CHECK);
7100 __ sub(r2, r0, Operand(kHeapObjectTag)); 7094 __ sub(r2, r0, Operand(kHeapObjectTag));
7101 __ vldr(d1, r2, HeapNumber::kValueOffset); 7095 __ vldr(d1, r2, HeapNumber::kValueOffset);
7102 __ b(&left); 7096 __ b(&left);
7103 __ bind(&right_smi); 7097 __ bind(&right_smi);
(...skipping 1003 matching lines...) Expand 10 before | Expand all | Expand 10 after
8107 8101
8108 __ Pop(lr, r5, r1); 8102 __ Pop(lr, r5, r1);
8109 __ Ret(); 8103 __ Ret();
8110 } 8104 }
8111 8105
8112 #undef __ 8106 #undef __
8113 8107
8114 } } // namespace v8::internal 8108 } } // namespace v8::internal
8115 8109
8116 #endif // V8_TARGET_ARCH_ARM 8110 #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