Bug 1867190 - Add prefs for PHC probablities r=glandium
[gecko.git] / js / src / jit / Disassemble.cpp
blob6026df27d6bb5fa8a758880d52d41bcecdcbdae4
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "jit/Disassemble.h"
9 #include <stddef.h> // size_t
10 #include <stdint.h> // uint8_t, int32_t
12 #include "js/Printf.h" // JS_smprintf
13 #include "js/Utility.h" // JS::UniqueChars
15 #if defined(JS_JITSPEW)
16 # if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
17 # include "zydis/ZydisAPI.h" // zydisDisassemble
18 # elif defined(JS_CODEGEN_ARM64)
19 # include "jit/arm/disasm/Disasm-arm.h" // js::jit::disasm::*
20 # include "jit/arm64/vixl/Decoder-vixl.h" // vixl::Decoder
21 # include "jit/arm64/vixl/Disasm-vixl.h" // vixl::Disassembler
22 # include "jit/arm64/vixl/Instructions-vixl.h" // vixl::Instruction
23 # elif defined(JS_CODEGEN_ARM)
24 # include "jit/arm/disasm/Disasm-arm.h" // js::jit::disasm::*
25 # endif
26 #endif
28 namespace js {
29 namespace jit {
31 #if defined(JS_JITSPEW) && (defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64))
33 bool HasDisassembler() { return true; }
35 void Disassemble(uint8_t* code, size_t length, InstrCallback callback) {
36 zydisDisassemble(code, length, callback);
39 #elif defined(JS_JITSPEW) && defined(JS_CODEGEN_ARM64)
41 class ARM64Disassembler : public vixl::Disassembler {
42 public:
43 explicit ARM64Disassembler(InstrCallback callback) : callback_(callback) {}
45 protected:
46 void ProcessOutput(const vixl::Instruction* instr) override {
47 JS::UniqueChars formatted = JS_smprintf(
48 "0x%p %08x %s", instr, instr->InstructionBits(), GetOutput());
49 callback_(formatted.get());
52 private:
53 InstrCallback callback_;
56 bool HasDisassembler() { return true; }
58 void Disassemble(uint8_t* code, size_t length, InstrCallback callback) {
59 ARM64Disassembler dis(callback);
60 vixl::Decoder decoder;
61 decoder.AppendVisitor(&dis);
63 uint8_t* instr = code;
64 uint8_t* end = code + length;
66 while (instr < end) {
67 decoder.Decode(reinterpret_cast<vixl::Instruction*>(instr));
69 instr += sizeof(vixl::Instr);
73 #elif defined(JS_JITSPEW) && defined(JS_CODEGEN_ARM)
75 bool HasDisassembler() { return true; }
77 void Disassemble(uint8_t* code, size_t length, InstrCallback callback) {
78 disasm::NameConverter converter;
79 disasm::Disassembler d(converter);
81 uint8_t* instr = code;
82 uint8_t* end = code + length;
84 while (instr < end) {
85 disasm::EmbeddedVector<char, disasm::ReasonableBufferSize> buffer;
86 buffer[0] = '\0';
87 uint8_t* next_instr = instr + d.InstructionDecode(buffer, instr);
89 JS::UniqueChars formatted =
90 JS_smprintf("0x%p %08x %s", instr, *reinterpret_cast<int32_t*>(instr),
91 buffer.start());
92 callback(formatted.get());
94 instr = next_instr;
98 #else
100 bool HasDisassembler() { return false; }
102 void Disassemble(uint8_t* code, size_t length, InstrCallback callback) {
103 callback("*** No disassembly available ***\n");
106 #endif
108 } // namespace jit
109 } // namespace js