Index: src/arm/simulator-arm.cc |
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc |
index fae282207aac85f6133cb6d517d9c671cbfb0f9d..af396d2e90283359512986fb8e97f565004ace18 100644 |
--- a/src/arm/simulator-arm.cc |
+++ b/src/arm/simulator-arm.cc |
@@ -3997,7 +3997,29 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
: 0; |
} |
set_q_register(Vd, src1); |
- |
+ } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xf && |
+ instr->Bit(6) == 1 && instr->Bit(4) == 1) { |
+ int Vd = instr->VFPDRegValue(kSimd128Precision); |
+ int Vm = instr->VFPMRegValue(kSimd128Precision); |
+ int Vn = instr->VFPNRegValue(kSimd128Precision); |
+ uint32_t src1[4], src2[4]; |
+ get_q_register(Vn, src1); |
+ get_q_register(Vm, src2); |
+ if (instr->Bit(21) == 0) { |
+ // vrecps.f32 Qd, Qm, Qn. |
+ for (int i = 0; i < 4; i++) { |
+ src1[i] = bit_cast<uint32_t>( |
+ 2.0f - bit_cast<float>(src1[i]) * bit_cast<float>(src2[i])); |
+ } |
+ } else { |
+ // vrsqrts.f32 Qd, Qm, Qn. |
+ for (int i = 0; i < 4; i++) { |
+ src1[i] = bit_cast<uint32_t>( |
+ (3.0f - bit_cast<float>(src1[i]) * bit_cast<float>(src2[i])) / |
+ 2); |
+ } |
+ } |
+ set_q_register(Vd, src1); |
} else { |
UNIMPLEMENTED(); |
} |
@@ -4507,6 +4529,30 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
UNIMPLEMENTED(); |
} |
set_q_register(Vd, src); |
+ } else if (instr->Bits(19, 18) == 0x2 && instr->Bits(11, 8) == 0x5) { |
+ // vrecpe/vrsqrte.f32 Qd, Qm. |
+ int Vd = instr->VFPDRegValue(kSimd128Precision); |
+ int Vm = instr->VFPMRegValue(kSimd128Precision); |
+ uint32_t src[4]; |
+ get_q_register(Vm, src); |
+ if (instr->Bit(7) == 0) { |
+ for (int i = 0; i < 4; i++) { |
+ float denom = bit_cast<float>(src[i]); |
+ div_zero_vfp_flag_ = (denom == 0); |
+ float result = 1.0f / denom; |
+ result = canonicalizeNaN(result); |
+ src[i] = bit_cast<uint32_t>(result); |
+ } |
+ } else { |
+ lazily_initialize_fast_sqrt(isolate_); |
+ for (int i = 0; i < 4; i++) { |
+ float radicand = bit_cast<float>(src[i]); |
+ float result = 1.0f / fast_sqrt(radicand, isolate_); |
+ result = canonicalizeNaN(result); |
+ src[i] = bit_cast<uint32_t>(result); |
+ } |
+ } |
+ set_q_register(Vd, src); |
} else { |
UNIMPLEMENTED(); |
} |