r600/sfn: Make 3vec loads skip possible moves
[mesa.git] / src / gallium / drivers / r600 / sfn / sfn_value.h
1 /* -*- mesa-c++ -*-
2 *
3 * Copyright (c) 2018 Collabora LTD
4 *
5 * Author: Gert Wollny <gert.wollny@collabora.com>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #ifndef SFN_VALUE_H
28 #define SFN_VALUE_H
29
30 #include "sfn_alu_defines.h"
31 #include "nir.h"
32
33 #include <memory>
34 #include <set>
35 #include <bitset>
36 #include <iostream>
37
38 namespace r600 {
39
40 class Value {
41 public:
42 using Pointer=std::shared_ptr<Value>;
43
44 struct PrintFlags {
45 PrintFlags():index_mode(0),
46 flags(0)
47 {
48 }
49 PrintFlags(int im, int f):index_mode(im),
50 flags(f)
51 {
52 }
53 int index_mode;
54 int flags;
55 static const int is_rel = 1;
56 static const int has_abs = 2;
57 static const int has_neg = 4;
58 static const int literal_is_float = 8;
59 static const int index_ar = 16;
60 static const int index_loopidx = 32;
61 };
62
63 enum Type {
64 gpr,
65 kconst,
66 literal,
67 cinline,
68 lds_direct,
69 gpr_vector,
70 gpr_array_value,
71 unknown
72 };
73
74 static const char *component_names;
75
76 using LiteralFlags=std::bitset<4>;
77
78 Value();
79
80 Value(Type type);
81
82 virtual ~Value(){}
83
84 Type type() const;
85 virtual uint32_t sel() const = 0;
86 uint32_t chan() const {return m_chan;}
87
88 void set_chan(uint32_t chan);
89 void print(std::ostream& os, const PrintFlags& flags) const;
90
91 void print(std::ostream& os) const;
92
93 bool operator < (const Value& lhs) const;
94
95 static Value::Pointer zero;
96 static Value::Pointer one_f;
97 static Value::Pointer zero_dot_5;
98 static Value::Pointer one_i;
99
100 protected:
101 Value(Type type, uint32_t chan);
102
103 private:
104 virtual void do_print(std::ostream& os) const = 0;
105 virtual void do_print(std::ostream& os, const PrintFlags& flags) const;
106
107 virtual bool is_equal_to(const Value& other) const = 0;
108
109 Type m_type;
110 uint32_t m_chan;
111
112 friend bool operator == (const Value& lhs, const Value& rhs);
113 };
114
115
116 inline std::ostream& operator << (std::ostream& os, const Value& v)
117 {
118 v.print(os);
119 return os;
120 }
121
122
123 inline bool operator == (const Value& lhs, const Value& rhs)
124 {
125 if (lhs.type() == rhs.type())
126 return lhs.is_equal_to(rhs);
127 return false;
128 }
129
130 inline bool operator != (const Value& lhs, const Value& rhs)
131 {
132 return !(lhs == rhs);
133 }
134
135 using PValue=Value::Pointer;
136
137 struct value_less {
138 inline bool operator () (PValue lhs, PValue rhs) const {
139 return *lhs < *rhs;
140 }
141 };
142
143 using ValueSet = std::set<PValue, value_less>;
144
145
146 class LiteralValue: public Value {
147 public:
148 LiteralValue(float value, uint32_t chan= 0);
149 LiteralValue(uint32_t value, uint32_t chan= 0);
150 LiteralValue(int value, uint32_t chan= 0);
151 uint32_t sel() const override final;
152 uint32_t value() const;
153 float value_float() const;
154 private:
155 void do_print(std::ostream& os) const override;
156 void do_print(std::ostream& os, const PrintFlags& flags) const override;
157 bool is_equal_to(const Value& other) const override;
158 union {
159 uint32_t u;
160 float f;
161 } m_value;
162 };
163
164 class SpecialValue: public Value {
165 protected:
166 SpecialValue(Type type, int value, int chan);
167 uint32_t sel() const override final;
168 private:
169 void do_print(std::ostream& os) const override;
170 AluInlineConstants m_value;
171 };
172
173 class InlineConstValue: public SpecialValue {
174 public:
175 InlineConstValue(int value, int chan);
176 bool is_equal_to(const Value& other) const override;
177
178 private:
179 AluInlineConstants m_value;
180 };
181
182 class UniformValue: public Value {
183 public:
184 UniformValue(uint32_t sel, uint32_t chan, uint32_t kcache_bank = 0);
185 UniformValue(uint32_t sel, uint32_t chan, PValue addr);
186 uint32_t sel() const override;
187 uint32_t kcache_bank() const;
188 private:
189 void do_print(std::ostream& os) const override;
190 bool is_equal_to(const Value& other) const override;
191
192 uint32_t m_index;
193 uint32_t m_kcache_bank;
194 PValue m_addr;
195 };
196
197 } // end ns r600
198
199 #endif