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

Side by Side Diff: src/arm/disasm-arm.cc

Issue 2546933002: [Turbofan] Add ARM NEON instructions for implementing SIMD. (Closed)
Patch Set: Don't use temporary FP regs in tests. 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 unified diff | Download patch
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A Disassembler object is used to disassemble a block of code instruction by 5 // A Disassembler object is used to disassemble a block of code instruction by
6 // instruction. The default implementation of the NameConverter object can be 6 // instruction. The default implementation of the NameConverter object can be
7 // overriden to modify register names or to do symbol lookup on addresses. 7 // overriden to modify register names or to do symbol lookup on addresses.
8 // 8 //
9 // The example below will disassemble a block of code and print it to stdout. 9 // The example below will disassemble a block of code and print it to stdout.
10 // 10 //
(...skipping 1401 matching lines...) Expand 10 before | Expand all | Expand 10 after
1412 // Dd = vmls(Dn, Dm) 1412 // Dd = vmls(Dn, Dm)
1413 // Sd = vmls(Sn, Sm) 1413 // Sd = vmls(Sn, Sm)
1414 // Dd = vdiv(Dn, Dm) 1414 // Dd = vdiv(Dn, Dm)
1415 // Sd = vdiv(Sn, Sm) 1415 // Sd = vdiv(Sn, Sm)
1416 // vcmp(Dd, Dm) 1416 // vcmp(Dd, Dm)
1417 // vcmp(Sd, Sm) 1417 // vcmp(Sd, Sm)
1418 // Dd = vsqrt(Dm) 1418 // Dd = vsqrt(Dm)
1419 // Sd = vsqrt(Sm) 1419 // Sd = vsqrt(Sm)
1420 // vmrs 1420 // vmrs
1421 // vmsr 1421 // vmsr
1422 // Qd = vdup.size(Qd, Rt)
1422 void Decoder::DecodeTypeVFP(Instruction* instr) { 1423 void Decoder::DecodeTypeVFP(Instruction* instr) {
1423 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); 1424 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
1424 VERIFY(instr->Bits(11, 9) == 0x5); 1425 VERIFY(instr->Bits(11, 9) == 0x5);
1425 1426
1426 if (instr->Bit(4) == 0) { 1427 if (instr->Bit(4) == 0) {
1427 if (instr->Opc1Value() == 0x7) { 1428 if (instr->Opc1Value() == 0x7) {
1428 // Other data processing instructions 1429 // Other data processing instructions
1429 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { 1430 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
1430 // vmov register to register. 1431 // vmov register to register.
1431 if (instr->SzValue() == 0x1) { 1432 if (instr->SzValue() == 0x1) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 } else { 1525 } else {
1525 Format(instr, "vdiv'cond.f32 'Sd, 'Sn, 'Sm"); 1526 Format(instr, "vdiv'cond.f32 'Sd, 'Sn, 'Sm");
1526 } 1527 }
1527 } else { 1528 } else {
1528 Unknown(instr); // Not used by V8. 1529 Unknown(instr); // Not used by V8.
1529 } 1530 }
1530 } else { 1531 } else {
1531 if ((instr->VCValue() == 0x0) && 1532 if ((instr->VCValue() == 0x0) &&
1532 (instr->VAValue() == 0x0)) { 1533 (instr->VAValue() == 0x0)) {
1533 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 1534 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
1534 } else if ((instr->VLValue() == 0x0) && 1535 } else if ((instr->VLValue() == 0x0) && (instr->VCValue() == 0x1)) {
1535 (instr->VCValue() == 0x1) && 1536 if (instr->Bit(23) == 0) {
1536 (instr->Bit(23) == 0x0)) { 1537 if (instr->Bit(21) == 0x0) {
1537 if (instr->Bit(21) == 0x0) { 1538 Format(instr, "vmov'cond.32 'Dd[0], 'rt");
1538 Format(instr, "vmov'cond.32 'Dd[0], 'rt"); 1539 } else {
1540 Format(instr, "vmov'cond.32 'Dd[1], 'rt");
1541 }
1539 } else { 1542 } else {
1540 Format(instr, "vmov'cond.32 'Dd[1], 'rt"); 1543 int size = 32;
1544 if (instr->Bit(5) != 0)
1545 size = 16;
1546 else if (instr->Bit(22) != 0)
1547 size = 8;
1548 int Vd = (instr->Bit(7) << 3) | (instr->VnValue() >> 1);
1549 int Rt = instr->RtValue();
1550 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1551 "vdup.%i q%d, r%d", size, Vd, Rt);
1541 } 1552 }
1542 } else if ((instr->VLValue() == 0x1) && 1553 } else if ((instr->VLValue() == 0x1) &&
1543 (instr->VCValue() == 0x1) && 1554 (instr->VCValue() == 0x1) &&
1544 (instr->Bit(23) == 0x0)) { 1555 (instr->Bit(23) == 0x0)) {
1545 if (instr->Bit(21) == 0x0) { 1556 if (instr->Bit(21) == 0x0) {
1546 Format(instr, "vmov'cond.32 'rt, 'Dd[0]"); 1557 Format(instr, "vmov'cond.32 'rt, 'Dd[0]");
1547 } else { 1558 } else {
1548 Format(instr, "vmov'cond.32 'rt, 'Dd[1]"); 1559 Format(instr, "vmov'cond.32 'rt, 'Dd[1]");
1549 } 1560 }
1550 } else if ((instr->VCValue() == 0x0) && 1561 } else if ((instr->VCValue() == 0x0) &&
1551 (instr->VAValue() == 0x7) && 1562 (instr->VAValue() == 0x7) &&
1552 (instr->Bits(19, 16) == 0x1)) { 1563 (instr->Bits(19, 16) == 0x1)) {
1553 if (instr->VLValue() == 0) { 1564 if (instr->VLValue() == 0) {
1554 if (instr->Bits(15, 12) == 0xF) { 1565 if (instr->Bits(15, 12) == 0xF) {
1555 Format(instr, "vmsr'cond FPSCR, APSR"); 1566 Format(instr, "vmsr'cond FPSCR, APSR");
1556 } else { 1567 } else {
1557 Format(instr, "vmsr'cond FPSCR, 'rt"); 1568 Format(instr, "vmsr'cond FPSCR, 'rt");
1558 } 1569 }
1559 } else { 1570 } else {
1560 if (instr->Bits(15, 12) == 0xF) { 1571 if (instr->Bits(15, 12) == 0xF) {
1561 Format(instr, "vmrs'cond APSR, FPSCR"); 1572 Format(instr, "vmrs'cond APSR, FPSCR");
1562 } else { 1573 } else {
1563 Format(instr, "vmrs'cond 'rt, FPSCR"); 1574 Format(instr, "vmrs'cond 'rt, FPSCR");
1564 } 1575 }
1565 } 1576 }
1577 } else {
1578 Unknown(instr); // Not used by V8.
1566 } 1579 }
1567 } 1580 }
1568 } 1581 }
1569 1582
1570 void Decoder::DecodeTypeCP15(Instruction* instr) { 1583 void Decoder::DecodeTypeCP15(Instruction* instr) {
1571 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0)); 1584 VERIFY((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0));
1572 VERIFY(instr->CoprocessorValue() == 15); 1585 VERIFY(instr->CoprocessorValue() == 15);
1573 1586
1574 if (instr->Bit(4) == 1) { 1587 if (instr->Bit(4) == 1) {
1575 int crn = instr->Bits(19, 16); 1588 int crn = instr->Bits(19, 16);
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
1802 void Decoder::DecodeSpecialCondition(Instruction* instr) { 1815 void Decoder::DecodeSpecialCondition(Instruction* instr) {
1803 switch (instr->SpecialValue()) { 1816 switch (instr->SpecialValue()) {
1804 case 4: 1817 case 4:
1805 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 && 1818 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 &&
1806 instr->Bit(4) == 1) { 1819 instr->Bit(4) == 1) {
1807 // vmov Qd, Qm 1820 // vmov Qd, Qm
1808 int Vd = instr->VFPDRegValue(kSimd128Precision); 1821 int Vd = instr->VFPDRegValue(kSimd128Precision);
1809 int Vm = instr->VFPMRegValue(kSimd128Precision); 1822 int Vm = instr->VFPMRegValue(kSimd128Precision);
1810 out_buffer_pos_ += 1823 out_buffer_pos_ +=
1811 SNPrintF(out_buffer_ + out_buffer_pos_, "vmov q%d, q%d", Vd, Vm); 1824 SNPrintF(out_buffer_ + out_buffer_pos_, "vmov q%d, q%d", Vd, Vm);
1825 } else if (instr->Bits(11, 8) == 8) {
1826 const char* op = (instr->Bit(4) == 0) ? "vadd" : "vtst";
1827 int size = kBitsPerByte * (1 << instr->Bits(21, 20));
1828 int Vd = instr->VFPDRegValue(kSimd128Precision);
1829 int Vm = instr->VFPMRegValue(kSimd128Precision);
1830 int Vn = instr->VFPNRegValue(kSimd128Precision);
1831 // vadd/vtst.I<size> Qd, Qm, Qn.
1832 out_buffer_pos_ +=
1833 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.I%d q%d, q%d, q%d", op,
1834 size, Vd, Vn, Vm);
1835 } else if (instr->Bits(11, 8) == 0xd && instr->Bit(4) == 0) {
1836 const char* op = (instr->Bits(21, 20) == 0) ? "vadd" : "vsub";
1837 int size = kBitsPerByte * (1 << instr->Bits(21, 20));
1838 int Vd = instr->VFPDRegValue(kSimd128Precision);
1839 int Vm = instr->VFPMRegValue(kSimd128Precision);
1840 int Vn = instr->VFPNRegValue(kSimd128Precision);
1841 // vadd/vsub.F32 Qd, Qm, Qn.
1842 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1843 "%s.F32 q%d, q%d, q%d", op, Vd, Vn, Vm);
Rodolph Perfetta (ARM) 2016/12/07 15:59:00 use lower case for the type.
bbudge 2016/12/08 03:07:31 Done.
1812 } else { 1844 } else {
1813 Unknown(instr); 1845 Unknown(instr);
1814 } 1846 }
1815 break; 1847 break;
1816 case 5: 1848 case 5:
1817 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 1849 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
1818 (instr->Bit(4) == 1)) { 1850 (instr->Bit(4) == 1)) {
1819 // vmovl signed 1851 // vmovl signed
1820 if ((instr->VdValue() & 1) != 0) Unknown(instr); 1852 if ((instr->VdValue() & 1) != 0) Unknown(instr);
1821 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 1853 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
1822 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 1854 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
1823 int imm3 = instr->Bits(21, 19); 1855 int imm3 = instr->Bits(21, 19);
1824 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1856 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1825 "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm); 1857 "vmovl.s%d q%d, d%d", imm3*8, Vd, Vm);
1826 } else { 1858 } else {
1827 Unknown(instr); 1859 Unknown(instr);
1828 } 1860 }
1829 break; 1861 break;
1830 case 6: 1862 case 6:
1831 if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 && 1863 if (instr->Bits(11, 8) == 8) {
1832 instr->Bit(4) == 1) { 1864 int size = kBitsPerByte * (1 << instr->Bits(21, 20));
1865 int Vd = instr->VFPDRegValue(kSimd128Precision);
1866 int Vm = instr->VFPMRegValue(kSimd128Precision);
1867 int Vn = instr->VFPNRegValue(kSimd128Precision);
1868 if (instr->Bit(4) == 0) {
1869 out_buffer_pos_ +=
1870 SNPrintF(out_buffer_ + out_buffer_pos_, "vsub.I%d q%d, q%d, q%d",
Rodolph Perfetta (ARM) 2016/12/07 15:59:00 lower case
bbudge 2016/12/08 03:07:31 Done.
1871 size, Vd, Vn, Vm);
1872 } else {
1873 out_buffer_pos_ +=
1874 SNPrintF(out_buffer_ + out_buffer_pos_, "vceq.I%d q%d, q%d, q%d",
Rodolph Perfetta (ARM) 2016/12/07 15:59:00 lower case.
bbudge 2016/12/08 03:07:31 Done.
1875 size, Vd, Vn, Vm);
1876 }
1877 } else if (instr->Bits(21, 20) == 1 && instr->Bits(11, 8) == 1 &&
1878 instr->Bit(4) == 1) {
1879 int Vd = instr->VFPDRegValue(kSimd128Precision);
1880 int Vm = instr->VFPMRegValue(kSimd128Precision);
1881 int Vn = instr->VFPNRegValue(kSimd128Precision);
1882 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1883 "vbsl q%d, q%d, q%d", Vd, Vn, Vm);
1884 } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 &&
1885 instr->Bit(4) == 1) {
1833 if (instr->Bit(6) == 0) { 1886 if (instr->Bit(6) == 0) {
1834 // veor Dd, Dn, Dm 1887 // veor Dd, Dn, Dm
1835 int Vd = instr->VFPDRegValue(kDoublePrecision); 1888 int Vd = instr->VFPDRegValue(kDoublePrecision);
1836 int Vn = instr->VFPNRegValue(kDoublePrecision); 1889 int Vn = instr->VFPNRegValue(kDoublePrecision);
1837 int Vm = instr->VFPMRegValue(kDoublePrecision); 1890 int Vm = instr->VFPMRegValue(kDoublePrecision);
1838 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1891 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1839 "veor d%d, d%d, d%d", Vd, Vn, Vm); 1892 "veor d%d, d%d, d%d", Vd, Vn, Vm);
1840 1893
1841 } else { 1894 } else {
1842 // veor Qd, Qn, Qm 1895 // veor Qd, Qn, Qm
(...skipping 10 matching lines...) Expand all
1853 case 7: 1906 case 7:
1854 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 1907 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
1855 (instr->Bit(4) == 1)) { 1908 (instr->Bit(4) == 1)) {
1856 // vmovl unsigned 1909 // vmovl unsigned
1857 if ((instr->VdValue() & 1) != 0) Unknown(instr); 1910 if ((instr->VdValue() & 1) != 0) Unknown(instr);
1858 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 1911 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
1859 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 1912 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
1860 int imm3 = instr->Bits(21, 19); 1913 int imm3 = instr->Bits(21, 19);
1861 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, 1914 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1862 "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm); 1915 "vmovl.u%d q%d, d%d", imm3*8, Vd, Vm);
1916 } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0 &&
1917 instr->Bits(11, 6) == 0x17 && instr->Bit(4) == 0) {
1918 int Vd = instr->VFPDRegValue(kSimd128Precision);
1919 int Vm = instr->VFPMRegValue(kSimd128Precision);
1920 out_buffer_pos_ +=
1921 SNPrintF(out_buffer_ + out_buffer_pos_, "vmvn q%d, q%d", Vd, Vm);
1922 } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0xB &&
1923 instr->Bits(11, 9) == 0x3 && instr->Bit(4) == 0) {
1924 int Vd = instr->VFPDRegValue(kSimd128Precision);
1925 int Vm = instr->VFPMRegValue(kSimd128Precision);
1926 const char* suffix = nullptr;
1927 int op = instr->Bits(8, 7);
1928 switch (op) {
1929 case 0:
Rodolph Perfetta (ARM) 2016/12/07 15:59:00 same as the assembler this is incorrect, it should
bbudge 2016/12/08 03:07:31 Done.
1930 suffix = "S32.F32";
1931 break;
1932 case 1:
1933 suffix = "U32.F32";
1934 break;
1935 case 2:
1936 suffix = "F32.S32";
1937 break;
1938 case 3:
1939 suffix = "F32.U32";
1940 break;
1941 }
1942 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1943 "vcvt.%s q%d, q%d", suffix, Vd, Vm);
1863 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) && 1944 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) &&
1864 (instr->Bit(4) == 0)) { 1945 (instr->Bit(4) == 0)) {
1865 if (instr->Bit(6) == 0) { 1946 if (instr->Bit(6) == 0) {
1866 int Vd = instr->VFPDRegValue(kDoublePrecision); 1947 int Vd = instr->VFPDRegValue(kDoublePrecision);
1867 int Vm = instr->VFPMRegValue(kDoublePrecision); 1948 int Vm = instr->VFPMRegValue(kDoublePrecision);
1868 out_buffer_pos_ += 1949 out_buffer_pos_ +=
1869 SNPrintF(out_buffer_ + out_buffer_pos_, "vswp d%d, d%d", Vd, Vm); 1950 SNPrintF(out_buffer_ + out_buffer_pos_, "vswp d%d, d%d", Vd, Vm);
1870 } else { 1951 } else {
1871 int Vd = instr->VFPDRegValue(kSimd128Precision); 1952 int Vd = instr->VFPDRegValue(kSimd128Precision);
1872 int Vm = instr->VFPMRegValue(kSimd128Precision); 1953 int Vm = instr->VFPMRegValue(kSimd128Precision);
1873 out_buffer_pos_ += 1954 out_buffer_pos_ +=
1874 SNPrintF(out_buffer_ + out_buffer_pos_, "vswp q%d, q%d", Vd, Vm); 1955 SNPrintF(out_buffer_ + out_buffer_pos_, "vswp q%d, q%d", Vd, Vm);
1875 } 1956 }
1957 } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 7) == 0x18 &&
1958 instr->Bit(4) == 0x0) {
1959 int Vd = instr->VFPDRegValue(kSimd128Precision);
1960 int Vm = instr->VFPMRegValue(kDoublePrecision);
1961 int index = instr->Bit(19);
1962 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_,
1963 "vdup q%d, d%d[%d]", Vd, Vm, index);
1964 } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 10) == 0x2 &&
1965 instr->Bit(4) == 0x0) {
1966 int Vd = instr->VFPDRegValue(kDoublePrecision);
1967 int Vn = instr->VFPNRegValue(kDoublePrecision);
1968 int Vm = instr->VFPMRegValue(kDoublePrecision);
1969 int len = instr->Bits(9, 8);
1970 NeonListOperand list(DwVfpRegister::from_code(Vn), len + 1);
1971 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%s d%d, ",
1972 instr->Bit(6) == 0 ? "vtbl" : "vtbx", Vd);
1973 FormatNeonList(Vn, list.type());
1974 Print(", ");
1975 PrintDRegister(Vm);
1876 } else { 1976 } else {
1877 Unknown(instr); 1977 Unknown(instr);
1878 } 1978 }
1879 break; 1979 break;
1880 case 8: 1980 case 8:
1881 if (instr->Bits(21, 20) == 0) { 1981 if (instr->Bits(21, 20) == 0) {
1882 // vst1 1982 // vst1
1883 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); 1983 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
1884 int Rn = instr->VnValue(); 1984 int Rn = instr->VnValue();
1885 int type = instr->Bits(11, 8); 1985 int type = instr->Bits(11, 8);
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 pc += d.InstructionDecode(buffer, pc); 2311 pc += d.InstructionDecode(buffer, pc);
2212 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), 2312 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc),
2213 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); 2313 *reinterpret_cast<int32_t*>(prev_pc), buffer.start());
2214 } 2314 }
2215 } 2315 }
2216 2316
2217 2317
2218 } // namespace disasm 2318 } // namespace disasm
2219 2319
2220 #endif // V8_TARGET_ARCH_ARM 2320 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698