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 #include "sfn_value.h"
28 #include "util/macros.h"
29
30 #include <iostream>
31 #include <iomanip>
32 #include <cassert>
33
34 namespace r600 {
35
36 using std::unique_ptr;
37 using std::make_shared;
38
39 const char *Value::component_names = "xyzw01?_!";
40
Value()41 Value::Value():
42 m_type(gpr),
43 m_chan(0)
44 {
45 }
46
Value(Type type,uint32_t chan)47 Value::Value(Type type, uint32_t chan):
48 m_type(type),
49 m_chan(chan)
50 {
51
52 }
53
54
55
Value(Type type)56 Value::Value(Type type):
57 Value(type, 0)
58 {
59 }
60
type() const61 Value::Type Value::type() const
62 {
63 return m_type;
64 }
65
set_chan(uint32_t chan)66 void Value::set_chan(uint32_t chan)
67 {
68 m_chan = chan;
69 }
70
print(std::ostream & os) const71 void Value::print(std::ostream& os) const
72 {
73 do_print(os);
74 }
75
print(std::ostream & os,const PrintFlags & flags) const76 void Value::print(std::ostream& os, const PrintFlags& flags) const
77 {
78 if (flags.flags & PrintFlags::has_neg) os << '-';
79 if (flags.flags & PrintFlags::has_abs) os << '|';
80 do_print(os, flags);
81 if (flags.flags & PrintFlags::has_abs) os << '|';
82 }
83
do_print(std::ostream & os,const PrintFlags & flags) const84 void Value::do_print(std::ostream& os, const PrintFlags& flags) const
85 {
86 (void)flags;
87 do_print(os);
88 }
89
operator <(const Value & lhs) const90 bool Value::operator < (const Value& lhs) const
91 {
92 return sel() < lhs.sel() ||
93 (sel() == lhs.sel() && chan() < lhs.chan());
94 }
95
96
LiteralValue(float value,uint32_t chan)97 LiteralValue::LiteralValue(float value, uint32_t chan):
98 Value(Value::literal, chan)
99 {
100 m_value.f=value;
101 }
102
103
LiteralValue(uint32_t value,uint32_t chan)104 LiteralValue::LiteralValue(uint32_t value, uint32_t chan):
105 Value(Value::literal, chan)
106 {
107 m_value.u=value;
108 }
109
LiteralValue(int value,uint32_t chan)110 LiteralValue::LiteralValue(int value, uint32_t chan):
111 Value(Value::literal, chan)
112 {
113 m_value.u=value;
114 }
115
sel() const116 uint32_t LiteralValue::sel() const
117 {
118 return ALU_SRC_LITERAL;
119 }
120
value() const121 uint32_t LiteralValue::value() const
122 {
123 return m_value.u;
124 }
125
value_float() const126 float LiteralValue::value_float() const
127 {
128 return m_value.f;
129 }
130
do_print(std::ostream & os) const131 void LiteralValue::do_print(std::ostream& os) const
132 {
133 os << "[0x" << std::setbase(16) << m_value.u << " " << std::setbase(10)
134 << m_value.f << "].";
135 os << component_names[chan()];
136 }
137
do_print(std::ostream & os,UNUSED const PrintFlags & flags) const138 void LiteralValue::do_print(std::ostream& os, UNUSED const PrintFlags& flags) const
139 {
140 os << "[0x" << std::setbase(16) << m_value.u << " "
141 << std::setbase(10);
142
143 os << m_value.f << "f";
144
145 os<< "]";
146 }
147
is_equal_to(const Value & other) const148 bool LiteralValue::is_equal_to(const Value& other) const
149 {
150 assert(other.type() == Value::Type::literal);
151 const auto& rhs = static_cast<const LiteralValue&>(other);
152 return (sel() == rhs.sel() &&
153 value() == rhs.value());
154 }
155
SpecialValue(Type type,int value,int chan)156 SpecialValue::SpecialValue(Type type, int value, int chan):
157 Value(type, chan),
158 m_value(static_cast<AluInlineConstants>(value))
159 {
160 }
161
sel() const162 uint32_t SpecialValue::sel() const
163 {
164 return m_value;
165 }
166
167
do_print(std::ostream & os) const168 void SpecialValue::do_print(std::ostream& os) const
169 {
170 auto sv_info = alu_src_const.find(m_value);
171 if (sv_info != alu_src_const.end()) {
172 os << sv_info->second.descr;
173 if (sv_info->second.use_chan)
174 os << '.' << component_names[chan()];
175 else if (chan() > 0)
176 os << "." << component_names[chan()]
177 << " (W: Channel ignored)";
178 } else {
179 if (m_value >= ALU_SRC_PARAM_BASE && m_value < ALU_SRC_PARAM_BASE + 32)
180 os << " Param" << m_value - ALU_SRC_PARAM_BASE;
181 else
182 os << " E: unknown inline constant " << m_value;
183 }
184 }
185
186 PValue Value::zero(new InlineConstValue(ALU_SRC_0, 0));
187 PValue Value::one_f(new InlineConstValue(ALU_SRC_1, 0));
188 PValue Value::one_i(new InlineConstValue(ALU_SRC_1_INT, 0));
189 PValue Value::zero_dot_5(new InlineConstValue(ALU_SRC_0_5, 0));
190
InlineConstValue(int value,int chan)191 InlineConstValue::InlineConstValue(int value, int chan):
192 SpecialValue(Value::cinline, value, chan)
193 {
194 }
195
is_equal_to(const Value & other) const196 bool InlineConstValue::is_equal_to(const Value& other) const
197 {
198 assert(other.type() == Value::Type::cinline);
199 const auto& rhs = static_cast<const InlineConstValue&>(other);
200 return sel() == rhs.sel();
201 }
202
UniformValue(uint32_t sel,uint32_t chan,uint32_t kcache_bank)203 UniformValue::UniformValue(uint32_t sel, uint32_t chan, uint32_t kcache_bank):
204 Value(Value::kconst, chan)
205 {
206 m_index = sel;
207 m_kcache_bank = kcache_bank;
208 }
209
UniformValue(uint32_t sel,uint32_t chan,PValue addr)210 UniformValue::UniformValue(uint32_t sel, uint32_t chan, PValue addr):
211 Value(Value::kconst, chan),
212 m_index(sel),
213 m_kcache_bank(1),
214 m_addr(addr)
215 {
216
217 }
218
sel() const219 uint32_t UniformValue::sel() const
220 {
221 const int bank_base[4] = {128, 160, 256, 288};
222 return m_index < 512 ? m_index + bank_base[m_kcache_bank] : m_index;
223 }
224
kcache_bank() const225 uint32_t UniformValue::kcache_bank() const
226 {
227 return m_kcache_bank;
228 }
229
is_equal_to(const Value & other) const230 bool UniformValue::is_equal_to(const Value& other) const
231 {
232 const UniformValue& o = static_cast<const UniformValue&>(other);
233 return sel() == o.sel() &&
234 m_kcache_bank == o.kcache_bank();
235 }
236
do_print(std::ostream & os) const237 void UniformValue::do_print(std::ostream& os) const
238 {
239 if (m_index < 512)
240 os << "KC" << m_kcache_bank << "[" << m_index;
241 else if (m_addr)
242 os << "KC[" << *m_addr << "][" << m_index;
243 else
244 os << "KCx[" << m_index;
245 os << "]." << component_names[chan()];
246 }
247
248 }
249