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 2149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && | 2160 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && |
2161 (instr->Bit(4) == 1)) { | 2161 (instr->Bit(4) == 1)) { |
2162 // vmovl unsigned | 2162 // vmovl unsigned |
2163 if ((instr->VdValue() & 1) != 0) Unknown(instr); | 2163 if ((instr->VdValue() & 1) != 0) Unknown(instr); |
2164 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); | 2164 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); |
2165 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); | 2165 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); |
2166 int imm3 = instr->Bits(21, 19); | 2166 int imm3 = instr->Bits(21, 19); |
2167 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 2167 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
2168 "vmovl.u%d q%d, d%d", imm3 * 8, Vd, Vm); | 2168 "vmovl.u%d q%d, d%d", imm3 * 8, Vd, Vm); |
2169 } else if (instr->Opc1Value() == 7 && instr->Bit(4) == 0) { | 2169 } else if (instr->Opc1Value() == 7 && instr->Bit(4) == 0) { |
2170 if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 7) == 0) { | 2170 if (instr->Bits(11, 7) == 0x18) { |
2171 if (instr->Bit(6) == 0) { | |
2172 int Vd = instr->VFPDRegValue(kDoublePrecision); | |
2173 int Vm = instr->VFPMRegValue(kDoublePrecision); | |
2174 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2175 "vswp d%d, d%d", Vd, Vm); | |
2176 } else { | |
2177 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2178 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2179 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2180 "vswp q%d, q%d", Vd, Vm); | |
2181 } | |
2182 } else if (instr->Bits(11, 7) == 0x18) { | |
2183 int Vd = instr->VFPDRegValue(kSimd128Precision); | 2171 int Vd = instr->VFPDRegValue(kSimd128Precision); |
2184 int Vm = instr->VFPMRegValue(kDoublePrecision); | 2172 int Vm = instr->VFPMRegValue(kDoublePrecision); |
2185 int index = instr->Bit(19); | 2173 int index = instr->Bit(19); |
2186 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | 2174 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
2187 "vdup q%d, d%d[%d]", Vd, Vm, index); | 2175 "vdup q%d, d%d[%d]", Vd, Vm, index); |
2188 } else if (instr->Bits(19, 16) == 0 && instr->Bits(11, 6) == 0x17) { | |
2189 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2190 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2191 out_buffer_pos_ += | |
2192 SNPrintF(out_buffer_ + out_buffer_pos_, "vmvn q%d, q%d", Vd, Vm); | |
2193 } else if (instr->Bits(19, 16) == 0xB && instr->Bits(11, 9) == 0x3 && | |
2194 instr->Bit(6) == 1) { | |
2195 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2196 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2197 const char* suffix = nullptr; | |
2198 int op = instr->Bits(8, 7); | |
2199 switch (op) { | |
2200 case 0: | |
2201 suffix = "f32.s32"; | |
2202 break; | |
2203 case 1: | |
2204 suffix = "f32.u32"; | |
2205 break; | |
2206 case 2: | |
2207 suffix = "s32.f32"; | |
2208 break; | |
2209 case 3: | |
2210 suffix = "u32.f32"; | |
2211 break; | |
2212 } | |
2213 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2214 "vcvt.%s q%d, q%d", suffix, Vd, Vm); | |
2215 } else if (instr->Bits(11, 10) == 0x2) { | 2176 } else if (instr->Bits(11, 10) == 0x2) { |
2216 int Vd = instr->VFPDRegValue(kDoublePrecision); | 2177 int Vd = instr->VFPDRegValue(kDoublePrecision); |
2217 int Vn = instr->VFPNRegValue(kDoublePrecision); | 2178 int Vn = instr->VFPNRegValue(kDoublePrecision); |
2218 int Vm = instr->VFPMRegValue(kDoublePrecision); | 2179 int Vm = instr->VFPMRegValue(kDoublePrecision); |
2219 int len = instr->Bits(9, 8); | 2180 int len = instr->Bits(9, 8); |
2220 NeonListOperand list(DwVfpRegister::from_code(Vn), len + 1); | 2181 NeonListOperand list(DwVfpRegister::from_code(Vn), len + 1); |
2221 out_buffer_pos_ += | 2182 out_buffer_pos_ += |
2222 SNPrintF(out_buffer_ + out_buffer_pos_, "%s d%d, ", | 2183 SNPrintF(out_buffer_ + out_buffer_pos_, "%s d%d, ", |
2223 instr->Bit(6) == 0 ? "vtbl.8" : "vtbx.8", Vd); | 2184 instr->Bit(6) == 0 ? "vtbl.8" : "vtbx.8", Vd); |
2224 FormatNeonList(Vn, list.type()); | 2185 FormatNeonList(Vn, list.type()); |
2225 Print(", "); | 2186 Print(", "); |
2226 PrintDRegister(Vm); | 2187 PrintDRegister(Vm); |
2227 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x1 && | |
2228 instr->Bit(6) == 1) { | |
2229 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2230 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2231 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); | |
2232 const char* op = instr->Bit(7) != 0 ? "vzip" : "vuzp"; | |
2233 // vzip/vuzp.<size> Qd, Qm. | |
2234 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2235 "%s.%d q%d, q%d", op, size, Vd, Vm); | |
2236 } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0 && | |
2237 instr->Bit(6) == 1) { | |
2238 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2239 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2240 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); | |
2241 int op = kBitsPerByte | |
2242 << (static_cast<int>(Neon64) - instr->Bits(8, 7)); | |
2243 // vrev<op>.<size> Qd, Qm. | |
2244 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2245 "vrev%d.%d q%d, q%d", op, size, Vd, Vm); | |
2246 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x3) { | |
2247 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2248 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2249 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); | |
2250 // vtrn.<size> Qd, Qm. | |
2251 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2252 "vtrn.%d q%d, q%d", size, Vd, Vm); | |
2253 } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0 && | |
2254 instr->Bit(6) == 1) { | |
2255 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2256 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2257 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); | |
2258 char type = instr->Bit(10) != 0 ? 'f' : 's'; | |
2259 if (instr->Bits(9, 6) == 0xd) { | |
2260 // vabs<type>.<size> Qd, Qm. | |
2261 out_buffer_pos_ += | |
2262 SNPrintF(out_buffer_ + out_buffer_pos_, "vabs.%c%d q%d, q%d", | |
2263 type, size, Vd, Vm); | |
2264 } else if (instr->Bits(9, 6) == 0xf) { | |
2265 // vneg<type>.<size> Qd, Qm. | |
2266 out_buffer_pos_ += | |
2267 SNPrintF(out_buffer_ + out_buffer_pos_, "vneg.%c%d q%d, q%d", | |
2268 type, size, Vd, Vm); | |
2269 } else { | |
2270 Unknown(instr); | |
2271 } | |
2272 } else if (instr->Bits(19, 18) == 0x2 && instr->Bits(11, 8) == 0x5 && | |
2273 instr->Bit(6) == 1) { | |
2274 // vrecpe/vrsqrte.f32 Qd, Qm. | |
2275 int Vd = instr->VFPDRegValue(kSimd128Precision); | |
2276 int Vm = instr->VFPMRegValue(kSimd128Precision); | |
2277 const char* op = instr->Bit(7) == 0 ? "vrecpe" : "vrsqrte"; | |
2278 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, | |
2279 "%s.f32 q%d, q%d", op, Vd, Vm); | |
2280 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x2 && | 2188 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x2 && |
2281 instr->Bits(7, 6) != 0) { | 2189 instr->Bits(7, 6) != 0) { |
2282 // vqmovn.<type><size> Dd, Qm. | 2190 // vqmovn.<type><size> Dd, Qm. |
2283 int Vd = instr->VFPDRegValue(kDoublePrecision); | 2191 int Vd = instr->VFPDRegValue(kDoublePrecision); |
2284 int Vm = instr->VFPMRegValue(kSimd128Precision); | 2192 int Vm = instr->VFPMRegValue(kSimd128Precision); |
2285 char type = instr->Bit(6) != 0 ? 'u' : 's'; | 2193 char type = instr->Bit(6) != 0 ? 'u' : 's'; |
2286 int size = 2 * kBitsPerByte * (1 << instr->Bits(19, 18)); | 2194 int size = 2 * kBitsPerByte * (1 << instr->Bits(19, 18)); |
2287 out_buffer_pos_ += | 2195 out_buffer_pos_ += |
2288 SNPrintF(out_buffer_ + out_buffer_pos_, "vqmovn.%c%i d%d, q%d", | 2196 SNPrintF(out_buffer_ + out_buffer_pos_, "vqmovn.%c%i d%d, q%d", |
2289 type, size, Vd, Vm); | 2197 type, size, Vd, Vm); |
2290 } else { | 2198 } else { |
2291 Unknown(instr); | 2199 int Vd, Vm; |
| 2200 if (instr->Bit(6) == 0) { |
| 2201 Vd = instr->VFPDRegValue(kDoublePrecision); |
| 2202 Vm = instr->VFPMRegValue(kDoublePrecision); |
| 2203 } else { |
| 2204 Vd = instr->VFPDRegValue(kSimd128Precision); |
| 2205 Vm = instr->VFPMRegValue(kSimd128Precision); |
| 2206 } |
| 2207 if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 7) == 0) { |
| 2208 if (instr->Bit(6) == 0) { |
| 2209 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2210 "vswp d%d, d%d", Vd, Vm); |
| 2211 } else { |
| 2212 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2213 "vswp q%d, q%d", Vd, Vm); |
| 2214 } |
| 2215 } else if (instr->Bits(19, 16) == 0 && instr->Bits(11, 6) == 0x17) { |
| 2216 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2217 "vmvn q%d, q%d", Vd, Vm); |
| 2218 } else if (instr->Bits(19, 16) == 0xB && instr->Bits(11, 9) == 0x3 && |
| 2219 instr->Bit(6) == 1) { |
| 2220 const char* suffix = nullptr; |
| 2221 int op = instr->Bits(8, 7); |
| 2222 switch (op) { |
| 2223 case 0: |
| 2224 suffix = "f32.s32"; |
| 2225 break; |
| 2226 case 1: |
| 2227 suffix = "f32.u32"; |
| 2228 break; |
| 2229 case 2: |
| 2230 suffix = "s32.f32"; |
| 2231 break; |
| 2232 case 3: |
| 2233 suffix = "u32.f32"; |
| 2234 break; |
| 2235 } |
| 2236 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2237 "vcvt.%s q%d, q%d", suffix, Vd, Vm); |
| 2238 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 8) == 0x1) { |
| 2239 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); |
| 2240 const char* op = instr->Bit(7) != 0 ? "vzip" : "vuzp"; |
| 2241 if (instr->Bit(6) == 0) { |
| 2242 // vzip/vuzp.<size> Dd, Dm. |
| 2243 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2244 "%s.%d d%d, d%d", op, size, Vd, Vm); |
| 2245 } else { |
| 2246 // vzip/vuzp.<size> Qd, Qm. |
| 2247 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2248 "%s.%d q%d, q%d", op, size, Vd, Vm); |
| 2249 } |
| 2250 } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0 && |
| 2251 instr->Bit(6) == 1) { |
| 2252 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); |
| 2253 int op = kBitsPerByte |
| 2254 << (static_cast<int>(Neon64) - instr->Bits(8, 7)); |
| 2255 // vrev<op>.<size> Qd, Qm. |
| 2256 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2257 "vrev%d.%d q%d, q%d", op, size, Vd, Vm); |
| 2258 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 7) == 0x1) { |
| 2259 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); |
| 2260 if (instr->Bit(6) == 0) { |
| 2261 // vtrn.<size> Dd, Dm. |
| 2262 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2263 "vtrn.%d d%d, d%d", size, Vd, Vm); |
| 2264 } else { |
| 2265 // vtrn.<size> Qd, Qm. |
| 2266 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2267 "vtrn.%d q%d, q%d", size, Vd, Vm); |
| 2268 } |
| 2269 } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0 && |
| 2270 instr->Bit(6) == 1) { |
| 2271 int size = kBitsPerByte * (1 << instr->Bits(19, 18)); |
| 2272 char type = instr->Bit(10) != 0 ? 'f' : 's'; |
| 2273 if (instr->Bits(9, 6) == 0xd) { |
| 2274 // vabs<type>.<size> Qd, Qm. |
| 2275 out_buffer_pos_ += |
| 2276 SNPrintF(out_buffer_ + out_buffer_pos_, "vabs.%c%d q%d, q%d", |
| 2277 type, size, Vd, Vm); |
| 2278 } else if (instr->Bits(9, 6) == 0xf) { |
| 2279 // vneg<type>.<size> Qd, Qm. |
| 2280 out_buffer_pos_ += |
| 2281 SNPrintF(out_buffer_ + out_buffer_pos_, "vneg.%c%d q%d, q%d", |
| 2282 type, size, Vd, Vm); |
| 2283 } else { |
| 2284 Unknown(instr); |
| 2285 } |
| 2286 } else if (instr->Bits(19, 18) == 0x2 && instr->Bits(11, 8) == 0x5 && |
| 2287 instr->Bit(6) == 1) { |
| 2288 // vrecpe/vrsqrte.f32 Qd, Qm. |
| 2289 const char* op = instr->Bit(7) == 0 ? "vrecpe" : "vrsqrte"; |
| 2290 out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, |
| 2291 "%s.f32 q%d, q%d", op, Vd, Vm); |
| 2292 } else { |
| 2293 Unknown(instr); |
| 2294 } |
2292 } | 2295 } |
2293 } else if (instr->Bits(11, 7) == 0 && instr->Bit(4) == 1 && | 2296 } else if (instr->Bits(11, 7) == 0 && instr->Bit(4) == 1 && |
2294 instr->Bit(6) == 1) { | 2297 instr->Bit(6) == 1) { |
2295 // vshr.u<size> Qd, Qm, shift | 2298 // vshr.u<size> Qd, Qm, shift |
2296 int size = base::bits::RoundDownToPowerOfTwo32(instr->Bits(21, 16)); | 2299 int size = base::bits::RoundDownToPowerOfTwo32(instr->Bits(21, 16)); |
2297 int shift = 2 * size - instr->Bits(21, 16); | 2300 int shift = 2 * size - instr->Bits(21, 16); |
2298 int Vd = instr->VFPDRegValue(kSimd128Precision); | 2301 int Vd = instr->VFPDRegValue(kSimd128Precision); |
2299 int Vm = instr->VFPMRegValue(kSimd128Precision); | 2302 int Vm = instr->VFPMRegValue(kSimd128Precision); |
2300 out_buffer_pos_ += | 2303 out_buffer_pos_ += |
2301 SNPrintF(out_buffer_ + out_buffer_pos_, "vshr.u%d q%d, q%d, #%d", | 2304 SNPrintF(out_buffer_ + out_buffer_pos_, "vshr.u%d q%d, q%d, #%d", |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2638 pc += d.InstructionDecode(buffer, pc); | 2641 pc += d.InstructionDecode(buffer, pc); |
2639 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), | 2642 v8::internal::PrintF(f, "%p %08x %s\n", static_cast<void*>(prev_pc), |
2640 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); | 2643 *reinterpret_cast<int32_t*>(prev_pc), buffer.start()); |
2641 } | 2644 } |
2642 } | 2645 } |
2643 | 2646 |
2644 | 2647 |
2645 } // namespace disasm | 2648 } // namespace disasm |
2646 | 2649 |
2647 #endif // V8_TARGET_ARCH_ARM | 2650 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |