xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/r600/sfn/sfn_instr_alu.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /* -*- mesa-c++  -*-
2  * Copyright 2022 Collabora LTD
3  * Author: Gert Wollny <[email protected]>
4  * SPDX-License-Identifier: MIT
5  */
6 
7 #ifndef INSTRALU_H
8 #define INSTRALU_H
9 
10 #include "sfn_instr.h"
11 
12 #include <unordered_set>
13 
14 struct nir_alu_instr;
15 
16 namespace r600 {
17 
18 class Shader;
19 class ValueFactory;
20 
21 class AluInstr : public Instr {
22 public:
23    using SrcValues = std::vector<PVirtualValue, Allocator<PVirtualValue>>;
24 
25    enum Op2Options {
26       op2_opt_none = 0,
27       op2_opt_reverse = 1,
28       op2_opt_neg_src1 = 1 << 1,
29       op2_opt_abs_src0 = 1 << 2
30    };
31 
32    enum SourceMod {
33       mod_none = 0,
34       mod_abs = 1,
35       mod_neg = 2
36    };
37 
38 
39    static constexpr const AluBankSwizzle bs[6] = {
40       alu_vec_012, alu_vec_021, alu_vec_120, alu_vec_102, alu_vec_201, alu_vec_210};
41 
42    static const AluModifiers src_abs_flags[2];
43    static const AluModifiers src_neg_flags[3];
44    static const AluModifiers src_rel_flags[3];
45 
46    AluInstr(EAluOp opcode);
47    AluInstr(EAluOp opcode, int chan);
48    AluInstr(EAluOp opcode,
49             PRegister dest,
50             SrcValues src0,
51             const std::set<AluModifiers>& flags,
52             int alu_slot);
53 
54    AluInstr(EAluOp opcode,
55             PRegister dest,
56             PVirtualValue src0,
57             const std::set<AluModifiers>& flags);
58 
59    AluInstr(EAluOp opcode,
60             PRegister dest,
61             PVirtualValue src0,
62             PVirtualValue src1,
63             const std::set<AluModifiers>& flags);
64 
65    AluInstr(EAluOp opcode,
66             PRegister dest,
67             PVirtualValue src0,
68             PVirtualValue src1,
69             PVirtualValue src2,
70             const std::set<AluModifiers>& flags);
71 
72    AluInstr(ESDOp op, PVirtualValue src0, PVirtualValue src1, PVirtualValue address);
73    AluInstr(ESDOp op, const SrcValues& src, const std::set<AluModifiers>& flags);
74 
75    void accept(ConstInstrVisitor& visitor) const override;
76    void accept(InstrVisitor& visitor) override;
77 
opcode()78    auto opcode() const
79    {
80       assert(!has_alu_flag(alu_is_lds));
81       return m_opcode;
82    }
lds_opcode()83    auto lds_opcode() const
84    {
85       assert(has_alu_flag(alu_is_lds));
86       return m_lds_opcode;
87    }
88 
89    bool can_propagate_src() const;
90    bool can_propagate_dest() const;
91 
92    bool replace_source(PRegister old_src, PVirtualValue new_src) override;
93    bool replace_dest(PRegister new_dest, AluInstr *move_instr) override;
94 
95    bool can_replace_source(PRegister old_src, PVirtualValue new_src);
96    bool do_replace_source(PRegister old_src, PVirtualValue new_src);
97 
set_op(EAluOp op)98    void set_op(EAluOp op) { m_opcode = op; }
99 
dest()100    PRegister dest() const { return m_dest; }
n_sources()101    unsigned n_sources() const { return m_src.size(); }
102 
dest_chan()103    int dest_chan() const { return m_dest ? m_dest->chan() : m_fallback_chan; }
104 
psrc(unsigned i)105    const VirtualValue *psrc(unsigned i) const { return i < m_src.size() ? m_src[i] : nullptr; }
psrc(unsigned i)106    PVirtualValue psrc(unsigned i) { return i < m_src.size() ? m_src[i] : nullptr; }
src(unsigned i)107    VirtualValue& src(unsigned i)
108    {
109       assert(i < m_src.size() && m_src[i]);
110       return *m_src[i];
111    }
src(unsigned i)112    const VirtualValue& src(unsigned i) const
113    {
114       assert(i < m_src.size() && m_src[i]);
115       return *m_src[i];
116    }
117 
118    void set_sources(SrcValues src);
sources()119    const SrcValues& sources() const { return m_src; }
120    void pin_sources_to_chan();
121 
122    int register_priority() const;
123 
reset_alu_flag(AluModifiers flag)124    void reset_alu_flag(AluModifiers flag) { m_alu_flags.reset(flag); }
set_alu_flag(AluModifiers flag)125    void set_alu_flag(AluModifiers flag) { m_alu_flags.set(flag); }
has_alu_flag(AluModifiers f)126    bool has_alu_flag(AluModifiers f) const { return m_alu_flags.test(f); }
127 
cf_type()128    ECFAluOpCode cf_type() const { return m_cf_type; }
set_cf_type(ECFAluOpCode cf_type)129    void set_cf_type(ECFAluOpCode cf_type) { m_cf_type = cf_type; }
set_bank_swizzle(AluBankSwizzle swz)130    void set_bank_swizzle(AluBankSwizzle swz) { m_bank_swizzle = swz; }
bank_swizzle()131    AluBankSwizzle bank_swizzle() const { return m_bank_swizzle; }
132 
set_index_offset(unsigned offs)133    void set_index_offset(unsigned offs) { m_idx_offset = offs; }
index_offset()134    auto index_offset() const { return m_idx_offset; }
135 
136    bool is_equal_to(const AluInstr& lhs) const;
137 
138    bool has_lds_access() const;
139    bool has_lds_queue_read() const;
140    bool is_kill() const;
141 
142    static const std::map<ECFAluOpCode, std::string> cf_map;
143    static const std::map<AluBankSwizzle, std::string> bank_swizzle_map;
144    static Instr::Pointer
145    from_string(std::istream& is, ValueFactory& value_factory, AluGroup *, bool is_cayman);
146    static bool from_nir(nir_alu_instr *alu, Shader& shader);
147 
alu_slots()148    int alu_slots() const { return m_alu_slots; }
149 
150    AluGroup *split(ValueFactory& vf);
151 
end_group()152    bool end_group() const override { return m_alu_flags.test(alu_last_instr); }
153 
154    static const std::set<AluModifiers> empty;
155    static const std::set<AluModifiers> write;
156    static const std::set<AluModifiers> last;
157    static const std::set<AluModifiers> last_write;
158 
159    std::tuple<PRegister, bool, PRegister> indirect_addr() const;
160    void update_indirect_addr(PRegister old_reg, PRegister reg) override;
161 
162    void add_extra_dependency(PVirtualValue reg);
163 
set_required_slots(int nslots)164    void set_required_slots(int nslots) { m_required_slots = nslots; }
required_slots()165    unsigned required_slots() const { return m_required_slots; }
166 
add_priority(int priority)167    void add_priority(int priority) { m_priority += priority; }
priority()168    int priority() const { return m_priority; }
inc_priority()169    void inc_priority() { ++m_priority; }
170 
set_parent_group(AluGroup * group)171    void set_parent_group(AluGroup *group) { m_parent_group = group; }
parent_group()172    AluGroup *parent_group() { return m_parent_group;}
173 
as_alu()174    AluInstr *as_alu() override { return this; }
175 
176    uint8_t allowed_src_chan_mask() const override;
allowed_dest_chan_mask()177    uint8_t allowed_dest_chan_mask() const {return m_allowed_dest_mask;}
178 
inc_ar_uses()179    void inc_ar_uses() { ++m_num_ar_uses;}
num_ar_uses()180    auto num_ar_uses() const {return m_num_ar_uses;}
181 
182    bool replace_src(int i, PVirtualValue new_src, uint32_t to_set,
183                     SourceMod to_clear);
184 
set_source_mod(int src,SourceMod mod)185    void set_source_mod(int src, SourceMod mod) {
186       m_source_modifiers |= mod << (2 * src);
187    }
has_source_mod(int src,SourceMod mod)188    auto has_source_mod(int src, SourceMod mod) const {
189       return (m_source_modifiers & (mod << (2 * src))) != 0;
190    }
reset_source_mod(int src,SourceMod mod)191    void reset_source_mod(int src, SourceMod mod) {
192       m_source_modifiers &= ~(mod << (2 * src));
193    }
194 
195 private:
196    friend class AluGroup;
197 
198    void update_uses();
199 
200    bool do_ready() const override;
201 
202    bool can_copy_propagate() const;
203 
204    bool check_readport_validation(PRegister old_src, PVirtualValue new_src) const;
205 
set_alu_flags(const AluOpFlags & flags)206    void set_alu_flags(const AluOpFlags& flags) { m_alu_flags = flags; }
207    bool propagate_death() override;
208 
209    void do_print(std::ostream& os) const override;
210 
211    union {
212       EAluOp m_opcode;
213       ESDOp m_lds_opcode;
214    };
215 
216    PRegister m_dest{nullptr};
217    SrcValues m_src;
218 
219    AluOpFlags m_alu_flags;
220    AluBankSwizzle m_bank_swizzle{alu_vec_unknown};
221    ECFAluOpCode m_cf_type{cf_alu};
222    int m_alu_slots{1};
223    int m_fallback_chan{0};
224    unsigned m_idx_offset{0};
225    int m_required_slots{0};
226    int m_priority{0};
227    std::set<PRegister, std::less<PRegister>, Allocator<PRegister>> m_extra_dependencies;
228    AluGroup *m_parent_group{nullptr};
229    unsigned m_allowed_dest_mask{0xf};
230    unsigned m_num_ar_uses{0};
231    uint32_t m_source_modifiers{0};
232 };
233 
234 class AluInstrVisitor : public InstrVisitor {
235 public:
236    void visit(AluGroup *instr) override;
237    void visit(Block *instr) override;
238    void visit(IfInstr *instr) override;
239 
visit(TexInstr * instr)240    void visit(TexInstr *instr) override { (void)instr; }
visit(ExportInstr * instr)241    void visit(ExportInstr *instr) override { (void)instr; }
visit(FetchInstr * instr)242    void visit(FetchInstr *instr) override { (void)instr; }
visit(ControlFlowInstr * instr)243    void visit(ControlFlowInstr *instr) override { (void)instr; }
visit(ScratchIOInstr * instr)244    void visit(ScratchIOInstr *instr) override { (void)instr; }
visit(StreamOutInstr * instr)245    void visit(StreamOutInstr *instr) override { (void)instr; }
visit(MemRingOutInstr * instr)246    void visit(MemRingOutInstr *instr) override { (void)instr; }
visit(EmitVertexInstr * instr)247    void visit(EmitVertexInstr *instr) override { (void)instr; }
visit(GDSInstr * instr)248    void visit(GDSInstr *instr) override { (void)instr; };
visit(WriteTFInstr * instr)249    void visit(WriteTFInstr *instr) override { (void)instr; };
visit(LDSAtomicInstr * instr)250    void visit(LDSAtomicInstr *instr) override { (void)instr; };
visit(LDSReadInstr * instr)251    void visit(LDSReadInstr *instr) override { (void)instr; };
visit(RatInstr * instr)252    void visit(RatInstr *instr) override { (void)instr; };
253 };
254 
255 } // namespace r600
256 #endif // INSTRALU_H
257