1 /** 2 * Copyright (c) 2021-2024 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 ES2PANDA_COMPILER_IR_IRNODE_H 17 #define ES2PANDA_COMPILER_IR_IRNODE_H 18 19 #include "compiler/base/literals.h" 20 #include "compiler/core/vReg.h" 21 #include "compiler/core/programElement.h" 22 #include "lexer/token/sourceLocation.h" 23 #include "macros.h" 24 #include "util/ustring.h" 25 #include "utils/span.h" 26 27 #include <cstdint> 28 #include <list> 29 #include <limits> 30 #include <sstream> 31 #include <utility> 32 #include <variant> 33 #include <vector> 34 35 namespace ark::es2panda::ir { 36 class AstNode; 37 } // namespace ark::es2panda::ir 38 39 namespace ark::es2panda::compiler { 40 enum class OperandKind { 41 // the least significant bit indicates vreg 42 // the second bit indicates src or dst 43 SRC_VREG, 44 DST_VREG, 45 SRC_DST_VREG, 46 IMM, 47 ID, 48 STRING_ID, 49 LABEL 50 }; 51 52 enum class OperandType { 53 REF, // ref 54 B32, // u1 u2 i8 u8 i16 u16 i32 u32 b32 f32 55 B64, // i64, f64, b64 56 ANY, // any 57 NONE 58 }; 59 60 struct OutVReg { 61 const VReg *reg; 62 OperandType type; 63 }; 64 65 class FormatItem { 66 public: FormatItem(OperandKind kind, uint32_t bitWidth)67 constexpr FormatItem(OperandKind kind, uint32_t bitWidth) : kind_(kind), bitWidth_(bitWidth) {} 68 Kind() const69 OperandKind Kind() const 70 { 71 return kind_; 72 }; 73 IsVReg() const74 bool constexpr IsVReg() const 75 { 76 return kind_ == OperandKind::SRC_VREG || kind_ == OperandKind::DST_VREG || kind_ == OperandKind::SRC_DST_VREG; 77 } 78 BitWidth() const79 uint32_t BitWidth() const 80 { 81 return bitWidth_; 82 }; 83 84 private: 85 OperandKind kind_; 86 uint32_t bitWidth_; 87 }; 88 89 class Format { 90 public: Format(const FormatItem *item, size_t size)91 constexpr Format(const FormatItem *item, size_t size) : item_(item), size_(size) {} 92 GetFormatItem() const93 ark::Span<const FormatItem> GetFormatItem() const 94 { 95 return ark::Span<const FormatItem>(item_, size_); 96 } 97 98 private: 99 const FormatItem *item_; 100 size_t size_; 101 }; 102 103 using Formats = ark::Span<const Format>; 104 105 class Label; 106 class IRNode; 107 108 using Operand = std::variant<compiler::VReg, double, int64_t, util::StringView, Label *>; 109 110 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage) 111 #define FIRST_NODE_OF_FUNCTION (reinterpret_cast<ir::AstNode *>(0x1)) 112 113 class IRNode { 114 public: IRNode(const ir::AstNode *node)115 explicit IRNode(const ir::AstNode *node) : node_(node) {}; 116 virtual ~IRNode() = default; 117 118 NO_COPY_SEMANTIC(IRNode); 119 NO_MOVE_SEMANTIC(IRNode); 120 Node() const121 const ir::AstNode *Node() const 122 { 123 return node_; 124 } 125 MapRegister(uint32_t reg, uint32_t totalRegs)126 static uint16_t MapRegister(uint32_t reg, uint32_t totalRegs) 127 { 128 ASSERT(reg != VReg::Invalid().GetIndex()); 129 130 uint32_t regCount = VReg::REG_START - totalRegs; 131 uint16_t newReg = 0; 132 133 if (reg >= VReg::PARAM_START) { 134 newReg = reg - VReg::PARAM_START + regCount; 135 // NOTE: dbatiz. Remove this else if, and fix the regIndexes 136 } else if (reg <= regCount + VReg::MANDATORY_PARAM_NUM) { 137 newReg = VReg::REG_START - totalRegs + VReg::MANDATORY_PARAM_NUM + reg; 138 } else { 139 uint32_t regOffset = reg - totalRegs; 140 newReg = std::abs(static_cast<int32_t>(regOffset - regCount)); 141 } 142 143 return newReg; 144 } 145 146 static constexpr auto MAX_REG_OPERAND = 5; 147 148 virtual Formats GetFormats() const = 0; 149 virtual size_t Registers([[maybe_unused]] std::array<VReg *, MAX_REG_OPERAND> *regs) = 0; 150 virtual size_t Registers([[maybe_unused]] std::array<const VReg *, MAX_REG_OPERAND> *regs) const = 0; 151 virtual size_t OutRegisters([[maybe_unused]] std::array<OutVReg, MAX_REG_OPERAND> *regs) const = 0; 152 virtual void Transform(ark::pandasm::Ins *ins, [[maybe_unused]] ProgramElement *programElement, 153 [[maybe_unused]] uint32_t totalRegs) const = 0; 154 155 private: 156 const ir::AstNode *node_; 157 }; 158 } // namespace ark::es2panda::compiler 159 160 #endif 161