Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Unified Diff: src/arm/disasm-arm.cc

Issue 2546933002: [Turbofan] Add ARM NEON instructions for implementing SIMD. (Closed)
Patch Set: Fourth review comments. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/constants-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/disasm-arm.cc
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index abb13dd9f0d502de7a18b01af53913521d7ba498..7a42386d74aabd344294ac0d5fc731776cd7f24d 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -1419,6 +1419,9 @@ int Decoder::DecodeType7(Instruction* instr) {
// Sd = vsqrt(Sm)
// vmrs
// vmsr
+// Qd = vdup.size(Qd, Rt)
+// vmov.size: Dd[i] = Rt
+// vmov.sign.size: Rt = Dn[i]
void Decoder::DecodeTypeVFP(Instruction* instr) {
VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
VERIFY(instr->Bits(11, 9) == 0x5);
@@ -1531,21 +1534,71 @@ 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) {
+ int opc1_opc2 = (instr->Bits(22, 21) << 2) | instr->Bits(6, 5);
+ if ((opc1_opc2 & 0xb) == 0) {
+ // NeonS32/NeonU32
+ if (instr->Bit(21) == 0x0) {
+ Format(instr, "vmov'cond.32 'Dd[0], 'rt");
+ } else {
+ Format(instr, "vmov'cond.32 'Dd[1], 'rt");
+ }
+ } else {
+ int vd = instr->VFPNRegValue(kDoublePrecision);
+ int rt = instr->RtValue();
+ if ((opc1_opc2 & 0x8) != 0) {
+ // NeonS8 / NeonU8
+ int i = opc1_opc2 & 0x7;
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
+ "vmov.8 d%d[%d], r%d", vd, i, rt);
+ } else if ((opc1_opc2 & 0x1) != 0) {
+ // NeonS16 / NeonU16
+ int i = (opc1_opc2 >> 1) & 0x3;
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
+ "vmov.16 d%d[%d], r%d", vd, i, rt);
+ } else {
+ Unknown(instr);
+ }
+ }
} else {
- Format(instr, "vmov'cond.32 'Dd[1], 'rt");
- }
- } else if ((instr->VLValue() == 0x1) &&
- (instr->VCValue() == 0x1) &&
- (instr->Bit(23) == 0x0)) {
- if (instr->Bit(21) == 0x0) {
- Format(instr, "vmov'cond.32 'rt, 'Dd[0]");
+ int size = 32;
+ if (instr->Bit(5) != 0)
+ size = 16;
+ else if (instr->Bit(22) != 0)
+ size = 8;
+ int Vd = instr->VFPNRegValue(kSimd128Precision);
+ 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)) {
+ int opc1_opc2 = (instr->Bits(22, 21) << 2) | instr->Bits(6, 5);
+ if ((opc1_opc2 & 0xb) == 0) {
+ // NeonS32 / NeonU32
+ if (instr->Bit(21) == 0x0) {
+ Format(instr, "vmov'cond.32 'rt, 'Dd[0]");
+ } else {
+ Format(instr, "vmov'cond.32 'rt, 'Dd[1]");
+ }
} else {
- Format(instr, "vmov'cond.32 'rt, 'Dd[1]");
+ const char* sign = instr->Bit(23) != 0 ? "u" : "s";
+ int rt = instr->RtValue();
+ int vn = instr->VFPNRegValue(kDoublePrecision);
+ if ((opc1_opc2 & 0x8) != 0) {
+ // NeonS8 / NeonU8
+ int i = opc1_opc2 & 0x7;
+ out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
+ "vmov.%s8 r%d, d%d[%d]", sign, rt, vn, i);
+ } else if ((opc1_opc2 & 0x1) != 0) {
+ // NeonS16 / NeonU16
+ int i = (opc1_opc2 >> 1) & 0x3;
+ out_buffer_pos_ +=
+ SNPrintF(out_buffer_ + out_buffer_pos_, "vmov.%s16 r%d, d%d[%d]",
+ sign, rt, vn, i);
+ } else {
+ Unknown(instr);
+ }
}
} else if ((instr->VCValue() == 0x0) &&
(instr->VAValue() == 0x7) &&
@@ -1563,6 +1616,8 @@ void Decoder::DecodeTypeVFP(Instruction* instr) {
Format(instr, "vmrs'cond 'rt, FPSCR");
}
}
+ } else {
+ Unknown(instr); // Not used by V8.
}
}
}
@@ -1809,6 +1864,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 +1902,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 +1955,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 +1997,26 @@ 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.8" : "vtbx.8", Vd);
+ FormatNeonList(Vn, list.type());
+ Print(", ");
+ PrintDRegister(Vm);
} else {
Unknown(instr);
}
« no previous file with comments | « src/arm/constants-arm.h ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698