1 /** 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef PANDA_DISASSEMBLY_H 17 #define PANDA_DISASSEMBLY_H 18 19 #include <fstream> 20 #include <string> 21 #include <variant> 22 #include <memory> 23 #include "compiler_options.h" 24 #include "macros.h" 25 26 namespace panda::compiler { 27 28 class Codegen; 29 class Encoder; 30 class Inst; 31 class StackMap; 32 33 class Disassembly { 34 public: 35 explicit Disassembly(const Codegen *codegen); 36 ~Disassembly() = default; 37 NO_COPY_SEMANTIC(Disassembly); 38 NO_MOVE_SEMANTIC(Disassembly); 39 40 void Init(); 41 GetStream()42 std::ostream &GetStream() 43 { 44 return *stream_; 45 } GetDepth()46 uint32_t GetDepth() const 47 { 48 return depth_; 49 } GetPosition()50 uint32_t GetPosition() const 51 { 52 return position_; 53 } SetPosition(uint32_t pos)54 void SetPosition(uint32_t pos) 55 { 56 position_ = pos; 57 } GetEncoder()58 const Encoder *GetEncoder() const 59 { 60 return encoder_; 61 } SetEncoder(const Encoder * encoder)62 void SetEncoder(const Encoder *encoder) 63 { 64 encoder_ = encoder; 65 } 66 void IncreaseDepth(); DecreaseDepth()67 void DecreaseDepth() 68 { 69 depth_--; 70 } IsEnabled()71 bool IsEnabled() const 72 { 73 return is_enabled_; 74 } IsCodeEnabled()75 bool IsCodeEnabled() const 76 { 77 return is_code_enabled_; 78 } 79 80 void PrintMethodEntry(const Codegen *codegen); 81 void PrintCodeInfo(const Codegen *codegen); 82 void PrintCodeStatistics(const Codegen *codegen); 83 void PrintStackMap(const Codegen *codegen); 84 85 private: 86 void FlushDisasm(const Codegen *codegen); 87 88 private: 89 using StreamDeleterType = void (*)(std::ostream *stream); 90 const Codegen *codegen_ {nullptr}; 91 const Encoder *encoder_ {nullptr}; 92 std::unique_ptr<std::ostream, StreamDeleterType> stream_; 93 uint32_t depth_ {0}; 94 uint32_t position_ {0}; 95 bool is_enabled_ {false}; 96 bool is_code_enabled_ {false}; 97 98 friend class ScopedDisasmPrinter; 99 }; 100 101 class ScopedDisasmPrinter { 102 public: 103 ScopedDisasmPrinter(Codegen *codegen, const std::string &msg); 104 ScopedDisasmPrinter(Codegen *codegen, const Inst *inst); 105 ~ScopedDisasmPrinter(); 106 107 NO_COPY_SEMANTIC(ScopedDisasmPrinter); 108 NO_MOVE_SEMANTIC(ScopedDisasmPrinter); 109 110 private: 111 Disassembly *disasm_ {nullptr}; 112 }; 113 114 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 115 #define DISASM_VAR_CONCAT2(a, b) a##b 116 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 117 #define DISASM_VAR_CONCAT(a, b) DISASM_VAR_CONCAT2(a, b) 118 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 119 #define SCOPED_DISASM_INST(codegen, inst) ScopedDisasmPrinter DISASM_VAR_CONCAT(disasm_, __LINE__)(codegen, inst) 120 #ifndef NDEBUG 121 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 122 #define SCOPED_DISASM_STR(codegen, str) ScopedDisasmPrinter DISASM_VAR_CONCAT(disasm_, __LINE__)(codegen, str) 123 #else 124 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 125 #define SCOPED_DISASM_STR(codegen, str) (void)codegen 126 #endif 127 128 } // namespace panda::compiler 129 130 #endif // PANDA_DISASSEMBLY_H 131