Chromium Code Reviews| Index: src/arm/simulator-arm.cc |
| diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc |
| index fae282207aac85f6133cb6d517d9c671cbfb0f9d..25d85789fcf04935f79035424cb3a9524fe553a4 100644 |
| --- a/src/arm/simulator-arm.cc |
| +++ b/src/arm/simulator-arm.cc |
| @@ -3852,7 +3852,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| set_q_register(Vd, data); |
| } else if (instr->Bits(11, 8) == 8) { |
| // vadd/vtst |
| - int size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| int Vn = instr->VFPNRegValue(kSimd128Precision); |
| @@ -3985,6 +3985,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| set_q_register(Vd, src1); |
| } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 0xe && |
| instr->Bit(4) == 0) { |
| + // vceq.f32 Qd, Qm, Qn |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| int Vn = instr->VFPNRegValue(kSimd128Precision); |
| @@ -3998,6 +3999,57 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| } |
| set_q_register(Vd, src1); |
| + } else if (instr->Bits(11, 8) == 0x3) { |
| + // vcge/vcgt.s<size> Qd, Qm, Qn. |
| + bool ge = instr->Bit(4) == 1; |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| + 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); |
| + switch (size) { |
| + case Neon8: { |
| + int8_t* s1 = reinterpret_cast<int8_t*>(src1); |
|
martyn.capewell
2017/01/06 19:10:21
It's worth implementing some new get/set_q_registe
bbudge
2017/01/10 11:17:51
Yes, good idea. Done.
|
| + int8_t* s2 = reinterpret_cast<int8_t*>(src2); |
| + for (int i = 0; i < 16; i++) { |
| + if (ge) |
| + s1[i] = s1[i] >= s2[i] ? 0xFF : 0; |
| + else |
| + s1[i] = s1[i] > s2[i] ? 0xFF : 0; |
| + } |
| + break; |
| + } |
| + case Neon16: { |
| + int16_t s1[8], s2[8]; |
| + memcpy(s1, src1, sizeof(s1)); |
| + memcpy(s2, src2, sizeof(s2)); |
| + for (int i = 0; i < 8; i++) { |
| + if (ge) |
| + s1[i] = s1[i] >= s2[i] ? 0xffffu : 0; |
| + else |
| + s1[i] = s1[i] > s2[i] ? 0xffffu : 0; |
| + } |
| + memcpy(src1, s1, sizeof(src1)); |
| + break; |
| + } |
| + case Neon32: { |
| + int32_t* s1 = reinterpret_cast<int32_t*>(src1); |
| + int32_t* s2 = reinterpret_cast<int32_t*>(src2); |
| + for (int i = 0; i < 4; i++) { |
| + if (ge) |
| + s1[i] = s1[i] >= s2[i] ? 0xFFFFFFFF : 0; |
| + else |
| + s1[i] = s1[i] > s2[i] ? 0xFFFFFFFF : 0; |
| + } |
| + break; |
| + } |
| + default: |
| + UNREACHABLE(); |
| + break; |
| + } |
| + set_q_register(Vd, src1); |
| } else { |
| UNIMPLEMENTED(); |
| } |
| @@ -4050,7 +4102,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| case 6: |
| if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) { |
| // vsub.size Qd, Qm, Qn. |
| - int size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| int Vn = instr->VFPNRegValue(kSimd128Precision); |
| @@ -4089,7 +4141,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| set_q_register(Vd, src1); |
| } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) { |
| // vceq.size Qd, Qm, Qn. |
| - int size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| int Vn = instr->VFPNRegValue(kSimd128Precision); |
| @@ -4178,6 +4230,78 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| bit_cast<float>(src2[i])); |
| } |
| set_q_register(Vd, src1); |
| + } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xe && |
| + instr->Bit(4) == 0) { |
| + // vcge/vcgt.f32 Qd, Qm, Qn |
| + bool ge = instr->Bit(21) == 0; |
| + 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); |
| + for (int i = 0; i < 4; i++) { |
| + if (ge) { |
| + src1[i] = bit_cast<float>(src1[i]) >= bit_cast<float>(src2[i]) |
| + ? 0xFFFFFFFF |
| + : 0; |
| + } else { |
| + src1[i] = bit_cast<float>(src1[i]) > bit_cast<float>(src2[i]) |
| + ? 0xFFFFFFFF |
| + : 0; |
| + } |
| + } |
| + set_q_register(Vd, src1); |
| + |
| + } else if (instr->Bits(11, 8) == 0x3) { |
| + // vcge/vcgt.u<size> Qd, Qm, Qn. |
| + bool ge = instr->Bit(4) == 1; |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| + 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); |
| + switch (size) { |
| + case Neon8: { |
| + uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); |
| + uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); |
| + for (int i = 0; i < 16; i++) { |
| + if (ge) |
| + s1[i] = s1[i] >= s2[i] ? 0xFF : 0; |
| + else |
| + s1[i] = s1[i] > s2[i] ? 0xFF : 0; |
| + } |
| + break; |
| + } |
| + case Neon16: { |
| + uint16_t s1[8], s2[8]; |
| + memcpy(s1, src1, sizeof(s1)); |
| + memcpy(s2, src2, sizeof(s2)); |
| + for (int i = 0; i < 8; i++) { |
| + if (ge) |
| + s1[i] = s1[i] >= s2[i] ? 0xffffu : 0; |
| + else |
| + s1[i] = s1[i] > s2[i] ? 0xffffu : 0; |
| + } |
| + memcpy(src1, s1, sizeof(src1)); |
| + break; |
| + } |
| + case Neon32: { |
| + for (int i = 0; i < 4; i++) { |
| + if (ge) |
| + src1[i] = src1[i] >= src2[i] ? 0xFFFFFFFF : 0; |
| + else |
| + src1[i] = src1[i] > src2[i] ? 0xFFFFFFFF : 0; |
| + } |
| + break; |
| + } |
| + default: |
| + UNREACHABLE(); |
| + break; |
| + } |
| + set_q_register(Vd, src1); |
| } else { |
| UNIMPLEMENTED(); |
| } |
| @@ -4299,7 +4423,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| set_d_register(vd, &result); |
| } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x7) { |
| // vzip.<size> Qd, Qm. |
| - int size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| uint32_t src1[4], src2[4], dst1[4], dst2[4]; |
| @@ -4352,7 +4476,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| // vrev<op>.size Qd, Qm |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| - int size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| NeonSize op = static_cast<NeonSize>(static_cast<int>(Neon64) - |
| instr->Bits(8, 7)); |
| uint32_t src[4]; |
| @@ -4425,7 +4549,7 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) { |
| } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0) { |
| int Vd = instr->VFPDRegValue(kSimd128Precision); |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| - int size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| + NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| uint32_t src[4]; |
| get_q_register(Vm, src); |
| if (instr->Bits(9, 6) == 0xd) { |