swr: fix build with mingw
[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.set_pin_to_channel();
153 }
154
155 void GPRVector::pin_all_to_channel()
156 {
157 for (auto& v: m_elms) {
158 auto& c = static_cast<GPRValue&>(*v);
159 c.set_pin_to_channel();
160 }
161 }
162
163 void GPRVector::do_print(std::ostream& os) const
164 {
165 os << "R" << sel() << ".";
166 for (int i = 0; i < 4; ++i)
167 os << (m_elms[i] ? component_names[m_elms[i]->chan() < 8 ? m_elms[i]->chan() : 8] : '?');
168 }
169
170 void GPRVector::swizzle(const Swizzle& swz)
171 {
172 Values v(m_elms);
173 for (uint32_t i = 0; i < 4; ++i)
174 if (i != swz[i]) {
175 assert(swz[i] < 4);
176 m_elms[i] = v[swz[i]];
177 }
178 }
179
180 bool GPRVector::is_equal_to(const Value& other) const
181 {
182 if (other.type() != gpr_vector) {
183 std::cerr << "t";
184 return false;
185 }
186
187 const GPRVector& o = static_cast<const GPRVector&>(other);
188
189 for (int i = 0; i < 4; ++i) {
190 if (*m_elms[i] != *o.m_elms[i]) {
191 std::cerr << "elm" << i;
192 return false;
193 }
194 }
195 return true;
196 }
197
198
199 GPRArrayValue::GPRArrayValue(PValue value, PValue addr, GPRArray *array):
200 Value(gpr_array_value, value->chan()),
201 m_value(value),
202 m_addr(addr),
203 m_array(array)
204 {
205 }
206
207 GPRArrayValue::GPRArrayValue(PValue value, GPRArray *array):
208 Value(gpr_array_value, value->chan()),
209 m_value(value),
210 m_array(array)
211 {
212 }
213
214 static const char *swz_char = "xyzw01_";
215
216 void GPRArrayValue::do_print(std::ostream& os) const
217 {
218 assert(m_array);
219 os << "R" << m_value->sel();
220 if (m_addr) {
221 os << "[" << *m_addr << "] ";
222 }
223 os << swz_char[m_value->chan()];
224
225 os << "(" << *m_array << ")";
226 }
227
228 bool GPRArrayValue::is_equal_to(const Value& other) const
229 {
230 const GPRArrayValue& v = static_cast<const GPRArrayValue&>(other);
231
232 return *m_value == *v.m_value &&
233 *m_array == *v.m_array;
234 }
235
236 void GPRArrayValue::record_read(LiverangeEvaluator& ev) const
237 {
238 if (m_addr) {
239 ev.record_read(*m_addr);
240 unsigned chan = m_value->chan();
241 assert(m_array);
242 m_array->record_read(ev, chan);
243 } else
244 ev.record_read(*m_value);
245 }
246
247 void GPRArrayValue::record_write(LiverangeEvaluator& ev) const
248 {
249 if (m_addr) {
250 ev.record_read(*m_addr);
251 unsigned chan = m_value->chan();
252 assert(m_array);
253 m_array->record_write(ev, chan);
254 } else
255 ev.record_write(*m_value);
256 }
257
258 void GPRArrayValue::reset_value(PValue new_value)
259 {
260 m_value = new_value;
261 }
262
263 void GPRArrayValue::reset_addr(PValue new_addr)
264 {
265 m_addr = new_addr;
266 }
267
268
269 GPRArray::GPRArray(int base, int size, int mask, int frac):
270 Value (gpr_vector),
271 m_base_index(base),
272 m_component_mask(mask),
273 m_frac(frac)
274 {
275 m_values.resize(size);
276 for (int i = 0; i < size; ++i) {
277 for (int j = 0; j < 4; ++j) {
278 if (mask & (1 << j))
279 m_values[i].set_reg_i(j, PValue(new GPRValue(base + i, j)));
280 }
281 }
282 }
283
284 uint32_t GPRArray::sel() const
285 {
286 return m_base_index;
287 }
288
289 static const char *compchar = "xyzw";
290 void GPRArray::do_print(std::ostream& os) const
291 {
292 os << "ARRAY[R" << sel() << "..R" << sel() + m_values.size() - 1 << "].";
293 for (int j = 0; j < 4; ++j) {
294 if (m_component_mask & (1 << j))
295 os << compchar[j];
296 }
297 }
298
299 bool GPRArray::is_equal_to(const Value& other) const
300 {
301 const GPRArray& o = static_cast<const GPRArray&>(other);
302 return o.sel() == sel() &&
303 o.m_values.size() == m_values.size() &&
304 o.m_component_mask == m_component_mask;
305 }
306
307 uint32_t GPRArrayValue::sel() const
308 {
309 return m_value->sel();
310 }
311
312 PValue GPRArray::get_indirect(unsigned index, PValue indirect, unsigned component)
313 {
314 assert(index < m_values.size());
315 assert(m_component_mask & (1 << (component + m_frac)));
316
317 sfn_log << SfnLog::reg << "Create indirect register from " << *this;
318
319 PValue v = m_values[index].reg_i(component + m_frac);
320 assert(v);
321
322 sfn_log << SfnLog::reg << " -> " << *v;
323
324 if (indirect) {
325 sfn_log << SfnLog::reg << "[" << *indirect << "]";
326 switch (indirect->type()) {
327 case Value::literal: {
328 const LiteralValue& lv = static_cast<const LiteralValue&>(*indirect);
329 v = m_values[lv.value()].reg_i(component + m_frac);
330 break;
331 }
332 case Value::gpr: {
333 v = PValue(new GPRArrayValue(v, indirect, this));
334 sfn_log << SfnLog::reg << "(" << *v << ")";
335 break;
336 }
337 default:
338 assert(0 && !"Indirect addressing must be literal value or GPR");
339 }
340 }
341 sfn_log << SfnLog::reg <<" -> " << *v << "\n";
342 return v;
343 }
344
345 void GPRArray::record_read(LiverangeEvaluator& ev, int chan) const
346 {
347 for (auto& v: m_values)
348 ev.record_read(*v.reg_i(chan), true);
349 }
350
351 void GPRArray::record_write(LiverangeEvaluator& ev, int chan) const
352 {
353 for (auto& v: m_values)
354 ev.record_write(*v.reg_i(chan), true);
355 }
356
357 void GPRArray::collect_registers(ValueMap& output) const
358 {
359 for (auto& v: m_values) {
360 for (int i = 0; i < 4; ++i) {
361 auto vv = v.reg_i(i);
362 if (vv)
363 output.insert(vv);
364 }
365 }
366 }
367
368 }