From 25c2940a08453ec206268f5e86cc520b06194d88 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Sun, 19 Aug 2012 17:01:32 -0700 Subject: [PATCH] v8: Relax requirement from VFP3 to VFP2 where possible. BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10818026 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@12194 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- deps/v8/build/common.gypi | 12 ++- deps/v8/src/arm/assembler-arm.cc | 108 ++++++++++++---------- deps/v8/src/arm/assembler-arm.h | 3 + deps/v8/src/arm/builtins-arm.cc | 5 +- deps/v8/src/arm/code-stubs-arm.cc | 105 ++++++++++----------- deps/v8/src/arm/code-stubs-arm.h | 16 ++-- deps/v8/src/arm/codegen-arm.cc | 10 +- deps/v8/src/arm/full-codegen-arm.cc | 8 +- deps/v8/src/arm/macro-assembler-arm.cc | 24 +++-- deps/v8/src/arm/stub-cache-arm.cc | 44 ++++----- deps/v8/src/flag-definitions.h | 4 +- deps/v8/src/platform-linux.cc | 3 + deps/v8/src/v8globals.h | 1 + deps/v8/test/cctest/test-assembler-arm.cc | 14 +-- 14 files changed, 192 insertions(+), 165 deletions(-) diff --git a/deps/v8/build/common.gypi b/deps/v8/build/common.gypi index 16091978763..b677a556850 100644 --- a/deps/v8/build/common.gypi +++ b/deps/v8/build/common.gypi @@ -48,7 +48,8 @@ # both for the snapshot and for the ARM target. Leaving the default value # of 'false' will avoid VFP instructions in the snapshot and use CPU feature # probing when running on the target. - 'v8_can_use_vfp_instructions%': 'false', + 'v8_can_use_vfp2_instructions%': 'false', + 'v8_can_use_vfp3_instructions%': 'false', # Similar to vfp but on MIPS. 'v8_can_use_fpu_instructions%': 'true', @@ -125,9 +126,14 @@ 'CAN_USE_UNALIGNED_ACCESSES=0', ], }], - [ 'v8_can_use_vfp_instructions=="true"', { + [ 'v8_can_use_vfp2_instructions=="true"', { 'defines': [ - 'CAN_USE_VFP_INSTRUCTIONS', + 'CAN_USE_VFP2_INSTRUCTIONS', + ], + }], + [ 'v8_can_use_vfp3_instructions=="true"', { + 'defines': [ + 'CAN_USE_VFP3_INSTRUCTIONS', ], }], [ 'v8_use_arm_eabi_hardfloat=="true"', { diff --git a/deps/v8/src/arm/assembler-arm.cc b/deps/v8/src/arm/assembler-arm.cc index ec28da40025..1787d158a88 100644 --- a/deps/v8/src/arm/assembler-arm.cc +++ b/deps/v8/src/arm/assembler-arm.cc @@ -32,7 +32,7 @@ // The original source code covered by the above license above has been // modified significantly by Google Inc. -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. #include "v8.h" @@ -52,17 +52,20 @@ unsigned CpuFeatures::found_by_runtime_probing_ = 0; // Get the CPU features enabled by the build. For cross compilation the -// preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP_INSTRUCTIONS +// preprocessor symbols CAN_USE_ARMV7_INSTRUCTIONS and CAN_USE_VFP3_INSTRUCTIONS // can be defined to enable ARMv7 and VFPv3 instructions when building the // snapshot. -static uint64_t CpuFeaturesImpliedByCompiler() { - uint64_t answer = 0; +static unsigned CpuFeaturesImpliedByCompiler() { + unsigned answer = 0; #ifdef CAN_USE_ARMV7_INSTRUCTIONS answer |= 1u << ARMv7; -#endif // def CAN_USE_ARMV7_INSTRUCTIONS -#ifdef CAN_USE_VFP_INSTRUCTIONS - answer |= 1u << VFP3 | 1u << ARMv7; -#endif // def CAN_USE_VFP_INSTRUCTIONS +#endif // CAN_USE_ARMV7_INSTRUCTIONS +#ifdef CAN_USE_VFP3_INSTRUCTIONS + answer |= 1u << VFP3 | 1u << VFP2 | 1u << ARMv7; +#endif // CAN_USE_VFP3_INSTRUCTIONS +#ifdef CAN_USE_VFP2_INSTRUCTIONS + answer |= 1u << VFP2; +#endif // CAN_USE_VFP2_INSTRUCTIONS #ifdef __arm__ // If the compiler is allowed to use VFP then we can use VFP too in our code @@ -70,10 +73,10 @@ static uint64_t CpuFeaturesImpliedByCompiler() { // point support implies VFPv3, see ARM DDI 0406B, page A1-6. #if defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) \ && !defined(__SOFTFP__) - answer |= 1u << VFP3 | 1u << ARMv7; + answer |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; #endif // defined(CAN_USE_ARMV7_INSTRUCTIONS) && defined(__VFP_FP__) // && !defined(__SOFTFP__) -#endif // def __arm__ +#endif // _arm__ return answer; } @@ -101,27 +104,32 @@ void CpuFeatures::Probe() { // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6. if (FLAG_enable_vfp3) { - supported_ |= 1u << VFP3 | 1u << ARMv7; + supported_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; } // For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled if (FLAG_enable_armv7) { supported_ |= 1u << ARMv7; } -#else // def __arm__ +#else // __arm__ // Probe for additional features not already known to be available. if (!IsSupported(VFP3) && OS::ArmCpuHasFeature(VFP3)) { // This implementation also sets the VFP flags if runtime - // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI + // detection of VFP returns true. VFPv3 implies ARMv7 and VFP2, see ARM DDI // 0406B, page A1-6. - supported_ |= 1u << VFP3 | 1u << ARMv7; - found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7; + found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7 | 1u << VFP2; + } else if (!IsSupported(VFP2) && OS::ArmCpuHasFeature(VFP2)) { + found_by_runtime_probing_ |= 1u << VFP2; } if (!IsSupported(ARMv7) && OS::ArmCpuHasFeature(ARMv7)) { - supported_ |= 1u << ARMv7; found_by_runtime_probing_ |= 1u << ARMv7; } + + supported_ |= found_by_runtime_probing_; #endif + + // Assert that VFP3 implies VFP2 and ARMv7. + ASSERT(!IsSupported(VFP3) || (IsSupported(VFP2) && IsSupported(ARMv7))); } @@ -1656,7 +1664,7 @@ void Assembler::vldr(const DwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-628. // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | // Vdst(15-12) | 1011(11-8) | offset - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); int u = 1; if (offset < 0) { offset = -offset; @@ -1698,7 +1706,7 @@ void Assembler::vldr(const SwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-628. // cond(31-28) | 1101(27-24)| U001(23-20) | Rbase(19-16) | // Vdst(15-12) | 1010(11-8) | offset - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); int u = 1; if (offset < 0) { offset = -offset; @@ -1742,7 +1750,7 @@ void Assembler::vstr(const DwVfpRegister src, // Instruction details available in ARM DDI 0406A, A8-786. // cond(31-28) | 1101(27-24)| U000(23-20) | | Rbase(19-16) | // Vsrc(15-12) | 1011(11-8) | (offset/4) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); int u = 1; if (offset < 0) { offset = -offset; @@ -1783,7 +1791,7 @@ void Assembler::vstr(const SwVfpRegister src, // Instruction details available in ARM DDI 0406A, A8-786. // cond(31-28) | 1101(27-24)| U000(23-20) | Rbase(19-16) | // Vdst(15-12) | 1010(11-8) | (offset/4) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); int u = 1; if (offset < 0) { offset = -offset; @@ -1826,7 +1834,7 @@ void Assembler::vldm(BlockAddrMode am, // Instruction details available in ARM DDI 0406A, A8-626. // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | // first(15-12) | 1010(11-8) | (count * 2) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT_LE(first.code(), last.code()); ASSERT(am == ia || am == ia_w || am == db_w); ASSERT(!base.is(pc)); @@ -1847,7 +1855,7 @@ void Assembler::vstm(BlockAddrMode am, // Instruction details available in ARM DDI 0406A, A8-784. // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | // first(15-12) | 1011(11-8) | (count * 2) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT_LE(first.code(), last.code()); ASSERT(am == ia || am == ia_w || am == db_w); ASSERT(!base.is(pc)); @@ -1867,7 +1875,7 @@ void Assembler::vldm(BlockAddrMode am, // Instruction details available in ARM DDI 0406A, A8-626. // cond(31-28) | 110(27-25)| PUDW1(24-20) | Rbase(19-16) | // first(15-12) | 1010(11-8) | (count/2) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT_LE(first.code(), last.code()); ASSERT(am == ia || am == ia_w || am == db_w); ASSERT(!base.is(pc)); @@ -1888,7 +1896,7 @@ void Assembler::vstm(BlockAddrMode am, // Instruction details available in ARM DDI 0406A, A8-784. // cond(31-28) | 110(27-25)| PUDW0(24-20) | Rbase(19-16) | // first(15-12) | 1011(11-8) | (count/2) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT_LE(first.code(), last.code()); ASSERT(am == ia || am == ia_w || am == db_w); ASSERT(!base.is(pc)); @@ -1911,7 +1919,7 @@ static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { // Only works for little endian floating point formats. // We don't support VFP on the mixed endian floating point platform. static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsSupported(VFP3)); // VMOV can accept an immediate of the form: // @@ -1964,10 +1972,10 @@ void Assembler::vmov(const DwVfpRegister dst, const Condition cond) { // Dd = immediate // Instruction details available in ARM DDI 0406B, A8-640. - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); uint32_t enc; - if (FitsVMOVDoubleImmediate(imm, &enc)) { + if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { // The double can be encoded in the instruction. emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0xB*B8 | enc); } else { @@ -2001,7 +2009,7 @@ void Assembler::vmov(const SwVfpRegister dst, const Condition cond) { // Sd = Sm // Instruction details available in ARM DDI 0406B, A8-642. - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); int sd, d, sm, m; dst.split_code(&sd, &d); src.split_code(&sm, &m); @@ -2014,7 +2022,7 @@ void Assembler::vmov(const DwVfpRegister dst, const Condition cond) { // Dd = Dm // Instruction details available in ARM DDI 0406B, A8-642. - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); } @@ -2028,7 +2036,7 @@ void Assembler::vmov(const DwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-646. // cond(31-28) | 1100(27-24)| 010(23-21) | op=0(20) | Rt2(19-16) | // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT(!src1.is(pc) && !src2.is(pc)); emit(cond | 0xC*B24 | B22 | src2.code()*B16 | src1.code()*B12 | 0xB*B8 | B4 | dst.code()); @@ -2043,7 +2051,7 @@ void Assembler::vmov(const Register dst1, // Instruction details available in ARM DDI 0406A, A8-646. // cond(31-28) | 1100(27-24)| 010(23-21) | op=1(20) | Rt2(19-16) | // Rt(15-12) | 1011(11-8) | 00(7-6) | M(5) | 1(4) | Vm - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT(!dst1.is(pc) && !dst2.is(pc)); emit(cond | 0xC*B24 | B22 | B20 | dst2.code()*B16 | dst1.code()*B12 | 0xB*B8 | B4 | src.code()); @@ -2057,7 +2065,7 @@ void Assembler::vmov(const SwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-642. // cond(31-28) | 1110(27-24)| 000(23-21) | op=0(20) | Vn(19-16) | // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT(!src.is(pc)); int sn, n; dst.split_code(&sn, &n); @@ -2072,7 +2080,7 @@ void Assembler::vmov(const Register dst, // Instruction details available in ARM DDI 0406A, A8-642. // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT(!dst.is(pc)); int sn, n; src.split_code(&sn, &n); @@ -2197,7 +2205,7 @@ void Assembler::vcvt_f64_s32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(F64, dst.code(), S32, src.code(), mode, cond)); } @@ -2206,7 +2214,7 @@ void Assembler::vcvt_f32_s32(const SwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(F32, dst.code(), S32, src.code(), mode, cond)); } @@ -2215,7 +2223,7 @@ void Assembler::vcvt_f64_u32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(F64, dst.code(), U32, src.code(), mode, cond)); } @@ -2224,7 +2232,7 @@ void Assembler::vcvt_s32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(S32, dst.code(), F64, src.code(), mode, cond)); } @@ -2233,7 +2241,7 @@ void Assembler::vcvt_u32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(U32, dst.code(), F64, src.code(), mode, cond)); } @@ -2242,7 +2250,7 @@ void Assembler::vcvt_f64_f32(const DwVfpRegister dst, const SwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(F64, dst.code(), F32, src.code(), mode, cond)); } @@ -2251,7 +2259,7 @@ void Assembler::vcvt_f32_f64(const SwVfpRegister dst, const DwVfpRegister src, VFPConversionMode mode, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(EncodeVCVT(F32, dst.code(), F64, src.code(), mode, cond)); } @@ -2259,6 +2267,7 @@ void Assembler::vcvt_f32_f64(const SwVfpRegister dst, void Assembler::vneg(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond) { + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0xB*B20 | B16 | dst.code()*B12 | 0x5*B9 | B8 | B6 | src.code()); } @@ -2267,6 +2276,7 @@ void Assembler::vneg(const DwVfpRegister dst, void Assembler::vabs(const DwVfpRegister dst, const DwVfpRegister src, const Condition cond) { + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0xB*B20 | dst.code()*B12 | 0x5*B9 | B8 | 0x3*B6 | src.code()); } @@ -2281,7 +2291,7 @@ void Assembler::vadd(const DwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-536. // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | dst.code()*B12 | 0x5*B9 | B8 | src2.code()); } @@ -2296,7 +2306,7 @@ void Assembler::vsub(const DwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-784. // cond(31-28) | 11100(27-23)| D=?(22) | 11(21-20) | Vn(19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 1(6) | M=?(5) | 0(4) | Vm(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0x3*B20 | src1.code()*B16 | dst.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); } @@ -2311,7 +2321,7 @@ void Assembler::vmul(const DwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-784. // cond(31-28) | 11100(27-23)| D=?(22) | 10(21-20) | Vn(19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=0 | 0(6) | M=?(5) | 0(4) | Vm(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0x2*B20 | src1.code()*B16 | dst.code()*B12 | 0x5*B9 | B8 | src2.code()); } @@ -2326,7 +2336,7 @@ void Assembler::vdiv(const DwVfpRegister dst, // Instruction details available in ARM DDI 0406A, A8-584. // cond(31-28) | 11101(27-23)| D=?(22) | 00(21-20) | Vn(19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | N(7)=? | 0(6) | M=?(5) | 0(4) | Vm(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | B23 | src1.code()*B16 | dst.code()*B12 | 0x5*B9 | B8 | src2.code()); } @@ -2339,7 +2349,7 @@ void Assembler::vcmp(const DwVfpRegister src1, // Instruction details available in ARM DDI 0406A, A8-570. // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0100 (19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | Vm(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | src1.code()*B12 | 0x5*B9 | B8 | B6 | src2.code()); } @@ -2352,7 +2362,7 @@ void Assembler::vcmp(const DwVfpRegister src1, // Instruction details available in ARM DDI 0406A, A8-570. // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0101 (19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | E(7)=0 | 1(6) | M(5)=? | 0(4) | 0000(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); ASSERT(src2 == 0.0); emit(cond | 0xE*B24 |B23 | 0x3*B20 | B18 | B16 | src1.code()*B12 | 0x5*B9 | B8 | B6); @@ -2363,7 +2373,7 @@ void Assembler::vmsr(Register dst, Condition cond) { // Instruction details available in ARM DDI 0406A, A8-652. // cond(31-28) | 1110 (27-24) | 1110(23-20)| 0001 (19-16) | // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0xE*B20 | B16 | dst.code()*B12 | 0xA*B8 | B4); } @@ -2373,7 +2383,7 @@ void Assembler::vmrs(Register dst, Condition cond) { // Instruction details available in ARM DDI 0406A, A8-652. // cond(31-28) | 1110 (27-24) | 1111(23-20)| 0001 (19-16) | // Rt(15-12) | 1010 (11-8) | 0(7) | 00 (6-5) | 1(4) | 0000(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | 0xF*B20 | B16 | dst.code()*B12 | 0xA*B8 | B4); } @@ -2384,7 +2394,7 @@ void Assembler::vsqrt(const DwVfpRegister dst, const Condition cond) { // cond(31-28) | 11101 (27-23)| D=?(22) | 11 (21-20) | 0001 (19-16) | // Vd(15-12) | 101(11-9) | sz(8)=1 | 11 (7-6) | M(5)=? | 0(4) | Vm(3-0) - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); emit(cond | 0xE*B24 | B23 | 0x3*B20 | B16 | dst.code()*B12 | 0x5*B9 | B8 | 3*B6 | src.code()); } diff --git a/deps/v8/src/arm/assembler-arm.h b/deps/v8/src/arm/assembler-arm.h index e2d5f598b78..e0518ef77cf 100644 --- a/deps/v8/src/arm/assembler-arm.h +++ b/deps/v8/src/arm/assembler-arm.h @@ -510,6 +510,7 @@ class CpuFeatures : public AllStatic { static bool IsSupported(CpuFeature f) { ASSERT(initialized_); if (f == VFP3 && !FLAG_enable_vfp3) return false; + if (f == VFP2 && !FLAG_enable_vfp2) return false; return (supported_ & (1u << f)) != 0; } @@ -535,6 +536,8 @@ class CpuFeatures : public AllStatic { public: explicit Scope(CpuFeature f) { unsigned mask = 1u << f; + // VFP2 and ARMv7 are implied by VFP3. + if (f == VFP3) mask |= 1u << VFP2 | 1u << ARMv7; ASSERT(CpuFeatures::IsSupported(f)); ASSERT(!Serializer::enabled() || (CpuFeatures::found_by_runtime_probing_ & mask) == 0); diff --git a/deps/v8/src/arm/builtins-arm.cc b/deps/v8/src/arm/builtins-arm.cc index 578bd810d40..9cacac0b032 100644 --- a/deps/v8/src/arm/builtins-arm.cc +++ b/deps/v8/src/arm/builtins-arm.cc @@ -1246,10 +1246,7 @@ void Builtins::Generate_NotifyOSR(MacroAssembler* masm) { void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { CpuFeatures::TryForceFeatureScope scope(VFP3); - if (!CpuFeatures::IsSupported(VFP3)) { - __ Abort("Unreachable code: Cannot optimize without VFP3 support."); - return; - } + ASSERT(CPU::SupportsCrankshaft()); // Lookup the function in the JavaScript frame and push it as an // argument to the on-stack replacement function. diff --git a/deps/v8/src/arm/code-stubs-arm.cc b/deps/v8/src/arm/code-stubs-arm.cc index 761123f6393..3f0846ac6bd 100644 --- a/deps/v8/src/arm/code-stubs-arm.cc +++ b/deps/v8/src/arm/code-stubs-arm.cc @@ -519,8 +519,8 @@ void FloatingPointHelper::LoadSmis(MacroAssembler* masm, FloatingPointHelper::Destination destination, Register scratch1, Register scratch2) { - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ mov(scratch1, Operand(r0, ASR, kSmiTagSize)); __ vmov(d7.high(), scratch1); __ vcvt_f64_s32(d7, d7.high()); @@ -589,9 +589,9 @@ void FloatingPointHelper::LoadNumber(MacroAssembler* masm, __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_number); // Handle loading a double from a heap number. - if (CpuFeatures::IsSupported(VFP3) && + if (CpuFeatures::IsSupported(VFP2) && destination == kVFPRegisters) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); // Load the double from tagged HeapNumber to double register. __ sub(scratch1, object, Operand(kHeapObjectTag)); __ vldr(dst, scratch1, HeapNumber::kValueOffset); @@ -604,8 +604,8 @@ void FloatingPointHelper::LoadNumber(MacroAssembler* masm, // Handle loading a double from a smi. __ bind(&is_smi); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Convert smi to double using VFP instructions. __ vmov(dst.high(), scratch1); __ vcvt_f64_s32(dst, dst.high()); @@ -682,8 +682,8 @@ void FloatingPointHelper::ConvertIntToDouble(MacroAssembler* masm, Label done; - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ vmov(single_scratch, int_scratch); __ vcvt_f64_s32(double_dst, single_scratch); if (destination == kCoreRegisters) { @@ -776,8 +776,8 @@ void FloatingPointHelper::LoadNumberAsInt32Double(MacroAssembler* masm, __ JumpIfNotHeapNumber(object, heap_number_map, scratch1, not_int32); // Load the number. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Load the double value. __ sub(scratch1, object, Operand(kHeapObjectTag)); __ vldr(double_dst, scratch1, HeapNumber::kValueOffset); @@ -847,8 +847,8 @@ void FloatingPointHelper::LoadNumberAsInt32(MacroAssembler* masm, // Object is a heap number. // Convert the floating point value to a 32-bit integer. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); SwVfpRegister single_scratch = double_scratch.low(); // Load the double value. __ sub(scratch1, object, Operand(kHeapObjectTag)); @@ -978,7 +978,7 @@ void FloatingPointHelper::CallCCodeForDoubleOperation( __ push(lr); __ PrepareCallCFunction(0, 2, scratch); if (masm->use_eabi_hardfloat()) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ vmov(d0, r0, r1); __ vmov(d1, r2, r3); } @@ -990,7 +990,7 @@ void FloatingPointHelper::CallCCodeForDoubleOperation( // Store answer in the overwritable heap number. Double returned in // registers r0 and r1 or in d0. if (masm->use_eabi_hardfloat()) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ vstr(d0, FieldMemOperand(heap_number_result, HeapNumber::kValueOffset)); } else { @@ -1209,9 +1209,9 @@ static void EmitSmiNonsmiComparison(MacroAssembler* masm, } // Lhs is a smi, rhs is a number. - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { // Convert lhs to a double in d7. - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ SmiToDoubleVFPRegister(lhs, d7, r7, s15); // Load the double from rhs, tagged HeapNumber r0, to d6. __ sub(r7, rhs, Operand(kHeapObjectTag)); @@ -1249,8 +1249,8 @@ static void EmitSmiNonsmiComparison(MacroAssembler* masm, } // Rhs is a smi, lhs is a heap number. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Load the double from lhs, tagged HeapNumber r1, to d7. __ sub(r7, lhs, Operand(kHeapObjectTag)); __ vldr(d7, r7, HeapNumber::kValueOffset); @@ -1362,7 +1362,7 @@ static void EmitTwoNonNanDoubleComparison(MacroAssembler* masm, __ push(lr); __ PrepareCallCFunction(0, 2, r5); if (masm->use_eabi_hardfloat()) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ vmov(d0, r0, r1); __ vmov(d1, r2, r3); } @@ -1437,8 +1437,8 @@ static void EmitCheckForTwoHeapNumbers(MacroAssembler* masm, // Both are heap numbers. Load them up then jump to the code we have // for that. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ sub(r7, rhs, Operand(kHeapObjectTag)); __ vldr(d6, r7, HeapNumber::kValueOffset); __ sub(r7, lhs, Operand(kHeapObjectTag)); @@ -1527,8 +1527,8 @@ void NumberToStringStub::GenerateLookupNumberStringCache(MacroAssembler* masm, Label load_result_from_cache; if (!object_is_smi) { __ JumpIfSmi(object, &is_smi); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ CheckMap(object, scratch1, Heap::kHeapNumberMapRootIndex, @@ -1659,9 +1659,9 @@ void CompareStub::Generate(MacroAssembler* masm) { // The arguments have been converted to doubles and stored in d6 and d7, if // VFP3 is supported, or in r0, r1, r2, and r3. Isolate* isolate = masm->isolate(); - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { __ bind(&lhs_not_nan); - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); Label no_nan; // ARMv7 VFP3 instructions to implement double precision comparison. __ VFPCompareAndSetFlags(d7, d6); @@ -1780,7 +1780,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. // This stub uses VFP3 instructions. - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); Label patch; const Register map = r9.is(tos_) ? r7 : r9; @@ -1892,7 +1892,7 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { // restore them. __ stm(db_w, sp, kCallerSaved | lr.bit()); if (save_doubles_ == kSaveFPRegs) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ sub(sp, sp, Operand(kDoubleSize * DwVfpRegister::kNumRegisters)); for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { DwVfpRegister reg = DwVfpRegister::from_code(i); @@ -1910,7 +1910,7 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { ExternalReference::store_buffer_overflow_function(masm->isolate()), argument_count); if (save_doubles_ == kSaveFPRegs) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); for (int i = 0; i < DwVfpRegister::kNumRegisters; i++) { DwVfpRegister reg = DwVfpRegister::from_code(i); __ vldr(reg, MemOperand(sp, i * kDoubleSize)); @@ -2140,9 +2140,9 @@ void UnaryOpStub::GenerateHeapNumberCodeBitNot( __ mov(r0, r2); // Move newly allocated heap number to r0. } - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { // Convert the int32 in r1 to the heap number in r0. r2 is corrupted. - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ vmov(s0, r1); __ vcvt_f64_s32(d0, s0); __ sub(r2, r0, Operand(kHeapObjectTag)); @@ -2442,7 +2442,7 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm, // Load left and right operands into d6 and d7 or r0/r1 and r2/r3 // depending on whether VFP3 is available or not. FloatingPointHelper::Destination destination = - CpuFeatures::IsSupported(VFP3) && + CpuFeatures::IsSupported(VFP2) && op_ != Token::MOD ? FloatingPointHelper::kVFPRegisters : FloatingPointHelper::kCoreRegisters; @@ -2469,7 +2469,7 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm, // Using VFP registers: // d6: Left value // d7: Right value - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); switch (op_) { case Token::ADD: __ vadd(d5, d6, d7); @@ -2558,7 +2558,7 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm, // The code below for writing into heap numbers isn't capable of // writing the register as an unsigned int so we go to slow case if we // hit this case. - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { __ b(mi, &result_not_a_smi); } else { __ b(mi, not_numbers); @@ -2597,10 +2597,10 @@ void BinaryOpStub::GenerateFPOperation(MacroAssembler* masm, // result. __ mov(r0, Operand(r5)); - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { // Convert the int32 in r2 to the heap number in r0. r3 is corrupted. As // mentioned above SHR needs to always produce a positive result. - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ vmov(s0, r2); if (op_ == Token::SHR) { __ vcvt_f64_u32(d0, s0); @@ -2759,7 +2759,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { // Jump to type transition if they are not. The registers r0 and r1 (right // and left) are preserved for the runtime call. FloatingPointHelper::Destination destination = - (CpuFeatures::IsSupported(VFP3) && op_ != Token::MOD) + (CpuFeatures::IsSupported(VFP2) && op_ != Token::MOD) ? FloatingPointHelper::kVFPRegisters : FloatingPointHelper::kCoreRegisters; @@ -2787,7 +2787,7 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { &transition); if (destination == FloatingPointHelper::kVFPRegisters) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); Label return_heap_number; switch (op_) { case Token::ADD: @@ -2954,9 +2954,9 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { // We only get a negative result if the shift value (r2) is 0. // This result cannot be respresented as a signed 32-bit integer, try // to return a heap number if we can. - // The non vfp3 code does not support this special case, so jump to + // The non vfp2 code does not support this special case, so jump to // runtime if we don't support it. - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { __ b(mi, (result_type_ <= BinaryOpIC::INT32) ? &transition : &return_heap_number); @@ -2991,8 +2991,8 @@ void BinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { scratch2, &call_runtime); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); if (op_ != Token::SHR) { // Convert the result to a floating point value. __ vmov(double_scratch.low(), r2); @@ -3221,8 +3221,8 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { const Register cache_entry = r0; const bool tagged = (argument_type_ == TAGGED); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); if (tagged) { // Argument is a number and is on stack and in r0. // Load argument and check if it is a smi. @@ -3385,6 +3385,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm, Register scratch) { + ASSERT(CpuFeatures::IsEnabled(VFP2)); Isolate* isolate = masm->isolate(); __ push(lr); @@ -3445,7 +3446,7 @@ void InterruptStub::Generate(MacroAssembler* masm) { void MathPowStub::Generate(MacroAssembler* masm) { - CpuFeatures::Scope vfp3_scope(VFP3); + CpuFeatures::Scope vfp2_scope(VFP2); const Register base = r1; const Register exponent = r2; const Register heapnumbermap = r5; @@ -3544,7 +3545,7 @@ void MathPowStub::Generate(MacroAssembler* masm) { // Add +0 to convert -0 to +0. __ vadd(double_scratch, double_base, kDoubleRegZero); - __ vmov(double_result, 1); + __ vmov(double_result, 1.0); __ vsqrt(double_scratch, double_scratch); __ vdiv(double_result, double_result, double_scratch); __ jmp(&done); @@ -3901,8 +3902,8 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Save callee-saved registers (incl. cp and fp), sp, and lr __ stm(db_w, sp, kCalleeSaved | lr.bit()); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Save callee-saved vfp registers. __ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg); // Set up the reserved register for 0.0. @@ -3917,7 +3918,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { // Set up argv in r4. int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize; - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { offset_to_argv += kNumDoubleCalleeSaved * kDoubleSize; } __ ldr(r4, MemOperand(sp, offset_to_argv)); @@ -4055,8 +4056,8 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { } #endif - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Restore callee-saved vfp registers. __ vldm(ia_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg); } @@ -6583,8 +6584,8 @@ void ICCompareStub::GenerateHeapNumbers(MacroAssembler* masm) { // Inlining the double comparison and falling back to the general compare // stub if NaN is involved or VFP3 is unsupported. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Load left and right operand __ sub(r2, r1, Operand(kHeapObjectTag)); diff --git a/deps/v8/src/arm/code-stubs-arm.h b/deps/v8/src/arm/code-stubs-arm.h index 38ed476cc1e..3ddc405715e 100644 --- a/deps/v8/src/arm/code-stubs-arm.h +++ b/deps/v8/src/arm/code-stubs-arm.h @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -149,7 +149,7 @@ class BinaryOpStub: public CodeStub { mode_(mode), operands_type_(BinaryOpIC::UNINITIALIZED), result_type_(BinaryOpIC::UNINITIALIZED) { - use_vfp3_ = CpuFeatures::IsSupported(VFP3); + use_vfp2_ = CpuFeatures::IsSupported(VFP2); ASSERT(OpBits::is_valid(Token::NUM_TOKENS)); } @@ -159,7 +159,7 @@ class BinaryOpStub: public CodeStub { BinaryOpIC::TypeInfo result_type = BinaryOpIC::UNINITIALIZED) : op_(OpBits::decode(key)), mode_(ModeBits::decode(key)), - use_vfp3_(VFP3Bits::decode(key)), + use_vfp2_(VFP2Bits::decode(key)), operands_type_(operands_type), result_type_(result_type) { } @@ -171,7 +171,7 @@ class BinaryOpStub: public CodeStub { Token::Value op_; OverwriteMode mode_; - bool use_vfp3_; + bool use_vfp2_; // Operand type information determined at runtime. BinaryOpIC::TypeInfo operands_type_; @@ -182,7 +182,7 @@ class BinaryOpStub: public CodeStub { // Minor key encoding in 16 bits RRRTTTVOOOOOOOMM. class ModeBits: public BitField {}; class OpBits: public BitField {}; - class VFP3Bits: public BitField {}; + class VFP2Bits: public BitField {}; class OperandTypeInfoBits: public BitField {}; class ResultTypeInfoBits: public BitField {}; @@ -190,7 +190,7 @@ class BinaryOpStub: public CodeStub { int MinorKey() { return OpBits::encode(op_) | ModeBits::encode(mode_) - | VFP3Bits::encode(use_vfp3_) + | VFP2Bits::encode(use_vfp2_) | OperandTypeInfoBits::encode(operands_type_) | ResultTypeInfoBits::encode(result_type_); } @@ -571,7 +571,7 @@ class RecordWriteStub: public CodeStub { void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) { masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit()); if (mode == kSaveFPRegs) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); masm->sub(sp, sp, Operand(kDoubleSize * (DwVfpRegister::kNumRegisters - 1))); @@ -586,7 +586,7 @@ class RecordWriteStub: public CodeStub { inline void RestoreCallerSaveRegisters(MacroAssembler*masm, SaveFPRegsMode mode) { if (mode == kSaveFPRegs) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); // Restore all VFP registers except d0. for (int i = DwVfpRegister::kNumRegisters - 1; i > 0; i--) { DwVfpRegister reg = DwVfpRegister::from_code(i); diff --git a/deps/v8/src/arm/codegen-arm.cc b/deps/v8/src/arm/codegen-arm.cc index e00afb90354..3bdee1f945a 100644 --- a/deps/v8/src/arm/codegen-arm.cc +++ b/deps/v8/src/arm/codegen-arm.cc @@ -107,7 +107,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( // -- r4 : scratch (elements) // ----------------------------------- Label loop, entry, convert_hole, gc_required, only_change_map, done; - bool vfp3_supported = CpuFeatures::IsSupported(VFP3); + bool vfp2_supported = CpuFeatures::IsSupported(VFP2); // Check for empty arrays, which only require a map transition and no changes // to the backing store. @@ -163,7 +163,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( // r5: kHoleNanUpper32 // r6: end of destination FixedDoubleArray, not tagged // r7: begin of FixedDoubleArray element fields, not tagged - if (!vfp3_supported) __ Push(r1, r0); + if (!vfp2_supported) __ Push(r1, r0); __ b(&entry); @@ -191,8 +191,8 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( __ UntagAndJumpIfNotSmi(r9, r9, &convert_hole); // Normal smi, convert to double and store. - if (vfp3_supported) { - CpuFeatures::Scope scope(VFP3); + if (vfp2_supported) { + CpuFeatures::Scope scope(VFP2); __ vmov(s0, r9); __ vcvt_f64_s32(d0, s0); __ vstr(d0, r7, 0); @@ -225,7 +225,7 @@ void ElementsTransitionGenerator::GenerateSmiToDouble( __ cmp(r7, r6); __ b(lt, &loop); - if (!vfp3_supported) __ Pop(r1, r0); + if (!vfp2_supported) __ Pop(r1, r0); __ pop(lr); __ bind(&done); } diff --git a/deps/v8/src/arm/full-codegen-arm.cc b/deps/v8/src/arm/full-codegen-arm.cc index ff7c3c139e5..fbdb93082a9 100644 --- a/deps/v8/src/arm/full-codegen-arm.cc +++ b/deps/v8/src/arm/full-codegen-arm.cc @@ -675,7 +675,7 @@ void FullCodeGenerator::DoTest(Expression* condition, Label* if_true, Label* if_false, Label* fall_through) { - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { ToBooleanStub stub(result_register()); __ CallStub(&stub); __ tst(result_register(), result_register()); @@ -3052,13 +3052,13 @@ void FullCodeGenerator::EmitRandomHeapNumber(CallRuntime* expr) { // Convert 32 random bits in r0 to 0.(32 random bits) in a double // by computing: // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { __ PrepareCallCFunction(1, r0); __ ldr(r0, ContextOperand(context_register(), Context::GLOBAL_INDEX)); __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalContextOffset)); __ CallCFunction(ExternalReference::random_uint32_function(isolate()), 1); - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); // 0x41300000 is the top half of 1.0 x 2^20 as a double. // Create this constant using mov/orr to avoid PC relative load. __ mov(r1, Operand(0x41000000)); @@ -3181,7 +3181,7 @@ void FullCodeGenerator::EmitMathPow(CallRuntime* expr) { ASSERT(args->length() == 2); VisitForStackValue(args->at(0)); VisitForStackValue(args->at(1)); - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { MathPowStub stub(MathPowStub::ON_STACK); __ CallStub(&stub); } else { diff --git a/deps/v8/src/arm/macro-assembler-arm.cc b/deps/v8/src/arm/macro-assembler-arm.cc index 933399e00f4..d3bda3960d3 100644 --- a/deps/v8/src/arm/macro-assembler-arm.cc +++ b/deps/v8/src/arm/macro-assembler-arm.cc @@ -265,8 +265,8 @@ void MacroAssembler::Move(Register dst, Register src, Condition cond) { void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) { - ASSERT(CpuFeatures::IsSupported(VFP3)); - CpuFeatures::Scope scope(VFP3); + ASSERT(CpuFeatures::IsSupported(VFP2)); + CpuFeatures::Scope scope(VFP2); if (!dst.is(src)) { vmov(dst, src); } @@ -778,7 +778,7 @@ void MacroAssembler::VFPCompareAndLoadFlags(const DwVfpRegister src1, void MacroAssembler::Vmov(const DwVfpRegister dst, const double imm, const Condition cond) { - ASSERT(CpuFeatures::IsEnabled(VFP3)); + ASSERT(CpuFeatures::IsEnabled(VFP2)); static const DoubleRepresentation minus_zero(-0.0); static const DoubleRepresentation zero(0.0); DoubleRepresentation value(imm); @@ -930,6 +930,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, } void MacroAssembler::GetCFunctionDoubleResult(const DoubleRegister dst) { + ASSERT(CpuFeatures::IsSupported(VFP2)); if (use_eabi_hardfloat()) { Move(dst, d0); } else { @@ -1967,7 +1968,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, // scratch1 is now effective address of the double element FloatingPointHelper::Destination destination; - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { destination = FloatingPointHelper::kVFPRegisters; } else { destination = FloatingPointHelper::kCoreRegisters; @@ -1984,7 +1985,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, scratch4, s2); if (destination == FloatingPointHelper::kVFPRegisters) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); vstr(d0, scratch1, 0); } else { str(mantissa_reg, MemOperand(scratch1, 0)); @@ -2331,8 +2332,8 @@ void MacroAssembler::ConvertToInt32(Register source, Register scratch2, DwVfpRegister double_scratch, Label *not_int32) { - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); sub(scratch, source, Operand(kHeapObjectTag)); vldr(double_scratch, scratch, HeapNumber::kValueOffset); vcvt_s32_f64(double_scratch.low(), double_scratch); @@ -2427,8 +2428,8 @@ void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode, Register scratch1, Register scratch2, CheckForInexactConversion check_inexact) { - ASSERT(CpuFeatures::IsSupported(VFP3)); - CpuFeatures::Scope scope(VFP3); + ASSERT(CpuFeatures::IsSupported(VFP2)); + CpuFeatures::Scope scope(VFP2); Register prev_fpscr = scratch1; Register scratch = scratch2; @@ -2546,7 +2547,7 @@ void MacroAssembler::EmitECMATruncate(Register result, Register scratch, Register input_high, Register input_low) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); ASSERT(!input_high.is(result)); ASSERT(!input_low.is(result)); ASSERT(!input_low.is(input_high)); @@ -3332,6 +3333,7 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) { + ASSERT(CpuFeatures::IsSupported(VFP2)); if (use_eabi_hardfloat()) { Move(d0, dreg); } else { @@ -3342,6 +3344,7 @@ void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg) { void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1, DoubleRegister dreg2) { + ASSERT(CpuFeatures::IsSupported(VFP2)); if (use_eabi_hardfloat()) { if (dreg2.is(d0)) { ASSERT(!dreg1.is(d1)); @@ -3360,6 +3363,7 @@ void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg1, void MacroAssembler::SetCallCDoubleArguments(DoubleRegister dreg, Register reg) { + ASSERT(CpuFeatures::IsSupported(VFP2)); if (use_eabi_hardfloat()) { Move(d0, dreg); Move(r0, reg); diff --git a/deps/v8/src/arm/stub-cache-arm.cc b/deps/v8/src/arm/stub-cache-arm.cc index dd9de23fa45..d5e312de5cd 100644 --- a/deps/v8/src/arm/stub-cache-arm.cc +++ b/deps/v8/src/arm/stub-cache-arm.cc @@ -986,8 +986,8 @@ static void StoreIntAsFloat(MacroAssembler* masm, Register fval, Register scratch1, Register scratch2) { - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ vmov(s0, ival); __ add(scratch1, dst, Operand(wordoffset, LSL, 2)); __ vcvt_f32_s32(s0, s0); @@ -2089,11 +2089,11 @@ Handle CallStubCompiler::CompileMathFloorCall( // -- sp[argc * 4] : receiver // ----------------------------------- - if (!CpuFeatures::IsSupported(VFP3)) { + if (!CpuFeatures::IsSupported(VFP2)) { return Handle::null(); } - CpuFeatures::Scope scope_vfp3(VFP3); + CpuFeatures::Scope scope_vfp2(VFP2); const int argc = arguments().immediate(); // If the object is not a JSObject or we got an unexpected number of // arguments, bail out to the regular call. @@ -3549,8 +3549,8 @@ static void GenerateSmiKeyCheck(MacroAssembler* masm, Register scratch1, DwVfpRegister double_scratch0, Label* fail) { - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); Label key_ok; // Check for smi or a smi inside a heap number. We convert the heap // number and check if the conversion is exact and fits into the smi @@ -3636,8 +3636,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ ldr(value, MemOperand(r3, key, LSL, 1)); break; case EXTERNAL_FLOAT_ELEMENTS: - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ add(r2, r3, Operand(key, LSL, 1)); __ vldr(s0, r2, 0); } else { @@ -3645,8 +3645,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( } break; case EXTERNAL_DOUBLE_ELEMENTS: - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ add(r2, r3, Operand(key, LSL, 2)); __ vldr(d0, r2, 0); } else { @@ -3697,8 +3697,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // Now we can use r0 for the result as key is not needed any more. __ mov(r0, r5); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ vmov(s0, value); __ vcvt_f64_s32(d0, s0); __ sub(r3, r0, Operand(kHeapObjectTag)); @@ -3725,8 +3725,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( // The test is different for unsigned int values. Since we need // the value to be in the range of a positive smi, we can't // handle either of the top two bits being set in the value. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); Label box_int, done; __ tst(value, Operand(0xC0000000)); __ b(ne, &box_int); @@ -3789,8 +3789,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { // For the floating-point array type, we need to always allocate a // HeapNumber. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Allocate a HeapNumber for the result. Don't use r0 and r1 as // AllocateHeapNumber clobbers all registers - also when jumping due to // exhausted young space. @@ -3857,8 +3857,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray( __ Ret(); } } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); // Allocate a HeapNumber for the result. Don't use r0 and r1 as // AllocateHeapNumber clobbers all registers - also when jumping due to // exhausted young space. @@ -3983,7 +3983,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( __ add(r3, r3, Operand(key, LSL, 2)); // r3: effective address of the double element FloatingPointHelper::Destination destination; - if (CpuFeatures::IsSupported(VFP3)) { + if (CpuFeatures::IsSupported(VFP2)) { destination = FloatingPointHelper::kVFPRegisters; } else { destination = FloatingPointHelper::kCoreRegisters; @@ -3993,7 +3993,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( d0, r6, r7, // These are: double_dst, dst1, dst2. r4, s2); // These are: scratch2, single_scratch. if (destination == FloatingPointHelper::kVFPRegisters) { - CpuFeatures::Scope scope(VFP3); + CpuFeatures::Scope scope(VFP2); __ vstr(d0, r3, 0); } else { __ str(r6, MemOperand(r3, 0)); @@ -4028,8 +4028,8 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray( // The WebGL specification leaves the behavior of storing NaN and // +/-Infinity into integer arrays basically undefined. For more // reproducible behavior, convert these to zero. - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { // vldr requires offset to be a multiple of 4 so we can not diff --git a/deps/v8/src/flag-definitions.h b/deps/v8/src/flag-definitions.h index 2b4c53cd2de..6bb1507da24 100644 --- a/deps/v8/src/flag-definitions.h +++ b/deps/v8/src/flag-definitions.h @@ -263,7 +263,9 @@ DEFINE_bool(enable_sahf, true, "enable use of SAHF instruction if available (X64 only)") DEFINE_bool(enable_vfp3, true, "enable use of VFP3 instructions if available - this implies " - "enabling ARMv7 instructions (ARM only)") + "enabling ARMv7 and VFP2 instructions (ARM only)") +DEFINE_bool(enable_vfp2, true, + "enable use of VFP2 instructions if available") DEFINE_bool(enable_armv7, true, "enable use of ARMv7 instructions if available (ARM only)") DEFINE_bool(enable_fpu, true, diff --git a/deps/v8/src/platform-linux.cc b/deps/v8/src/platform-linux.cc index f6db423e427..ed9eb790846 100644 --- a/deps/v8/src/platform-linux.cc +++ b/deps/v8/src/platform-linux.cc @@ -132,6 +132,9 @@ bool OS::ArmCpuHasFeature(CpuFeature feature) { // facility is universally available on the ARM architectures, // so it's up to individual OSes to provide such. switch (feature) { + case VFP2: + search_string = "vfp"; + break; case VFP3: search_string = "vfpv3"; break; diff --git a/deps/v8/src/v8globals.h b/deps/v8/src/v8globals.h index 6a1766a1a58..4dec1830d94 100644 --- a/deps/v8/src/v8globals.h +++ b/deps/v8/src/v8globals.h @@ -442,6 +442,7 @@ enum CpuFeature { SSE4_1 = 32 + 19, // x86 CPUID = 10, // x86 VFP3 = 1, // ARM ARMv7 = 2, // ARM + VFP2 = 3, // ARM SAHF = 0, // x86 FPU = 1}; // MIPS diff --git a/deps/v8/test/cctest/test-assembler-arm.cc b/deps/v8/test/cctest/test-assembler-arm.cc index ecbf9569160..cdab1b95ce2 100644 --- a/deps/v8/test/cctest/test-assembler-arm.cc +++ b/deps/v8/test/cctest/test-assembler-arm.cc @@ -1,4 +1,4 @@ -// Copyright 2011 the V8 project authors. All rights reserved. +// Copyright 2012 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -642,8 +642,8 @@ TEST(8) { // single precision values around in memory. Assembler assm(Isolate::Current(), NULL, 0); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ mov(ip, Operand(sp)); __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); @@ -753,8 +753,8 @@ TEST(9) { // single precision values around in memory. Assembler assm(Isolate::Current(), NULL, 0); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ mov(ip, Operand(sp)); __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit()); @@ -868,8 +868,8 @@ TEST(10) { // single precision values around in memory. Assembler assm(Isolate::Current(), NULL, 0); - if (CpuFeatures::IsSupported(VFP3)) { - CpuFeatures::Scope scope(VFP3); + if (CpuFeatures::IsSupported(VFP2)) { + CpuFeatures::Scope scope(VFP2); __ mov(ip, Operand(sp)); __ stm(db_w, sp, r4.bit() | fp.bit() | lr.bit());