Chromium Code Reviews| Index: src/arm/disasm-arm.cc |
| diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc |
| index abb13dd9f0d502de7a18b01af53913521d7ba498..93566a344951cc1dd07337ab4d76ced12bceff2b 100644 |
| --- a/src/arm/disasm-arm.cc |
| +++ b/src/arm/disasm-arm.cc |
| @@ -1419,6 +1419,7 @@ int Decoder::DecodeType7(Instruction* instr) { |
| // Sd = vsqrt(Sm) |
| // vmrs |
| // vmsr |
| +// Qd = vdup.size(Qd, Rt) |
| void Decoder::DecodeTypeVFP(Instruction* instr) { |
| VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); |
| VERIFY(instr->Bits(11, 9) == 0x5); |
| @@ -1531,13 +1532,23 @@ void Decoder::DecodeTypeVFP(Instruction* instr) { |
| if ((instr->VCValue() == 0x0) && |
| (instr->VAValue() == 0x0)) { |
| DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); |
| - } else if ((instr->VLValue() == 0x0) && |
| - (instr->VCValue() == 0x1) && |
| - (instr->Bit(23) == 0x0)) { |
| - if (instr->Bit(21) == 0x0) { |
| - Format(instr, "vmov'cond.32 'Dd[0], 'rt"); |
| + } else if ((instr->VLValue() == 0x0) && (instr->VCValue() == 0x1)) { |
| + if (instr->Bit(23) == 0) { |
| + if (instr->Bit(21) == 0x0) { |
| + Format(instr, "vmov'cond.32 'Dd[0], 'rt"); |
| + } else { |
| + Format(instr, "vmov'cond.32 'Dd[1], 'rt"); |
| + } |
| } else { |
| - Format(instr, "vmov'cond.32 'Dd[1], 'rt"); |
| + int size = 32; |
| + if (instr->Bit(5) != 0) |
| + size = 16; |
| + else if (instr->Bit(22) != 0) |
| + size = 8; |
| + int Vd = (instr->Bit(7) << 3) | (instr->VnValue() >> 1); |
|
Rodolph Perfetta (ARM)
2016/12/08 18:08:28
int Vd = instr->VFPNRegValue(kSimd128Precision);
bbudge
2016/12/10 21:33:04
Done.
|
| + int Rt = instr->RtValue(); |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| + "vdup.%i q%d, r%d", size, Vd, Rt); |
| } |
| } else if ((instr->VLValue() == 0x1) && |
| (instr->VCValue() == 0x1) && |
| @@ -1563,6 +1574,8 @@ void Decoder::DecodeTypeVFP(Instruction* instr) { |
| Format(instr, "vmrs'cond 'rt, FPSCR"); |
| } |
| } |
| + } else { |
| + Unknown(instr); // Not used by V8. |
| } |
| } |
| } |
| @@ -1809,6 +1822,25 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { |
| int Vm = instr->VFPMRegValue(kSimd128Precision); |
| out_buffer_pos_ += |
| SNPrintF(out_buffer_ + out_buffer_pos_, "vmov q%d, q%d", Vd, Vm); |
| + } else if (instr->Bits(11, 8) == 8) { |
| + const char* op = (instr->Bit(4) == 0) ? "vadd" : "vtst"; |
| + int size = kBitsPerByte * (1 << instr->Bits(21, 20)); |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kSimd128Precision); |
| + int Vn = instr->VFPNRegValue(kSimd128Precision); |
| + // vadd/vtst.i<size> Qd, Qm, Qn. |
| + out_buffer_pos_ += |
| + SNPrintF(out_buffer_ + out_buffer_pos_, "%s.i%d q%d, q%d, q%d", op, |
| + size, Vd, Vn, Vm); |
| + } else if (instr->Bits(11, 8) == 0xd && instr->Bit(4) == 0) { |
| + const char* op = (instr->Bits(21, 20) == 0) ? "vadd" : "vsub"; |
| + int size = kBitsPerByte * (1 << instr->Bits(21, 20)); |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kSimd128Precision); |
| + int Vn = instr->VFPNRegValue(kSimd128Precision); |
| + // vadd/vsub.f32 Qd, Qm, Qn. |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| + "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm); |
| } else { |
| Unknown(instr); |
| } |
| @@ -1828,8 +1860,29 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { |
| } |
| break; |
| case 6: |
| - if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 && |
| - instr->Bit(4) == 1) { |
| + if (instr->Bits(11, 8) == 8) { |
| + int size = kBitsPerByte * (1 << instr->Bits(21, 20)); |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kSimd128Precision); |
| + int Vn = instr->VFPNRegValue(kSimd128Precision); |
| + if (instr->Bit(4) == 0) { |
| + out_buffer_pos_ += |
| + SNPrintF(out_buffer_ + out_buffer_pos_, "vsub.i%d q%d, q%d, q%d", |
| + size, Vd, Vn, Vm); |
| + } else { |
| + out_buffer_pos_ += |
| + SNPrintF(out_buffer_ + out_buffer_pos_, "vceq.i%d q%d, q%d, q%d", |
| + size, Vd, Vn, Vm); |
| + } |
| + } else if (instr->Bits(21, 20) == 1 && instr->Bits(11, 8) == 1 && |
| + instr->Bit(4) == 1) { |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kSimd128Precision); |
| + int Vn = instr->VFPNRegValue(kSimd128Precision); |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| + "vbsl q%d, q%d, q%d", Vd, Vn, Vm); |
| + } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 && |
| + instr->Bit(4) == 1) { |
| if (instr->Bit(6) == 0) { |
| // veor Dd, Dn, Dm |
| int Vd = instr->VFPDRegValue(kDoublePrecision); |
| @@ -1860,6 +1913,35 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { |
| int imm3 = instr->Bits(21, 19); |
| out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm); |
| + } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0 && |
| + instr->Bits(11, 6) == 0x17 && instr->Bit(4) == 0) { |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kSimd128Precision); |
| + out_buffer_pos_ += |
| + SNPrintF(out_buffer_ + out_buffer_pos_, "vmvn q%d, q%d", Vd, Vm); |
| + } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0xB && |
| + instr->Bits(11, 9) == 0x3 && instr->Bit(6) == 1 && |
| + instr->Bit(4) == 0) { |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kSimd128Precision); |
| + const char* suffix = nullptr; |
| + int op = instr->Bits(8, 7); |
| + switch (op) { |
| + case 0: |
| + suffix = "f32.s32"; |
| + break; |
| + case 1: |
| + suffix = "f32.u32"; |
| + break; |
| + case 2: |
| + suffix = "s32.f32"; |
| + break; |
| + case 3: |
| + suffix = "u32.f32"; |
| + break; |
| + } |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| + "vcvt.%s q%d, q%d", suffix, Vd, Vm); |
| } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) && |
| (instr->Bit(4) == 0)) { |
| if (instr->Bit(6) == 0) { |
| @@ -1873,6 +1955,25 @@ void Decoder::DecodeSpecialCondition(Instruction* instr) { |
| out_buffer_pos_ += |
| SNPrintF(out_buffer_ + out_buffer_pos_, "vswp q%d, q%d", Vd, Vm); |
| } |
| + } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 7) == 0x18 && |
| + instr->Bit(4) == 0x0) { |
| + int Vd = instr->VFPDRegValue(kSimd128Precision); |
| + int Vm = instr->VFPMRegValue(kDoublePrecision); |
| + int index = instr->Bit(19); |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| + "vdup q%d, d%d[%d]", Vd, Vm, index); |
| + } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 10) == 0x2 && |
| + instr->Bit(4) == 0x0) { |
| + int Vd = instr->VFPDRegValue(kDoublePrecision); |
| + int Vn = instr->VFPNRegValue(kDoublePrecision); |
| + int Vm = instr->VFPMRegValue(kDoublePrecision); |
| + int len = instr->Bits(9, 8); |
| + NeonListOperand list(DwVfpRegister::from_code(Vn), len + 1); |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s d%d, ", |
| + instr->Bit(6) == 0 ? "vtbl" : "vtbx", Vd); |
|
Rodolph Perfetta (ARM)
2016/12/08 18:08:28
vtbl.8, vtbx.8
bbudge
2016/12/10 21:33:04
Done.
|
| + FormatNeonList(Vn, list.type()); |
| + Print(", "); |
| + PrintDRegister(Vm); |
| } else { |
| Unknown(instr); |
| } |