Relax requirement from VFP3 to VFP2 where possible.
BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/10818026 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12194 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
abede994d9
commit
59f212e7eb
@ -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',
|
||||
@ -132,9 +133,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"', {
|
||||
|
@ -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;
|
||||
}
|
||||
@ -81,7 +84,7 @@ static uint64_t CpuFeaturesImpliedByCompiler() {
|
||||
|
||||
void CpuFeatures::Probe() {
|
||||
unsigned standard_features = static_cast<unsigned>(
|
||||
OS::CpuFeaturesImpliedByPlatform() | CpuFeaturesImpliedByCompiler());
|
||||
OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
|
||||
ASSERT(supported_ == 0 || supported_ == standard_features);
|
||||
#ifdef DEBUG
|
||||
initialized_ = true;
|
||||
@ -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));
|
||||
@ -1848,7 +1856,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));
|
||||
@ -1869,7 +1877,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));
|
||||
@ -1890,7 +1898,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));
|
||||
@ -1913,7 +1921,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:
|
||||
//
|
||||
@ -1966,10 +1974,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 {
|
||||
@ -2003,7 +2011,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);
|
||||
@ -2016,7 +2024,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());
|
||||
}
|
||||
@ -2030,7 +2038,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());
|
||||
@ -2045,7 +2053,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());
|
||||
@ -2059,7 +2067,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);
|
||||
@ -2074,7 +2082,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);
|
||||
@ -2199,7 +2207,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));
|
||||
}
|
||||
|
||||
@ -2208,7 +2216,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));
|
||||
}
|
||||
|
||||
@ -2217,7 +2225,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));
|
||||
}
|
||||
|
||||
@ -2226,7 +2234,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));
|
||||
}
|
||||
|
||||
@ -2235,7 +2243,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));
|
||||
}
|
||||
|
||||
@ -2244,7 +2252,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));
|
||||
}
|
||||
|
||||
@ -2253,7 +2261,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));
|
||||
}
|
||||
|
||||
@ -2261,6 +2269,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());
|
||||
}
|
||||
@ -2269,6 +2278,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());
|
||||
}
|
||||
@ -2283,7 +2293,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());
|
||||
}
|
||||
@ -2298,7 +2308,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());
|
||||
}
|
||||
@ -2313,7 +2323,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());
|
||||
}
|
||||
@ -2328,7 +2338,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());
|
||||
}
|
||||
@ -2341,7 +2351,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());
|
||||
}
|
||||
@ -2354,7 +2364,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);
|
||||
@ -2365,7 +2375,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);
|
||||
}
|
||||
@ -2375,7 +2385,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);
|
||||
}
|
||||
@ -2386,7 +2396,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());
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1283,10 +1283,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.
|
||||
|
@ -599,8 +599,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());
|
||||
@ -669,9 +669,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);
|
||||
@ -684,8 +684,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());
|
||||
@ -762,8 +762,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) {
|
||||
@ -856,8 +856,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);
|
||||
@ -927,8 +927,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));
|
||||
@ -1058,7 +1058,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);
|
||||
}
|
||||
@ -1070,7 +1070,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 {
|
||||
@ -1289,9 +1289,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));
|
||||
@ -1329,8 +1329,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);
|
||||
@ -1442,7 +1442,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);
|
||||
}
|
||||
@ -1517,8 +1517,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));
|
||||
@ -1607,8 +1607,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,
|
||||
@ -1739,9 +1739,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);
|
||||
@ -1860,7 +1860,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;
|
||||
@ -1972,7 +1972,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);
|
||||
@ -1990,7 +1990,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));
|
||||
@ -2220,9 +2220,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));
|
||||
@ -2522,7 +2522,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;
|
||||
@ -2549,7 +2549,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);
|
||||
@ -2638,7 +2638,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);
|
||||
@ -2677,10 +2677,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);
|
||||
@ -2839,7 +2839,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;
|
||||
|
||||
@ -2867,7 +2867,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:
|
||||
@ -3034,9 +3034,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);
|
||||
@ -3071,8 +3071,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);
|
||||
@ -3301,8 +3301,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.
|
||||
@ -3403,8 +3403,8 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
|
||||
ExternalReference(RuntimeFunction(), masm->isolate());
|
||||
__ TailCallExternalReference(runtime_function, 1, 1);
|
||||
} else {
|
||||
ASSERT(CpuFeatures::IsSupported(VFP3));
|
||||
CpuFeatures::Scope scope(VFP3);
|
||||
ASSERT(CpuFeatures::IsSupported(VFP2));
|
||||
CpuFeatures::Scope scope(VFP2);
|
||||
|
||||
Label no_update;
|
||||
Label skip_cache;
|
||||
@ -3465,6 +3465,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
|
||||
|
||||
void TranscendentalCacheStub::GenerateCallCFunction(MacroAssembler* masm,
|
||||
Register scratch) {
|
||||
ASSERT(CpuFeatures::IsEnabled(VFP2));
|
||||
Isolate* isolate = masm->isolate();
|
||||
|
||||
__ push(lr);
|
||||
@ -3525,7 +3526,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;
|
||||
@ -3624,7 +3625,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);
|
||||
@ -3981,8 +3982,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.
|
||||
@ -3997,7 +3998,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));
|
||||
@ -4135,8 +4136,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);
|
||||
}
|
||||
@ -6663,8 +6664,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));
|
||||
|
@ -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<OverwriteMode, 0, 2> {};
|
||||
class OpBits: public BitField<Token::Value, 2, 7> {};
|
||||
class VFP3Bits: public BitField<bool, 9, 1> {};
|
||||
class VFP2Bits: public BitField<bool, 9, 1> {};
|
||||
class OperandTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 10, 3> {};
|
||||
class ResultTypeInfoBits: public BitField<BinaryOpIC::TypeInfo, 13, 3> {};
|
||||
|
||||
@ -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);
|
||||
|
@ -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.
|
||||
@ -182,7 +182,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);
|
||||
|
||||
@ -210,8 +210,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);
|
||||
@ -244,7 +244,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);
|
||||
}
|
||||
|
@ -673,7 +673,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());
|
||||
@ -3050,13 +3050,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));
|
||||
@ -3179,7 +3179,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 {
|
||||
|
@ -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);
|
||||
|
@ -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<Code> CallStubCompiler::CompileMathFloorCall(
|
||||
// -- sp[argc * 4] : receiver
|
||||
// -----------------------------------
|
||||
|
||||
if (!CpuFeatures::IsSupported(VFP3)) {
|
||||
if (!CpuFeatures::IsSupported(VFP2)) {
|
||||
return Handle<Code>::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.
|
||||
@ -3554,8 +3554,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
|
||||
@ -3641,8 +3641,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 {
|
||||
@ -3650,8 +3650,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 {
|
||||
@ -3702,8 +3702,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));
|
||||
@ -3730,8 +3730,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);
|
||||
@ -3794,8 +3794,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.
|
||||
@ -3862,8 +3862,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.
|
||||
@ -3988,7 +3988,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;
|
||||
@ -3998,7 +3998,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));
|
||||
@ -4033,8 +4033,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
|
||||
|
@ -274,7 +274,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,
|
||||
|
@ -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;
|
||||
|
@ -436,6 +436,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
|
||||
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user