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 35namespace ark::es2panda::ir { 36class AstNode; 37} // namespace ark::es2panda::ir 38 39namespace ark::es2panda::compiler { 40enum 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 52enum 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 60struct OutVReg { 61 const VReg *reg; 62 OperandType type; 63}; 64 65class FormatItem { 66public: 67 constexpr FormatItem(OperandKind kind, uint32_t bitWidth) : kind_(kind), bitWidth_(bitWidth) {} 68 69 OperandKind Kind() const 70 { 71 return kind_; 72 }; 73 74 bool constexpr IsVReg() const 75 { 76 return kind_ == OperandKind::SRC_VREG || kind_ == OperandKind::DST_VREG || kind_ == OperandKind::SRC_DST_VREG; 77 } 78 79 uint32_t BitWidth() const 80 { 81 return bitWidth_; 82 }; 83 84private: 85 OperandKind kind_; 86 uint32_t bitWidth_; 87}; 88 89class Format { 90public: 91 constexpr Format(const FormatItem *item, size_t size) : item_(item), size_(size) {} 92 93 ark::Span<const FormatItem> GetFormatItem() const 94 { 95 return ark::Span<const FormatItem>(item_, size_); 96 } 97 98private: 99 const FormatItem *item_; 100 size_t size_; 101}; 102 103using Formats = ark::Span<const Format>; 104 105class Label; 106class IRNode; 107 108using 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 113class IRNode { 114public: 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 121 const ir::AstNode *Node() const 122 { 123 return node_; 124 } 125 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 155private: 156 const ir::AstNode *node_; 157}; 158} // namespace ark::es2panda::compiler 159 160#endif 161