r600/sfn: fix nop channel assignment.
[mesa.git] / src / gallium / drivers / r600 / sfn / sfn_value_gpr.cpp
1 /* -*- mesa-c++ -*-
2 *
3 * Copyright (c) 2018-2019 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 #include "sfn_value_gpr.h"
28 #include "sfn_valuepool.h"
29 #include "sfn_debug.h"
30 #include "sfn_liverange.h"
31
32 namespace r600 {
33
34 using std::vector;
35 using std::array;
36
37 GPRValue::GPRValue(uint32_t sel, uint32_t chan, int base_offset):
38 Value(Value::gpr, chan),
39 m_sel(sel),
40 m_base_offset(base_offset),
41 m_input(false)
42 {
43 }
44
45 GPRValue::GPRValue(uint32_t sel, uint32_t chan):
46 Value(Value::gpr, chan),
47 m_sel(sel),
48 m_base_offset(0),
49 m_input(false)
50 {
51 }
52
53 uint32_t GPRValue::sel() const
54 {
55 return m_sel;
56 }
57
58 void GPRValue::do_print(std::ostream& os) const
59 {
60 os << 'R';
61 os << m_sel;
62 os << '.' << component_names[chan()];
63 }
64
65 bool GPRValue::is_equal_to(const Value& other) const
66 {
67 assert(other.type() == Value::Type::gpr);
68 const auto& rhs = static_cast<const GPRValue&>(other);
69 return (sel() == rhs.sel() &&
70 chan() == rhs.chan());
71 }
72
73 void GPRValue::do_print(std::ostream& os, UNUSED const PrintFlags& flags) const
74 {
75 os << 'R';
76 os << m_sel;
77 os << '.' << component_names[chan()];
78 }
79
80 GPRVector::GPRVector(const GPRVector& orig):
81 Value(gpr_vector),
82 m_elms(orig.m_elms),
83 m_valid(orig.m_valid)
84 {
85 }
86
87 GPRVector::GPRVector(std::array<PValue,4> elms):
88 Value(gpr_vector),
89 m_elms(elms),
90 m_valid(false)
91 {
92 for (unsigned i = 0; i < 4; ++i)
93 if (!m_elms[i] || (m_elms[i]->type() != Value::gpr)) {
94 assert(0 && "GPR vector not valid because element missing or nit a GPR");
95 return;
96 }
97 unsigned sel = m_elms[0]->sel();
98 for (unsigned i = 1; i < 4; ++i)
99 if (m_elms[i]->sel() != sel) {
100 assert(0 && "GPR vector not valid because sel is not equal for all elements");
101 return;
102 }
103 m_valid = true;
104 }
105
106 GPRVector::GPRVector(uint32_t sel, std::array<uint32_t,4> swizzle):
107 Value (gpr_vector),
108 m_valid(true)
109 {
110 for (int i = 0; i < 4; ++i)
111 m_elms[i] = PValue(new GPRValue(sel, swizzle[i]));
112 }
113
114 GPRVector::GPRVector(const GPRVector& orig, const std::array<uint8_t,4>& swizzle)
115 {
116 for (int i = 0; i < 4; ++i)
117 m_elms[i] = orig.reg_i(swizzle[i]);
118 m_valid = orig.m_valid;
119 }
120
121 void GPRVector::validate() const
122 {
123 assert(m_elms[0]);
124 uint32_t sel = m_elms[0]->sel();
125 if (sel >= 124)
126 return;
127
128 for (unsigned i = 1; i < 4; ++i) {
129 assert(m_elms[i]);
130 if (sel != m_elms[i]->sel())
131 return;
132 }
133
134 m_valid = true;
135 }
136
137 uint32_t GPRVector::sel() const
138 {
139 validate();
140 assert(m_valid);
141 return m_elms[0] ? m_elms[0]->sel() : 999;
142 }
143
144 void GPRVector::set_reg_i(int i, PValue reg)
145 {
146 m_elms[i] = reg;
147 }
148
149 void GPRVector::pin_to_channel(int i)
150 {
151 auto& v = static_cast<GPRValue&>(*m_elms[i]);
152 v.pin_to_channel();
153 }
154
155 void GPRVector::do_print(std::ostream& os) const
156 {
157 os << "R" << sel() << ".";
158 for (int i = 0; i < 4; ++i)
159 os << (m_elms[i] ? component_names[m_elms[i]->chan() < 8 ? m_elms[i]->chan() : 8] : '?');
160 }
161
162 void GPRVector::swizzle(const Swizzle& swz)
163 {
164 Values v(m_elms);
165 for (uint32_t i = 0; i < 4; ++i)
166 if (i != swz[i]) {
167 assert(swz[i] < 4);
168 m_elms[i] = v[swz[i]];
169 }
170 }
171
172 bool GPRVector::is_equal_to(const Value& other) const
173 {
174 if (other.type() != gpr_vector) {
175 std::cerr << "t";
176 return false;
177 }
178
179 const GPRVector& o = static_cast<const GPRVector&>(other);
180
181 for (int i = 0; i < 4; ++i) {
182 if (*m_elms[i] != *o.m_elms[i]) {
183 std::cerr << "elm" << i;
184 return false;
185 }
186 }
187 return true;
188 }
189
190
191 GPRArrayValue::GPRArrayValue(PValue value, PValue addr, GPRArray *array):
192 Value(gpr_array_value, value->chan()),
193 m_value(value),
194 m_addr(addr),
195 m_array(array)
196 {
197 }
198
199 GPRArrayValue::GPRArrayValue(PValue value, GPRArray *array):
200 Value(gpr_array_value, value->chan()),
201 m_value(value),
202 m_array(array)
203 {
204 }
205
206 static const char *swz_char = "xyzw01_";
207
208 void GPRArrayValue::do_print(std::ostream& os) const
209 {
210 assert(m_array);
211 os << "R" << m_value->sel();
212 if (m_addr) {
213 os << "[" << *m_addr << "] ";
214 }
215 os << swz_char[m_value->chan()];
216
217 os << "(" << *m_array << ")";
218 }
219
220 bool GPRArrayValue::is_equal_to(const Value& other) const
221 {
222 const GPRArrayValue& v = static_cast<const GPRArrayValue&>(other);
223
224 return *m_value == *v.m_value &&
225 *m_array == *v.m_array;
226 }
227
228 void GPRArrayValue::record_read(LiverangeEvaluator& ev) const
229 {
230 if (m_addr) {
231 ev.record_read(*m_addr);
232 unsigned chan = m_value->chan();
233 assert(m_array);
234 m_array->record_read(ev, chan);
235 } else
236 ev.record_read(*m_value);
237 }
238
239 void GPRArrayValue::record_write(LiverangeEvaluator& ev) const
240 {
241 if (m_addr) {
242 ev.record_read(*m_addr);
243 unsigned chan = m_value->chan();
244 assert(m_array);
245 m_array->record_write(ev, chan);
246 } else
247 ev.record_write(*m_value);
248 }
249
250 void GPRArrayValue::reset_value(PValue new_value)
251 {
252 m_value = new_value;
253 }
254
255 void GPRArrayValue::reset_addr(PValue new_addr)
256 {
257 m_addr = new_addr;
258 }
259
260
261 GPRArray::GPRArray(int base, int size, int mask, int frac):
262 Value (gpr_vector),
263 m_base_index(base),
264 m_component_mask(mask),
265 m_frac(frac)
266 {
267 m_values.resize(size);
268 for (int i = 0; i < size; ++i) {
269 for (int j = 0; j < 4; ++j) {
270 if (mask & (1 << j))
271 m_values[i].set_reg_i(j, PValue(new GPRValue(base + i, j)));
272 }
273 }
274 }
275
276 uint32_t GPRArray::sel() const
277 {
278 return m_base_index;
279 }
280
281 static const char *compchar = "xyzw";
282 void GPRArray::do_print(std::ostream& os) const
283 {
284 os << "ARRAY[R" << sel() << "..R" << sel() + m_values.size() - 1 << "].";
285 for (int j = 0; j < 4; ++j) {
286 if (m_component_mask & (1 << j))
287 os << compchar[j];
288 }
289 }
290
291 bool GPRArray::is_equal_to(const Value& other) const
292 {
293 const GPRArray& o = static_cast<const GPRArray&>(other);
294 return o.sel() == sel() &&
295 o.m_values.size() == m_values.size() &&
296 o.m_component_mask == m_component_mask;
297 }
298
299 uint32_t GPRArrayValue::sel() const
300 {
301 return m_value->sel();
302 }
303
304 PValue GPRArray::get_indirect(unsigned index, PValue indirect, unsigned component)
305 {
306 assert(index < m_values.size());
307 assert(m_component_mask & (1 << (component + m_frac)));
308
309 sfn_log << SfnLog::reg << "Create indirect register from " << *this;
310
311 PValue v = m_values[index].reg_i(component + m_frac);
312 assert(v);
313
314 sfn_log << SfnLog::reg << " -> " << *v;
315
316 if (indirect) {
317 sfn_log << SfnLog::reg << "[" << *indirect << "]";
318 switch (indirect->type()) {
319 case Value::literal: {
320 const LiteralValue& lv = static_cast<const LiteralValue&>(*indirect);
321 v = m_values[lv.value()].reg_i(component + m_frac);
322 break;
323 }
324 case Value::gpr: {
325 v = PValue(new GPRArrayValue(v, indirect, this));
326 sfn_log << SfnLog::reg << "(" << *v << ")";
327 break;
328 }
329 default:
330 assert(0 && !"Indirect addressing must be literal value or GPR");
331 }
332 }
333 sfn_log << SfnLog::reg <<" -> " << *v << "\n";
334 return v;
335 }
336
337 void GPRArray::record_read(LiverangeEvaluator& ev, int chan) const
338 {
339 for (auto& v: m_values)
340 ev.record_read(*v.reg_i(chan), true);
341 }
342
343 void GPRArray::record_write(LiverangeEvaluator& ev, int chan) const
344 {
345 for (auto& v: m_values)
346 ev.record_write(*v.reg_i(chan), true);
347 }
348
349 void GPRArray::collect_registers(ValueMap& output) const
350 {
351 for (auto& v: m_values) {
352 for (int i = 0; i < 4; ++i) {
353 auto vv = v.reg_i(i);
354 if (vv)
355 output.insert(vv);
356 }
357 }
358 }
359
360 }