| Index: src/arm/simulator-arm.cc
 | 
| diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
 | 
| index e2bcd952a6c08df63c8bc3565c5e7c38a170d8d4..d3247f7ac64f224436fa6adb275bdca7ce2c4fde 100644
 | 
| --- a/src/arm/simulator-arm.cc
 | 
| +++ b/src/arm/simulator-arm.cc
 | 
| @@ -5046,57 +5046,109 @@ 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.
 | 
| +        } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x1 &&
 | 
| +                   instr->Bit(6) == 1) {
 | 
|            NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18));
 | 
|            int Vd = instr->VFPDRegValue(kSimd128Precision);
 | 
|            int Vm = instr->VFPMRegValue(kSimd128Precision);
 | 
| -          switch (size) {
 | 
| -            case Neon8: {
 | 
| -              uint8_t src1[16], src2[16], dst1[16], dst2[16];
 | 
| -              get_q_register(Vd, src1);
 | 
| -              get_q_register(Vm, src2);
 | 
| -              for (int i = 0; i < 8; i++) {
 | 
| -                dst1[i * 2] = src1[i];
 | 
| -                dst1[i * 2 + 1] = src2[i];
 | 
| -                dst2[i * 2] = src1[i + 8];
 | 
| -                dst2[i * 2 + 1] = src2[i + 8];
 | 
| +          if (instr->Bit(7) == 1) {
 | 
| +            // vzip.<size> Qd, Qm.
 | 
| +            switch (size) {
 | 
| +              case Neon8: {
 | 
| +                uint8_t src1[16], src2[16], dst1[16], dst2[16];
 | 
| +                get_q_register(Vd, src1);
 | 
| +                get_q_register(Vm, src2);
 | 
| +                for (int i = 0; i < 8; i++) {
 | 
| +                  dst1[i * 2] = src1[i];
 | 
| +                  dst1[i * 2 + 1] = src2[i];
 | 
| +                  dst2[i * 2] = src1[i + 8];
 | 
| +                  dst2[i * 2 + 1] = src2[i + 8];
 | 
| +                }
 | 
| +                set_q_register(Vd, dst1);
 | 
| +                set_q_register(Vm, dst2);
 | 
| +                break;
 | 
|                }
 | 
| -              set_q_register(Vd, dst1);
 | 
| -              set_q_register(Vm, dst2);
 | 
| -              break;
 | 
| -            }
 | 
| -            case Neon16: {
 | 
| -              uint16_t src1[8], src2[8], dst1[8], dst2[8];
 | 
| -              get_q_register(Vd, src1);
 | 
| -              get_q_register(Vm, src2);
 | 
| -              for (int i = 0; i < 8; i += 2) {
 | 
| -                dst1[i] = src1[i / 2];
 | 
| -                dst1[i + 1] = src2[i / 2];
 | 
| -                dst2[i] = src1[i / 2 + 4];
 | 
| -                dst2[i + 1] = src2[i / 2 + 4];
 | 
| +              case Neon16: {
 | 
| +                uint16_t src1[8], src2[8], dst1[8], dst2[8];
 | 
| +                get_q_register(Vd, src1);
 | 
| +                get_q_register(Vm, src2);
 | 
| +                for (int i = 0; i < 4; i++) {
 | 
| +                  dst1[i * 2] = src1[i];
 | 
| +                  dst1[i * 2 + 1] = src2[i];
 | 
| +                  dst2[i * 2] = src1[i + 4];
 | 
| +                  dst2[i * 2 + 1] = src2[i + 4];
 | 
| +                }
 | 
| +                set_q_register(Vd, dst1);
 | 
| +                set_q_register(Vm, dst2);
 | 
| +                break;
 | 
|                }
 | 
| -              set_q_register(Vd, dst1);
 | 
| -              set_q_register(Vm, dst2);
 | 
| -              break;
 | 
| +              case Neon32: {
 | 
| +                uint32_t src1[4], src2[4], dst1[4], dst2[4];
 | 
| +                get_q_register(Vd, src1);
 | 
| +                get_q_register(Vm, src2);
 | 
| +                for (int i = 0; i < 2; i++) {
 | 
| +                  dst1[i * 2] = src1[i];
 | 
| +                  dst1[i * 2 + 1] = src2[i];
 | 
| +                  dst2[i * 2] = src1[i + 2];
 | 
| +                  dst2[i * 2 + 1] = src2[i + 2];
 | 
| +                }
 | 
| +                set_q_register(Vd, dst1);
 | 
| +                set_q_register(Vm, dst2);
 | 
| +                break;
 | 
| +              }
 | 
| +              default:
 | 
| +                UNREACHABLE();
 | 
| +                break;
 | 
|              }
 | 
| -            case Neon32: {
 | 
| -              uint32_t src1[4], src2[4], dst1[4], dst2[4];
 | 
| -              get_q_register(Vd, src1);
 | 
| -              get_q_register(Vm, src2);
 | 
| -              for (int i = 0; i < 2; i++) {
 | 
| -                dst1[i * 2] = src1[i];
 | 
| -                dst1[i * 2 + 1] = src2[i];
 | 
| -                dst2[i * 2] = src1[i + 2];
 | 
| -                dst2[i * 2 + 1] = src2[i + 2];
 | 
| +          } else {
 | 
| +            // vuzp.<size> Qd, Qm.
 | 
| +            switch (size) {
 | 
| +              case Neon8: {
 | 
| +                uint8_t src1[16], src2[16], dst1[16], dst2[16];
 | 
| +                get_q_register(Vd, src1);
 | 
| +                get_q_register(Vm, src2);
 | 
| +                for (int i = 0; i < 8; i++) {
 | 
| +                  dst1[i] = src1[i * 2];
 | 
| +                  dst1[i + 8] = src2[i * 2];
 | 
| +                  dst2[i] = src1[i * 2 + 1];
 | 
| +                  dst2[i + 8] = src2[i * 2 + 1];
 | 
| +                }
 | 
| +                set_q_register(Vd, dst1);
 | 
| +                set_q_register(Vm, dst2);
 | 
| +                break;
 | 
|                }
 | 
| -              set_q_register(Vd, dst1);
 | 
| -              set_q_register(Vm, dst2);
 | 
| -              break;
 | 
| +              case Neon16: {
 | 
| +                uint16_t src1[8], src2[8], dst1[8], dst2[8];
 | 
| +                get_q_register(Vd, src1);
 | 
| +                get_q_register(Vm, src2);
 | 
| +                for (int i = 0; i < 4; i++) {
 | 
| +                  dst1[i] = src1[i * 2];
 | 
| +                  dst1[i + 4] = src2[i * 2];
 | 
| +                  dst2[i] = src1[i * 2 + 1];
 | 
| +                  dst2[i + 4] = src2[i * 2 + 1];
 | 
| +                }
 | 
| +                set_q_register(Vd, dst1);
 | 
| +                set_q_register(Vm, dst2);
 | 
| +                break;
 | 
| +              }
 | 
| +              case Neon32: {
 | 
| +                uint32_t src1[4], src2[4], dst1[4], dst2[4];
 | 
| +                get_q_register(Vd, src1);
 | 
| +                get_q_register(Vm, src2);
 | 
| +                for (int i = 0; i < 2; i++) {
 | 
| +                  dst1[i] = src1[i * 2];
 | 
| +                  dst1[i + 2] = src2[i * 2];
 | 
| +                  dst2[i] = src1[i * 2 + 1];
 | 
| +                  dst2[i + 2] = src2[i * 2 + 1];
 | 
| +                }
 | 
| +                set_q_register(Vd, dst1);
 | 
| +                set_q_register(Vm, dst2);
 | 
| +                break;
 | 
| +              }
 | 
| +              default:
 | 
| +                UNREACHABLE();
 | 
| +                break;
 | 
|              }
 | 
| -            default:
 | 
| -              UNREACHABLE();
 | 
| -              break;
 | 
|            }
 | 
|          } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0) {
 | 
|            // vrev<op>.size Qd, Qm
 | 
| @@ -5183,6 +5235,49 @@ void Simulator::DecodeSpecialCondition(Instruction* instr) {
 | 
|                UNREACHABLE();
 | 
|                break;
 | 
|            }
 | 
| +        } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x3) {
 | 
| +          int Vd = instr->VFPDRegValue(kSimd128Precision);
 | 
| +          int Vm = instr->VFPMRegValue(kSimd128Precision);
 | 
| +          NeonSize size = static_cast<NeonSize>(instr->Bits(19, 18));
 | 
| +          // vtrn.<size> Qd, Qm.
 | 
| +          switch (size) {
 | 
| +            case Neon8: {
 | 
| +              uint8_t src[16], dst[16];
 | 
| +              get_q_register(Vd, dst);
 | 
| +              get_q_register(Vm, src);
 | 
| +              for (int i = 0; i < 8; i++) {
 | 
| +                std::swap(dst[2 * i + 1], src[2 * i]);
 | 
| +              }
 | 
| +              set_q_register(Vd, dst);
 | 
| +              set_q_register(Vm, src);
 | 
| +              break;
 | 
| +            }
 | 
| +            case Neon16: {
 | 
| +              uint16_t src[8], dst[8];
 | 
| +              get_q_register(Vd, dst);
 | 
| +              get_q_register(Vm, src);
 | 
| +              for (int i = 0; i < 4; i++) {
 | 
| +                std::swap(dst[2 * i + 1], src[2 * i]);
 | 
| +              }
 | 
| +              set_q_register(Vd, dst);
 | 
| +              set_q_register(Vm, src);
 | 
| +              break;
 | 
| +            }
 | 
| +            case Neon32: {
 | 
| +              uint32_t src[4], dst[4];
 | 
| +              get_q_register(Vd, dst);
 | 
| +              get_q_register(Vm, src);
 | 
| +              for (int i = 0; i < 2; i++) {
 | 
| +                std::swap(dst[2 * i + 1], src[2 * i]);
 | 
| +              }
 | 
| +              set_q_register(Vd, dst);
 | 
| +              set_q_register(Vm, src);
 | 
| +              break;
 | 
| +            }
 | 
| +            default:
 | 
| +              UNREACHABLE();
 | 
| +              break;
 | 
| +          }
 | 
|          } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0) {
 | 
|            int Vd = instr->VFPDRegValue(kSimd128Precision);
 | 
|            int Vm = instr->VFPMRegValue(kSimd128Precision);
 | 
| 
 |