OLD | NEW |
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 1849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1860 int Vd, Vm, Vn; | 1860 int Vd, Vm, Vn; |
1861 if (instr->Bit(6) == 0) { | 1861 if (instr->Bit(6) == 0) { |
1862 Vd = instr->VFPDRegValue(kDoublePrecision); | 1862 Vd = instr->VFPDRegValue(kDoublePrecision); |
1863 Vm = instr->VFPMRegValue(kDoublePrecision); | 1863 Vm = instr->VFPMRegValue(kDoublePrecision); |
1864 Vn = instr->VFPNRegValue(kDoublePrecision); | 1864 Vn = instr->VFPNRegValue(kDoublePrecision); |
1865 } else { | 1865 } else { |
1866 Vd = instr->VFPDRegValue(kSimd128Precision); | 1866 Vd = instr->VFPDRegValue(kSimd128Precision); |
1867 Vm = instr->VFPMRegValue(kSimd128Precision); | 1867 Vm = instr->VFPMRegValue(kSimd128Precision); |
1868 Vn = instr->VFPNRegValue(kSimd128Precision); | 1868 Vn = instr->VFPNRegValue(kSimd128Precision); |
1869 } | 1869 } |
| 1870 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); |
1870 switch (instr->Bits(11, 8)) { | 1871 switch (instr->Bits(11, 8)) { |
1871 case 0x0: { | 1872 case 0x0: { |
1872 if (instr->Bit(4) == 1) { | 1873 if (instr->Bit(4) == 1) { |
1873 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
1874 // vqadd.s<size> Qd, Qm, Qn. | 1874 // vqadd.s<size> Qd, Qm, Qn. |
1875 out_buffer_pos_ += | 1875 out_buffer_pos_ += |
1876 SNPrintF(out_buffer_ + out_buffer_pos_, | 1876 SNPrintF(out_buffer_ + out_buffer_pos_, |
1877 "vqadd.s%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 1877 "vqadd.s%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
1878 } else { | 1878 } else { |
1879 Unknown(instr); | 1879 Unknown(instr); |
1880 } | 1880 } |
1881 break; | 1881 break; |
1882 } | 1882 } |
1883 case 0x1: { | 1883 case 0x1: { |
(...skipping 13 matching lines...) Expand all Loading... |
1897 // vand Qd, Qm, Qn. | 1897 // vand Qd, Qm, Qn. |
1898 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 1898 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
1899 "vand q%d, q%d, q%d", Vd, Vn, Vm); | 1899 "vand q%d, q%d, q%d", Vd, Vn, Vm); |
1900 } else { | 1900 } else { |
1901 Unknown(instr); | 1901 Unknown(instr); |
1902 } | 1902 } |
1903 break; | 1903 break; |
1904 } | 1904 } |
1905 case 0x2: { | 1905 case 0x2: { |
1906 if (instr->Bit(4) == 1) { | 1906 if (instr->Bit(4) == 1) { |
1907 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
1908 // vqsub.s<size> Qd, Qm, Qn. | 1907 // vqsub.s<size> Qd, Qm, Qn. |
1909 out_buffer_pos_ += | 1908 out_buffer_pos_ += |
1910 SNPrintF(out_buffer_ + out_buffer_pos_, | 1909 SNPrintF(out_buffer_ + out_buffer_pos_, |
1911 "vqsub.s%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 1910 "vqsub.s%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
1912 } else { | 1911 } else { |
1913 Unknown(instr); | 1912 Unknown(instr); |
1914 } | 1913 } |
1915 break; | 1914 break; |
1916 } | 1915 } |
1917 case 0x3: { | 1916 case 0x3: { |
1918 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
1919 const char* op = (instr->Bit(4) == 1) ? "vcge" : "vcgt"; | 1917 const char* op = (instr->Bit(4) == 1) ? "vcge" : "vcgt"; |
1920 // vcge/vcgt.s<size> Qd, Qm, Qn. | 1918 // vcge/vcgt.s<size> Qd, Qm, Qn. |
1921 out_buffer_pos_ += | 1919 out_buffer_pos_ += |
1922 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.s%d q%d, q%d, q%d", | 1920 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.s%d q%d, q%d, q%d", |
1923 op, size, Vd, Vn, Vm); | 1921 op, size, Vd, Vn, Vm); |
1924 break; | 1922 break; |
1925 } | 1923 } |
1926 case 0x6: { | 1924 case 0x6: { |
1927 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
1928 // vmin/vmax.s<size> Qd, Qm, Qn. | 1925 // vmin/vmax.s<size> Qd, Qm, Qn. |
1929 const char* op = instr->Bit(4) == 1 ? "vmin" : "vmax"; | 1926 const char* op = instr->Bit(4) == 1 ? "vmin" : "vmax"; |
1930 out_buffer_pos_ += | 1927 out_buffer_pos_ += |
1931 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.s%d q%d, q%d, q%d", | 1928 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.s%d q%d, q%d, q%d", |
1932 op, size, Vd, Vn, Vm); | 1929 op, size, Vd, Vn, Vm); |
1933 break; | 1930 break; |
1934 } | 1931 } |
1935 case 0x8: { | 1932 case 0x8: { |
1936 const char* op = (instr->Bit(4) == 0) ? "vadd" : "vtst"; | 1933 const char* op = (instr->Bit(4) == 0) ? "vadd" : "vtst"; |
1937 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
1938 // vadd/vtst.i<size> Qd, Qm, Qn. | 1934 // vadd/vtst.i<size> Qd, Qm, Qn. |
1939 out_buffer_pos_ += | 1935 out_buffer_pos_ += |
1940 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.i%d q%d, q%d, q%d", | 1936 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.i%d q%d, q%d, q%d", |
1941 op, size, Vd, Vn, Vm); | 1937 op, size, Vd, Vn, Vm); |
1942 break; | 1938 break; |
1943 } | 1939 } |
1944 case 0x9: { | 1940 case 0x9: { |
1945 if (instr->Bit(6) == 1 && instr->Bit(4) == 1) { | 1941 if (instr->Bit(6) == 1 && instr->Bit(4) == 1) { |
1946 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
1947 // vmul.i<size> Qd, Qm, Qn. | 1942 // vmul.i<size> Qd, Qm, Qn. |
1948 out_buffer_pos_ += | 1943 out_buffer_pos_ += |
1949 SNPrintF(out_buffer_ + out_buffer_pos_, | 1944 SNPrintF(out_buffer_ + out_buffer_pos_, |
1950 "vmul.i%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 1945 "vmul.i%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
1951 } else { | 1946 } else { |
1952 Unknown(instr); | 1947 Unknown(instr); |
1953 } | 1948 } |
1954 break; | 1949 break; |
1955 } | 1950 } |
| 1951 case 0xa: { |
| 1952 // vpmin/vpmax.s<size> Dd, Dm, Dn. |
| 1953 const char* op = instr->Bit(4) == 1 ? "vpmin" : "vpmax"; |
| 1954 out_buffer_pos_ += |
| 1955 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.s%d d%d, d%d, d%d", |
| 1956 op, size, Vd, Vn, Vm); |
| 1957 break; |
| 1958 } |
1956 case 0xd: { | 1959 case 0xd: { |
1957 if (instr->Bit(4) == 0) { | 1960 if (instr->Bit(4) == 0) { |
1958 const char* op = (instr->Bits(21, 20) == 0) ? "vadd" : "vsub"; | 1961 const char* op = (instr->Bits(21, 20) == 0) ? "vadd" : "vsub"; |
1959 // vadd/vsub.f32 Qd, Qm, Qn. | 1962 // vadd/vsub.f32 Qd, Qm, Qn. |
1960 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 1963 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
1961 "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm); | 1964 "%s.f32 q%d, q%d, q%d", op, Vd, Vn, Vm); |
1962 } else { | 1965 } else { |
1963 Unknown(instr); | 1966 Unknown(instr); |
1964 } | 1967 } |
1965 break; | 1968 break; |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2045 int Vd, Vm, Vn; | 2048 int Vd, Vm, Vn; |
2046 if (instr->Bit(6) == 0) { | 2049 if (instr->Bit(6) == 0) { |
2047 Vd = instr->VFPDRegValue(kDoublePrecision); | 2050 Vd = instr->VFPDRegValue(kDoublePrecision); |
2048 Vm = instr->VFPMRegValue(kDoublePrecision); | 2051 Vm = instr->VFPMRegValue(kDoublePrecision); |
2049 Vn = instr->VFPNRegValue(kDoublePrecision); | 2052 Vn = instr->VFPNRegValue(kDoublePrecision); |
2050 } else { | 2053 } else { |
2051 Vd = instr->VFPDRegValue(kSimd128Precision); | 2054 Vd = instr->VFPDRegValue(kSimd128Precision); |
2052 Vm = instr->VFPMRegValue(kSimd128Precision); | 2055 Vm = instr->VFPMRegValue(kSimd128Precision); |
2053 Vn = instr->VFPNRegValue(kSimd128Precision); | 2056 Vn = instr->VFPNRegValue(kSimd128Precision); |
2054 } | 2057 } |
| 2058 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); |
2055 switch (instr->Bits(11, 8)) { | 2059 switch (instr->Bits(11, 8)) { |
2056 case 0x0: { | 2060 case 0x0: { |
2057 if (instr->Bit(4) == 1) { | 2061 if (instr->Bit(4) == 1) { |
2058 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
2059 // vqadd.u<size> Qd, Qm, Qn. | 2062 // vqadd.u<size> Qd, Qm, Qn. |
2060 out_buffer_pos_ += | 2063 out_buffer_pos_ += |
2061 SNPrintF(out_buffer_ + out_buffer_pos_, | 2064 SNPrintF(out_buffer_ + out_buffer_pos_, |
2062 "vqadd.u%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 2065 "vqadd.u%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
2063 } else { | 2066 } else { |
2064 Unknown(instr); | 2067 Unknown(instr); |
2065 } | 2068 } |
2066 break; | 2069 break; |
2067 } | 2070 } |
2068 case 0x1: { | 2071 case 0x1: { |
(...skipping 11 matching lines...) Expand all Loading... |
2080 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 2083 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
2081 "veor q%d, q%d, q%d", Vd, Vn, Vm); | 2084 "veor q%d, q%d, q%d", Vd, Vn, Vm); |
2082 } | 2085 } |
2083 } else { | 2086 } else { |
2084 Unknown(instr); | 2087 Unknown(instr); |
2085 } | 2088 } |
2086 break; | 2089 break; |
2087 } | 2090 } |
2088 case 0x2: { | 2091 case 0x2: { |
2089 if (instr->Bit(4) == 1) { | 2092 if (instr->Bit(4) == 1) { |
2090 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
2091 // vqsub.u<size> Qd, Qm, Qn. | 2093 // vqsub.u<size> Qd, Qm, Qn. |
2092 out_buffer_pos_ += | 2094 out_buffer_pos_ += |
2093 SNPrintF(out_buffer_ + out_buffer_pos_, | 2095 SNPrintF(out_buffer_ + out_buffer_pos_, |
2094 "vqsub.u%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 2096 "vqsub.u%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
2095 } else { | 2097 } else { |
2096 Unknown(instr); | 2098 Unknown(instr); |
2097 } | 2099 } |
2098 break; | 2100 break; |
2099 } | 2101 } |
2100 case 0x3: { | 2102 case 0x3: { |
2101 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
2102 const char* op = (instr->Bit(4) == 1) ? "vcge" : "vcgt"; | 2103 const char* op = (instr->Bit(4) == 1) ? "vcge" : "vcgt"; |
2103 // vcge/vcgt.u<size> Qd, Qm, Qn. | 2104 // vcge/vcgt.u<size> Qd, Qm, Qn. |
2104 out_buffer_pos_ += | 2105 out_buffer_pos_ += |
2105 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.u%d q%d, q%d, q%d", | 2106 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.u%d q%d, q%d, q%d", |
2106 op, size, Vd, Vn, Vm); | 2107 op, size, Vd, Vn, Vm); |
2107 break; | 2108 break; |
2108 } | 2109 } |
2109 case 0x6: { | 2110 case 0x6: { |
2110 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
2111 // vmin/vmax.u<size> Qd, Qm, Qn. | 2111 // vmin/vmax.u<size> Qd, Qm, Qn. |
2112 const char* op = instr->Bit(4) == 1 ? "vmin" : "vmax"; | 2112 const char* op = instr->Bit(4) == 1 ? "vmin" : "vmax"; |
2113 out_buffer_pos_ += | 2113 out_buffer_pos_ += |
2114 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.u%d q%d, q%d, q%d", | 2114 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.u%d q%d, q%d, q%d", |
2115 op, size, Vd, Vn, Vm); | 2115 op, size, Vd, Vn, Vm); |
2116 break; | 2116 break; |
2117 } | 2117 } |
2118 case 0x8: { | 2118 case 0x8: { |
2119 int size = kBitsPerByte * (1 << instr->Bits(21, 20)); | |
2120 if (instr->Bit(4) == 0) { | 2119 if (instr->Bit(4) == 0) { |
2121 out_buffer_pos_ += | 2120 out_buffer_pos_ += |
2122 SNPrintF(out_buffer_ + out_buffer_pos_, | 2121 SNPrintF(out_buffer_ + out_buffer_pos_, |
2123 "vsub.i%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 2122 "vsub.i%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
2124 } else { | 2123 } else { |
2125 out_buffer_pos_ += | 2124 out_buffer_pos_ += |
2126 SNPrintF(out_buffer_ + out_buffer_pos_, | 2125 SNPrintF(out_buffer_ + out_buffer_pos_, |
2127 "vceq.i%d q%d, q%d, q%d", size, Vd, Vn, Vm); | 2126 "vceq.i%d q%d, q%d, q%d", size, Vd, Vn, Vm); |
2128 } | 2127 } |
2129 break; | 2128 break; |
2130 } | 2129 } |
| 2130 case 0xa: { |
| 2131 // vpmin/vpmax.u<size> Dd, Dm, Dn. |
| 2132 const char* op = instr->Bit(4) == 1 ? "vpmin" : "vpmax"; |
| 2133 out_buffer_pos_ += |
| 2134 SNPrintF(out_buffer_ + out_buffer_pos_, "%s.u%d d%d, d%d, d%d", |
| 2135 op, size, Vd, Vn, Vm); |
| 2136 break; |
| 2137 } |
2131 case 0xd: { | 2138 case 0xd: { |
2132 if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) { | 2139 if (instr->Bit(21) == 0 && instr->Bit(6) == 1 && instr->Bit(4) == 1) { |
2133 // vmul.f32 Qd, Qn, Qm | 2140 // vmul.f32 Qd, Qn, Qm |
2134 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 2141 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
2135 "vmul.f32 q%d, q%d, q%d", Vd, Vn, Vm); | 2142 "vmul.f32 q%d, q%d, q%d", Vd, Vn, Vm); |
2136 } else { | 2143 } else { |
2137 Unknown(instr); | 2144 Unknown(instr); |
2138 } | 2145 } |
2139 break; | 2146 break; |
2140 } | 2147 } |
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2615 pc += d.InstructionDecode(buffer, pc); | 2622 pc += d.InstructionDecode(buffer, pc); |
2616 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), | 2623 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), |
2617 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 2624 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
2618 } | 2625 } |
2619 } | 2626 } |
2620 | 2627 |
2621 | 2628 |
2622 } // namespace disasm | 2629 } // namespace disasm |
2623 | 2630 |
2624 #endif // V8_TARGET_ARCH_ARM | 2631 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |