Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 859 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); | 859 Operand(scratch1, LSL, kPointerSizeLog2 + 1)); |
| 860 | 860 |
| 861 Register probe = mask; | 861 Register probe = mask; |
| 862 __ ldr(probe, | 862 __ ldr(probe, |
| 863 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); | 863 FieldMemOperand(scratch1, FixedArray::kHeaderSize)); |
| 864 __ BranchOnSmi(probe, not_found); | 864 __ BranchOnSmi(probe, not_found); |
| 865 __ sub(scratch2, object, Operand(kHeapObjectTag)); | 865 __ sub(scratch2, object, Operand(kHeapObjectTag)); |
| 866 __ vldr(d0, scratch2, HeapNumber::kValueOffset); | 866 __ vldr(d0, scratch2, HeapNumber::kValueOffset); |
| 867 __ sub(probe, probe, Operand(kHeapObjectTag)); | 867 __ sub(probe, probe, Operand(kHeapObjectTag)); |
| 868 __ vldr(d1, probe, HeapNumber::kValueOffset); | 868 __ vldr(d1, probe, HeapNumber::kValueOffset); |
| 869 __ vcmp(d0, d1); | 869 __ VFPCompareAndSetFlags(d0, d1); |
| 870 __ vmrs(pc); | |
| 871 __ b(ne, not_found); // The cache did not contain this value. | 870 __ b(ne, not_found); // The cache did not contain this value. |
| 872 __ b(&load_result_from_cache); | 871 __ b(&load_result_from_cache); |
| 873 } else { | 872 } else { |
| 874 __ b(not_found); | 873 __ b(not_found); |
| 875 } | 874 } |
| 876 } | 875 } |
| 877 | 876 |
| 878 __ bind(&is_smi); | 877 __ bind(&is_smi); |
| 879 Register scratch = scratch1; | 878 Register scratch = scratch1; |
| 880 __ and_(scratch, mask, Operand(object, ASR, 1)); | 879 __ and_(scratch, mask, Operand(object, ASR, 1)); |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 968 EmitSmiNonsmiComparison(masm, lhs_, rhs_, &lhs_not_nan, &slow, strict_); | 967 EmitSmiNonsmiComparison(masm, lhs_, rhs_, &lhs_not_nan, &slow, strict_); |
| 969 | 968 |
| 970 __ bind(&both_loaded_as_doubles); | 969 __ bind(&both_loaded_as_doubles); |
| 971 // The arguments have been converted to doubles and stored in d6 and d7, if | 970 // The arguments have been converted to doubles and stored in d6 and d7, if |
| 972 // VFP3 is supported, or in r0, r1, r2, and r3. | 971 // VFP3 is supported, or in r0, r1, r2, and r3. |
| 973 if (CpuFeatures::IsSupported(VFP3)) { | 972 if (CpuFeatures::IsSupported(VFP3)) { |
| 974 __ bind(&lhs_not_nan); | 973 __ bind(&lhs_not_nan); |
| 975 CpuFeatures::Scope scope(VFP3); | 974 CpuFeatures::Scope scope(VFP3); |
| 976 Label no_nan; | 975 Label no_nan; |
| 977 // ARMv7 VFP3 instructions to implement double precision comparison. | 976 // ARMv7 VFP3 instructions to implement double precision comparison. |
| 978 __ vcmp(d7, d6); | 977 __ VFPCompareAndSetFlags(d7, d6, r0); |
|
Rodolph Perfetta
2011/01/10 14:59:36
No need to clear the flags, if the result is unord
Søren Thygesen Gjesse
2011/01/11 08:56:17
OK, then I am a bit in the dark regarding the clea
Søren Thygesen Gjesse
2011/01/11 12:41:52
Done.
| |
| 979 __ vmrs(pc); // Move vector status bits to normal status bits. | |
| 980 Label nan; | 978 Label nan; |
| 981 __ b(vs, &nan); | 979 __ b(vs, &nan); |
| 982 __ mov(r0, Operand(EQUAL), LeaveCC, eq); | 980 __ mov(r0, Operand(EQUAL), LeaveCC, eq); |
| 983 __ mov(r0, Operand(LESS), LeaveCC, lt); | 981 __ mov(r0, Operand(LESS), LeaveCC, lt); |
| 984 __ mov(r0, Operand(GREATER), LeaveCC, gt); | 982 __ mov(r0, Operand(GREATER), LeaveCC, gt); |
| 985 __ Ret(); | 983 __ Ret(); |
| 986 | 984 |
| 987 __ bind(&nan); | 985 __ bind(&nan); |
| 988 // If one of the sides was a NaN then the v flag is set. Load r0 with | 986 // If one of the sides was a NaN then the v flag is set. Load r0 with |
| 989 // whatever it takes to make the comparison fail, since comparisons with NaN | 987 // whatever it takes to make the comparison fail, since comparisons with NaN |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1089 __ b(eq, &false_result); | 1087 __ b(eq, &false_result); |
| 1090 | 1088 |
| 1091 // HeapNumber => false iff +0, -0, or NaN. | 1089 // HeapNumber => false iff +0, -0, or NaN. |
| 1092 __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset)); | 1090 __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset)); |
| 1093 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 1091 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
| 1094 __ cmp(scratch, ip); | 1092 __ cmp(scratch, ip); |
| 1095 __ b(¬_heap_number, ne); | 1093 __ b(¬_heap_number, ne); |
| 1096 | 1094 |
| 1097 __ sub(ip, tos_, Operand(kHeapObjectTag)); | 1095 __ sub(ip, tos_, Operand(kHeapObjectTag)); |
| 1098 __ vldr(d1, ip, HeapNumber::kValueOffset); | 1096 __ vldr(d1, ip, HeapNumber::kValueOffset); |
| 1099 __ vcmp(d1, 0.0); | 1097 __ VFPCompareAndSetFlags(d1, 0.0, scratch); |
|
Rodolph Perfetta
2011/01/10 14:59:36
Ditto.
Søren Thygesen Gjesse
2011/01/11 12:41:52
Done.
| |
| 1100 __ vmrs(pc); | |
| 1101 // "tos_" is a register, and contains a non zero value by default. | 1098 // "tos_" is a register, and contains a non zero value by default. |
| 1102 // Hence we only need to overwrite "tos_" with zero to return false for | 1099 // Hence we only need to overwrite "tos_" with zero to return false for |
| 1103 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. | 1100 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. |
| 1104 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO | 1101 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO |
| 1105 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN | 1102 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN |
| 1106 __ Ret(); | 1103 __ Ret(); |
| 1107 | 1104 |
| 1108 __ bind(¬_heap_number); | 1105 __ bind(¬_heap_number); |
| 1109 | 1106 |
| 1110 // Check if the value is 'null'. | 1107 // Check if the value is 'null'. |
| (...skipping 3797 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4908 if (CpuFeatures::IsSupported(VFP3)) { | 4905 if (CpuFeatures::IsSupported(VFP3)) { |
| 4909 CpuFeatures::Scope scope(VFP3); | 4906 CpuFeatures::Scope scope(VFP3); |
| 4910 | 4907 |
| 4911 // Load left and right operand | 4908 // Load left and right operand |
| 4912 __ sub(r2, r1, Operand(kHeapObjectTag)); | 4909 __ sub(r2, r1, Operand(kHeapObjectTag)); |
| 4913 __ vldr(d0, r2, HeapNumber::kValueOffset); | 4910 __ vldr(d0, r2, HeapNumber::kValueOffset); |
| 4914 __ sub(r2, r0, Operand(kHeapObjectTag)); | 4911 __ sub(r2, r0, Operand(kHeapObjectTag)); |
| 4915 __ vldr(d1, r2, HeapNumber::kValueOffset); | 4912 __ vldr(d1, r2, HeapNumber::kValueOffset); |
| 4916 | 4913 |
| 4917 // Compare operands | 4914 // Compare operands |
| 4918 __ vcmp(d0, d1); | 4915 __ VFPCompareAndSetFlags(d0, d1, r2); |
|
Rodolph Perfetta
2011/01/10 14:59:36
Ditto.
Søren Thygesen Gjesse
2011/01/11 12:41:52
Done.
| |
| 4919 __ vmrs(pc); // Move vector status bits to normal status bits. | |
| 4920 | 4916 |
| 4921 // Don't base result on status bits when a NaN is involved. | 4917 // Don't base result on status bits when a NaN is involved. |
| 4922 __ b(vs, &unordered); | 4918 __ b(vs, &unordered); |
| 4923 | 4919 |
| 4924 // Return a result of -1, 0, or 1, based on status bits. | 4920 // Return a result of -1, 0, or 1, based on status bits. |
| 4925 __ mov(r0, Operand(EQUAL), LeaveCC, eq); | 4921 __ mov(r0, Operand(EQUAL), LeaveCC, eq); |
| 4926 __ mov(r0, Operand(LESS), LeaveCC, lt); | 4922 __ mov(r0, Operand(LESS), LeaveCC, lt); |
| 4927 __ mov(r0, Operand(GREATER), LeaveCC, gt); | 4923 __ mov(r0, Operand(GREATER), LeaveCC, gt); |
| 4928 __ Ret(); | 4924 __ Ret(); |
| 4929 | 4925 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4980 __ pop(r1); | 4976 __ pop(r1); |
| 4981 __ Jump(r2); | 4977 __ Jump(r2); |
| 4982 } | 4978 } |
| 4983 | 4979 |
| 4984 | 4980 |
| 4985 #undef __ | 4981 #undef __ |
| 4986 | 4982 |
| 4987 } } // namespace v8::internal | 4983 } } // namespace v8::internal |
| 4988 | 4984 |
| 4989 #endif // V8_TARGET_ARCH_ARM | 4985 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |