diff options
Diffstat (limited to 'chromium/v8/src/execution/arm')
-rw-r--r-- | chromium/v8/src/execution/arm/simulator-arm.cc | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/chromium/v8/src/execution/arm/simulator-arm.cc b/chromium/v8/src/execution/arm/simulator-arm.cc index 019542b12d4..ddfc5650b56 100644 --- a/chromium/v8/src/execution/arm/simulator-arm.cc +++ b/chromium/v8/src/execution/arm/simulator-arm.cc @@ -1567,7 +1567,7 @@ using SimulatorRuntimeDirectGetterCall = void (*)(int32_t arg0, int32_t arg1); using SimulatorRuntimeProfilingGetterCall = void (*)(int32_t arg0, int32_t arg1, void* arg2); -// Separate for fine-grained UBSan blacklisting. Casting any given C++ +// Separate for fine-grained UBSan blocklisting. Casting any given C++ // function to {SimulatorRuntimeCall} is undefined behavior; but since // the target function can indeed be any function that's exposed via // the "fast C call" mechanism, we can't reconstruct its signature here. @@ -5375,7 +5375,8 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { } else { UNIMPLEMENTED(); } - } else if (instr->Bits(19, 18) == 0x2 && instr->Bits(11, 8) == 0x5) { + } else if (instr->Bits(19, 18) == 0x2 && instr->Bits(17, 16) == 0x3 && + instr->Bits(11, 8) == 0x5) { // vrecpe/vrsqrte.f32 Qd, Qm. int Vd = instr->VFPDRegValue(kSimd128Precision); int Vm = instr->VFPMRegValue(kSimd128Precision); @@ -5442,6 +5443,39 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { UNIMPLEMENTED(); break; } + } else if (instr->Bits(17, 16) == 0x2 && instr->Bit(10) == 1) { + // vrint<q>.<dt> <Dd>, <Dm> + // vrint<q>.<dt> <Qd>, <Qm> + // See F6.1.205 + int regs = instr->Bit(6) + 1; + int rounding_mode = instr->Bits(9, 7); + float (*fproundint)(float) = nullptr; + switch (rounding_mode) { + case 3: + fproundint = &truncf; + break; + case 5: + fproundint = &floorf; + break; + case 7: + fproundint = &ceilf; + break; + default: + UNIMPLEMENTED(); + } + int vm = instr->VFPMRegValue(kDoublePrecision); + int vd = instr->VFPDRegValue(kDoublePrecision); + + float floats[2]; + for (int r = 0; r < regs; r++) { + // We cannot simply use GetVFPSingleValue since our Q registers + // might not map to any S registers at all. + get_neon_register<float, kDoubleSize>(vm + r, floats); + for (int e = 0; e < 2; e++) { + floats[e] = canonicalizeNaN(fproundint(floats[e])); + } + set_neon_register<float, kDoubleSize>(vd + r, floats); + } } else { UNIMPLEMENTED(); } @@ -5658,12 +5692,12 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { int32_t address = get_register(Rn); int regs = instr->Bit(5) + 1; int size = instr->Bits(7, 6); - uint32_t q_data[4]; + uint32_t q_data[2]; switch (size) { case Neon8: { uint8_t data = ReadBU(address); uint8_t* dst = reinterpret_cast<uint8_t*>(q_data); - for (int i = 0; i < 16; i++) { + for (int i = 0; i < 8; i++) { dst[i] = data; } break; @@ -5671,21 +5705,21 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { case Neon16: { uint16_t data = ReadHU(address); uint16_t* dst = reinterpret_cast<uint16_t*>(q_data); - for (int i = 0; i < 8; i++) { + for (int i = 0; i < 4; i++) { dst[i] = data; } break; } case Neon32: { uint32_t data = ReadW(address); - for (int i = 0; i < 4; i++) { + for (int i = 0; i < 2; i++) { q_data[i] = data; } break; } } for (int r = 0; r < regs; r++) { - set_neon_register(Vd + r, q_data); + set_neon_register<uint32_t, kDoubleSize>(Vd + r, q_data); } if (Rm != 15) { if (Rm == 13) { |