| Index: src/arm/simulator-arm.cc
|
| diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
|
| index c1e6fc1f4db743a152e0952b8ae16ea55a98fa41..f4d0bbbc363eba43b3d2b8f5ade7aab65aa62d47 100644
|
| --- a/src/arm/simulator-arm.cc
|
| +++ b/src/arm/simulator-arm.cc
|
| @@ -4273,6 +4273,20 @@ void PairwiseMinMax(Simulator* simulator, int Vd, int Vm, int Vn, bool min) {
|
| simulator->set_neon_register<T, kDoubleSize>(Vd, dst);
|
| }
|
|
|
| +template <typename T>
|
| +void PairwiseAdd(Simulator* simulator, int Vd, int Vm, int Vn) {
|
| + static const int kElems = kDoubleSize / sizeof(T);
|
| + static const int kPairs = kElems / 2;
|
| + T dst[kElems], src1[kElems], src2[kElems];
|
| + simulator->get_neon_register<T, kDoubleSize>(Vn, src1);
|
| + simulator->get_neon_register<T, kDoubleSize>(Vm, src2);
|
| + for (int i = 0; i < kPairs; i++) {
|
| + dst[i] = src1[i * 2] + src1[i * 2 + 1];
|
| + dst[i + kPairs] = src2[i * 2] + src2[i * 2 + 1];
|
| + }
|
| + simulator->set_neon_register<T, kDoubleSize>(Vd, dst);
|
| +}
|
| +
|
| void Simulator::DecodeSpecialCondition(Instruction* instr) {
|
| switch (instr->SpecialValue()) {
|
| case 4: {
|
| @@ -4484,6 +4498,25 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
|
| }
|
| break;
|
| }
|
| + case 0xb: {
|
| + // vpadd.i<size> Dd, Dm, Dn.
|
| + NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20));
|
| + switch (size) {
|
| + case Neon8:
|
| + PairwiseAdd<int8_t>(this, Vd, Vm, Vn);
|
| + break;
|
| + case Neon16:
|
| + PairwiseAdd<int16_t>(this, Vd, Vm, Vn);
|
| + break;
|
| + case Neon32:
|
| + PairwiseAdd<int32_t>(this, Vd, Vm, Vn);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + break;
|
| + }
|
| case 0xd: {
|
| if (instr->Bit(4) == 0) {
|
| float src1[4], src2[4];
|
| @@ -4832,7 +4865,8 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
|
| break;
|
| }
|
| case 0xd: {
|
| - if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) {
|
| + if (instr->Bits(21, 20) == 0 && instr->Bit(6) == 1 &&
|
| + instr->Bit(4) == 1) {
|
| // vmul.f32 Qd, Qn, Qm
|
| float src1[4], src2[4];
|
| get_neon_register(Vn, src1);
|
| @@ -4841,6 +4875,10 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
|
| src1[i] = src1[i] * src2[i];
|
| }
|
| set_neon_register(Vd, src1);
|
| + } else if (instr->Bits(21, 20) == 0 && instr->Bit(6) == 0 &&
|
| + instr->Bit(4) == 0) {
|
| + // vpadd.f32 Dd, Dn, Dm
|
| + PairwiseAdd<float>(this, Vd, Vm, Vn);
|
| } else {
|
| UNIMPLEMENTED();
|
| }
|
|
|