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 ES2PANDA_COMPILER_IR_IRNODE_H
17#define ES2PANDA_COMPILER_IR_IRNODE_H
18
19#include <lexer/token/sourceLocation.h>
20#include <macros.h>
21#include <util/ustring.h>
22#include <utils/span.h>
23
24#include <cstdint>
25#include <list>
26#include <sstream>
27#include <utility>
28#include <variant>
29#include <vector>
30
31namespace panda::es2panda::ir {
32class AstNode;
33}  // namespace panda::es2panda::ir
34
35namespace panda::pandasm {
36struct Ins;
37}  // namespace panda::pandasm
38
39namespace panda::es2panda::compiler {
40
41enum class OperandKind {
42    // the least significant bit indicates vreg
43    // the second bit indicates src or dst
44    SRC_VREG,
45    DST_VREG,
46    SRC_DST_VREG,
47    IMM,
48    ID,
49    STRING_ID,
50    LABEL
51};
52
53class FormatItem {
54public:
55    constexpr FormatItem(OperandKind kind, uint32_t bitwidth) : kind_(kind), bitwidth_(bitwidth) {}
56
57    OperandKind Kind() const
58    {
59        return kind_;
60    };
61
62    bool constexpr IsVReg() const
63    {
64        return kind_ == OperandKind::SRC_VREG || kind_ == OperandKind::DST_VREG || kind_ == OperandKind::SRC_DST_VREG;
65    }
66
67    uint32_t Bitwidth() const
68    {
69        return bitwidth_;
70    };
71
72private:
73    OperandKind kind_;
74    uint32_t bitwidth_;
75};
76
77class Format {
78public:
79    constexpr Format(const FormatItem *item, size_t size) : item_(item), size_(size) {}
80
81    panda::Span<const FormatItem> GetFormatItem() const
82    {
83        return panda::Span<const FormatItem>(item_, size_);
84    }
85
86private:
87    const FormatItem *item_;
88    size_t size_;
89};
90
91using Formats = panda::Span<const Format>;
92using VReg = uint16_t;
93
94class Label;
95class IRNode;
96
97using Operand = std::variant<compiler::VReg, double, int64_t, util::StringView, Label *>;
98
99#define FIRST_NODE_OF_FUNCTION (reinterpret_cast<ir::AstNode *>(0x1))
100
101using ICSlot = uint16_t;
102
103using IcSizeType = uint32_t;
104
105class IRNode {
106public:
107    explicit IRNode(const ir::AstNode *node) : node_(node) {};
108    virtual ~IRNode() = default;
109
110    NO_COPY_SEMANTIC(IRNode);
111    NO_MOVE_SEMANTIC(IRNode);
112
113    const ir::AstNode *Node() const
114    {
115        return node_;
116    }
117
118    static constexpr auto MAX_REG_OPERAND = 5;
119
120    virtual Formats GetFormats() const = 0;
121    virtual size_t Registers([[maybe_unused]] std::array<VReg *, MAX_REG_OPERAND> *regs) = 0;
122    virtual size_t Registers([[maybe_unused]] std::array<const VReg *, MAX_REG_OPERAND> *regs) const = 0;
123    virtual void Transform(panda::pandasm::Ins *ins) const = 0;
124    virtual ICSlot SetIcSlot(IcSizeType currentSlot) = 0;
125    virtual bool InlineCacheEnabled() = 0;
126    virtual ICSlot GetIcSlot() = 0;
127    virtual bool oneByteSlotOnly() = 0;
128    virtual uint8_t IcSlots() = 0;
129
130    virtual bool IsRangeInst() const
131    {
132        return false;
133    }
134
135    virtual int64_t RangeRegsCount()
136    {
137        return 0;
138    }
139
140private:
141    const ir::AstNode *node_;
142};
143
144}  // namespace panda::es2panda::compiler
145
146#endif
147