diff --git a/src/diagnostics/arm/disasm-arm.cc b/src/diagnostics/arm/disasm-arm.cc index 867c38f382..aea45121d8 100644 --- a/src/diagnostics/arm/disasm-arm.cc +++ b/src/diagnostics/arm/disasm-arm.cc @@ -585,11 +585,14 @@ int Decoder::FormatOption(Instruction* instr, const char* format) { Print("s"); } return 4; - } else { // 'size, for Advanced SIMD instructions - DCHECK(STRING_STARTS_WITH(format, "size")); - int sz = 8 << instr->Bits(21, 20); + } else { + // 'size2 or 'size3, for Advanced SIMD instructions, 2 or 3 registers. + DCHECK(STRING_STARTS_WITH(format, "size2") || + STRING_STARTS_WITH(format, "size3")); + int sz = 8 << (format[4] == '2' ? instr->Bits(19, 18) + : instr->Bits(21, 20)); out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", sz); - return 4; + return 5; } } else if (format[1] == 'p') { if (format[8] == '_') { // 'spec_reg_fields @@ -2041,7 +2044,7 @@ void Decoder::DecodeAdvancedSIMDDataProcessing(Instruction* instr) { int sz = instr->Bits(21, 20); if (!u && opc == 0 && op1) { - Format(instr, "vqadd.s'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vqadd.s'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 1 && sz == 2 && q && op1) { if (Vm == Vn) { Format(instr, "vmov 'Qd, 'Qm"); @@ -2053,29 +2056,29 @@ void Decoder::DecodeAdvancedSIMDDataProcessing(Instruction* instr) { } else if (!u && opc == 1 && sz == 0 && q && op1) { Format(instr, "vand 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 2 && op1) { - Format(instr, "vqsub.s'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vqsub.s'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 3 && op1) { - Format(instr, "vcge.s'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vcge.s'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 3 && !op1) { - Format(instr, "vcgt.s'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vcgt.s'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 4 && !op1) { - Format(instr, "vshl.s'size 'Qd, 'Qm, 'Qn"); + Format(instr, "vshl.s'size3 'Qd, 'Qm, 'Qn"); } else if (!u && opc == 6 && op1) { - Format(instr, "vmin.s'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vmin.s'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 6 && !op1) { - Format(instr, "vmax.s'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vmax.s'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 8 && op1) { - Format(instr, "vtst.i'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vtst.i'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 8 && !op1) { - Format(instr, "vadd.i'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vadd.i'size3 'Qd, 'Qn, 'Qm"); } else if (opc == 9 && op1) { - Format(instr, "vmul.i'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vmul.i'size3 'Qd, 'Qn, 'Qm"); } else if (!u && opc == 0xA && op1) { - Format(instr, "vpmin.s'size 'Dd, 'Dn, 'Dm"); + Format(instr, "vpmin.s'size3 'Dd, 'Dn, 'Dm"); } else if (!u && opc == 0xA && !op1) { - Format(instr, "vpmax.s'size 'Dd, 'Dn, 'Dm"); + Format(instr, "vpmax.s'size3 'Dd, 'Dn, 'Dm"); } else if (!u && opc == 0xB) { - Format(instr, "vpadd.i'size 'Dd, 'Dn, 'Dm"); + Format(instr, "vpadd.i'size3 'Dd, 'Dn, 'Dm"); } else if (!u && !(sz >> 1) && opc == 0xD && !op1) { Format(instr, "vadd.f32 'Qd, 'Qn, 'Qm"); } else if (!u && (sz >> 1) && opc == 0xD && !op1) { @@ -2091,7 +2094,7 @@ void Decoder::DecodeAdvancedSIMDDataProcessing(Instruction* instr) { } else if (!u && (sz >> 1) && opc == 0xF && !op1) { Format(instr, "vmin.f32 'Qd, 'Qn, 'Qm"); } else if (u && opc == 0 && op1) { - Format(instr, "vqadd.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vqadd.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 1 && sz == 1 && op1) { Format(instr, "vbsl 'Qd, 'Qn, 'Qm"); } else if (u && opc == 1 && sz == 0 && q && op1) { @@ -2099,27 +2102,27 @@ void Decoder::DecodeAdvancedSIMDDataProcessing(Instruction* instr) { } else if (u && opc == 1 && sz == 0 && !q && op1) { Format(instr, "veor 'Dd, 'Dn, 'Dm"); } else if (u && opc == 1 && !op1) { - Format(instr, "vrhadd.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vrhadd.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 2 && op1) { - Format(instr, "vqsub.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vqsub.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 3 && op1) { - Format(instr, "vcge.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vcge.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 3 && !op1) { - Format(instr, "vcgt.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vcgt.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 4 && !op1) { - Format(instr, "vshl.u'size 'Qd, 'Qm, 'Qn"); + Format(instr, "vshl.u'size3 'Qd, 'Qm, 'Qn"); } else if (u && opc == 6 && op1) { - Format(instr, "vmin.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vmin.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 6 && !op1) { - Format(instr, "vmax.u'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vmax.u'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 8 && op1) { - Format(instr, "vceq.i'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vceq.i'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 8 && !op1) { - Format(instr, "vsub.i'size 'Qd, 'Qn, 'Qm"); + Format(instr, "vsub.i'size3 'Qd, 'Qn, 'Qm"); } else if (u && opc == 0xA && op1) { - Format(instr, "vpmin.u'size 'Dd, 'Dn, 'Dm"); + Format(instr, "vpmin.u'size3 'Dd, 'Dn, 'Dm"); } else if (u && opc == 0xA && !op1) { - Format(instr, "vpmax.u'size 'Dd, 'Dn, 'Dm"); + Format(instr, "vpmax.u'size3 'Dd, 'Dn, 'Dm"); } else if (u && opc == 0xD && sz == 0 && q && op1) { Format(instr, "vmul.f32 'Qd, 'Qn, 'Qm"); } else if (u && opc == 0xD && sz == 0 && !q && !op1) { @@ -2250,15 +2253,8 @@ void Decoder::DecodeAdvancedSIMDTwoOrThreeRegisters(Instruction* instr) { int opc1 = instr->Bits(17, 16); int opc2 = instr->Bits(10, 7); int q = instr->Bit(6); - - int Vd, Vm; - if (q) { - Vd = instr->VFPDRegValue(kSimd128Precision); - Vm = instr->VFPMRegValue(kSimd128Precision); - } else { - Vd = instr->VFPDRegValue(kDoublePrecision); - Vm = instr->VFPMRegValue(kDoublePrecision); - } + int Vd = instr->VFPDRegValue(q ? kSimd128Precision : kDoublePrecision); + int Vm = instr->VFPMRegValue(q ? kSimd128Precision : kDoublePrecision); int esize = kBitsPerByte * (1 << size); if (opc1 == 0 && (opc2 >> 2) == 0) { @@ -2270,37 +2266,20 @@ void Decoder::DecodeAdvancedSIMDTwoOrThreeRegisters(Instruction* instr) { Format(instr, q ? "vswp 'Qd, 'Qm" : "vswp 'Dd, 'Dm"); } else if (opc1 == 0 && opc2 == 0b1011) { Format(instr, "vmvn 'Qd, 'Qm"); - } else if (opc1 == 0b01 && (opc2 & 0b0111) == 0b110) { - // vabs. Qd, Qm. - char type = instr->Bit(10) != 0 ? 'f' : 's'; - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "vabs.%c%d q%d, q%d", type, esize, Vd, Vm); - } else if (opc1 == 0b01 && (opc2 & 0b0111) == 0b111) { - // vneg. Qd, Qm. - char type = instr->Bit(10) != 0 ? 'f' : 's'; - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "vneg.%c%d q%d, q%d", type, esize, Vd, Vm); + } else if (opc1 == 0b01 && opc2 == 0b0110) { + Format(instr, q ? "vabs.s'size2 'Qd, 'Qm" : "vabs.s.'size2 'Dd, 'Dm"); + } else if (opc1 == 0b01 && opc2 == 0b1110) { + Format(instr, q ? "vabs.f'size2 'Qd, 'Qm" : "vabs.f.'size2 'Dd, 'Dm"); + } else if (opc1 == 0b01 && opc2 == 0b0111) { + Format(instr, q ? "vneg.s'size2 'Qd, 'Qm" : "vneg.s.'size2 'Dd, 'Dm"); + } else if (opc1 == 0b01 && opc2 == 0b1111) { + Format(instr, q ? "vneg.f'size2 'Qd, 'Qm" : "vneg.f.'size2 'Dd, 'Dm"); } else if (opc1 == 0b10 && opc2 == 0b0001) { - if (q) { - // vtrn. Qd, Qm. - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "vtrn.%d q%d, q%d", esize, Vd, Vm); - } else { - // vtrn. Dd, Dm. - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "vtrn.%d d%d, d%d", esize, Vd, Vm); - } - } else if (opc1 == 0b10 && (opc2 & 0b1110) == 0b0010) { - const char* op = instr->Bit(7) != 0 ? "vzip" : "vuzp"; - if (q) { - // vzip/vuzp. Qd, Qm. - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "%s.%d q%d, q%d", op, esize, Vd, Vm); - } else { - // vzip/vuzp. Dd, Dm. - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "%s.%d d%d, d%d", op, esize, Vd, Vm); - } + Format(instr, q ? "vtrn.'size2 'Qd, 'Qm" : "vtrn.'size2 'Dd, 'Dm"); + } else if (opc1 == 0b10 && opc2 == 0b0010) { + Format(instr, q ? "vuzp.'size2 'Qd, 'Qm" : "vuzp.'size2 'Dd, 'Dm"); + } else if (opc1 == 0b10 && opc2 == 0b0011) { + Format(instr, q ? "vzip.'size2 'Qd, 'Qm" : "vzip.'size2 'Dd, 'Dm"); } else if (opc1 == 0b10 && (opc2 & 0b1110) == 0b0100) { // vqmov{u}n. Dd, Qm. int Vd = instr->VFPDRegValue(kDoublePrecision); @@ -2391,22 +2370,11 @@ void Decoder::DecodeAdvancedSIMDTwoOrThreeRegisters(Instruction* instr) { int u = instr->Bit(24); int opc = instr->Bits(11, 8); if (opc == 0b1000) { - // vmlal.u , , - int Vd = instr->VFPDRegValue(kSimd128Precision); - int Vn = instr->VFPNRegValue(kDoublePrecision); - int Vm = instr->VFPMRegValue(kDoublePrecision); - int esize = 8 << instr->Bits(21, 20); - out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, - "vmlal.u%d q%d, d%d, d%d", esize, Vd, Vn, Vm); + Format(instr, + u ? "vmlal.u'size3 'Qd, 'Dn, 'Dm" : "vmlal.s'size3 'Qd, 'Dn, 'Dm"); } else if (opc == 0b1100) { - // vmull.s/u Qd, Dn, Dm - int Vd = instr->VFPDRegValue(kSimd128Precision); - int Vn = instr->VFPNRegValue(kDoublePrecision); - int Vm = instr->VFPMRegValue(kDoublePrecision); - int esize = 8 << instr->Bits(21, 20); - out_buffer_pos_ += - SNPrintF(out_buffer_ + out_buffer_pos_, "vmull.%s%d q%d, d%d, d%d", - u ? "u" : "s", esize, Vd, Vn, Vm); + Format(instr, + u ? "vmull.u'size3 'Qd, 'Dn, 'Dm" : "vmull.s'size3 'Qd, 'Dn, 'Dm"); } } else if (op1 != 0b11 && op3) { // The instructions specified by this encoding are not used in V8.