Index: src/arm/assembler-arm.cc |
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc |
index b0fa462c9fe81f1f10b7a8b4e11d0c331303840b..c2092b42c87f903189c20ad8eb00809112e37620 100644 |
--- a/src/arm/assembler-arm.cc |
+++ b/src/arm/assembler-arm.cc |
@@ -2546,12 +2546,6 @@ void Assembler::vstm(BlockAddrMode am, |
} |
-void Assembler::vmov(const SwVfpRegister dst, float imm) { |
- mov(ip, Operand(bit_cast<int32_t>(imm))); |
- vmov(dst, ip); |
-} |
- |
- |
static void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) { |
uint64_t i; |
memcpy(&i, &d, 8); |
@@ -2563,7 +2557,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) { |
+static bool FitsVmovFPImmediate(double d, uint32_t* encoding) { |
DCHECK(CpuFeatures::IsSupported(VFP3)); |
// VMOV can accept an immediate of the form: |
@@ -2592,12 +2586,12 @@ static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { |
return false; |
} |
- // Bits 62:55 must be all clear or all set. |
+ // Bits 61:54 must be all clear or all set. |
if (((hi & 0x3fc00000) != 0) && ((hi & 0x3fc00000) != 0x3fc00000)) { |
return false; |
} |
- // Bit 63 must be NOT bit 62. |
+ // Bit 62 must be NOT bit 61. |
if (((hi ^ (hi << 1)) & (0x40000000)) == 0) { |
return false; |
} |
@@ -2612,6 +2606,25 @@ static bool FitsVMOVDoubleImmediate(double d, uint32_t *encoding) { |
} |
+void Assembler::vmov(const SwVfpRegister dst, float imm) { |
+ uint32_t enc; |
+ if (CpuFeatures::IsSupported(VFP3) && FitsVmovFPImmediate(imm, &enc)) { |
+ // The float can be encoded in the instruction. |
+ // |
+ // Sd = immediate |
+ // Instruction details available in ARM DDI 0406C.b, A8-936. |
+ // cond(31-28) | 11101(27-23) | D(22) | 11(21-20) | imm4H(19-16) | |
+ // Vd(15-12) | 101(11-9) | sz=0(8) | imm4L(3-0) |
+ int vd, d; |
+ dst.split_code(&vd, &d); |
+ emit(al | 0x1D * B23 | d * B22 | 0x3 * B20 | vd * B12 | 0x5 * B9 | enc); |
+ } else { |
+ mov(ip, Operand(bit_cast<int32_t>(imm))); |
+ vmov(dst, ip); |
+ } |
+} |
+ |
+ |
void Assembler::vmov(const DwVfpRegister dst, |
double imm, |
const Register scratch) { |
@@ -2622,7 +2635,7 @@ void Assembler::vmov(const DwVfpRegister dst, |
// pointer (pp) is valid. |
bool can_use_pool = |
!FLAG_enable_embedded_constant_pool || is_constant_pool_available(); |
- if (CpuFeatures::IsSupported(VFP3) && FitsVMOVDoubleImmediate(imm, &enc)) { |
+ if (CpuFeatures::IsSupported(VFP3) && FitsVmovFPImmediate(imm, &enc)) { |
// The double can be encoded in the instruction. |
// |
// Dd = immediate |