1 /* -*- mesa-c++ -*- 2 * 3 * Copyright (c) 2018 Collabora LTD 4 * 5 * Author: Gert Wollny <gert.wollny (at) 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 41 Value::Value(): 42 m_type(gpr), 43 m_chan(0) 44 { 45 } 46 47 Value::Value(Type type, uint32_t chan): 48 m_type(type), 49 m_chan(chan) 50 { 51 52 } 53 54 55 56 Value::Value(Type type): 57 Value(type, 0) 58 { 59 } 60 61 Value::Type Value::type() const 62 { 63 return m_type; 64 } 65 66 void Value::set_chan(uint32_t chan) 67 { 68 m_chan = chan; 69 } 70 71 void Value::print(std::ostream& os) const 72 { 73 do_print(os); 74 } 75 76 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 84 void Value::do_print(std::ostream& os, const PrintFlags& flags) const 85 { 86 (void)flags; 87 do_print(os); 88 } 89 90 bool Value::operator < (const Value& lhs) const 91 { 92 return sel() < lhs.sel() || 93 (sel() == lhs.sel() && chan() < lhs.chan()); 94 } 95 96 97 LiteralValue::LiteralValue(float value, uint32_t chan): 98 Value(Value::literal, chan) 99 { 100 m_value.f=value; 101 } 102 103 104 LiteralValue::LiteralValue(uint32_t value, uint32_t chan): 105 Value(Value::literal, chan) 106 { 107 m_value.u=value; 108 } 109 110 LiteralValue::LiteralValue(int value, uint32_t chan): 111 Value(Value::literal, chan) 112 { 113 m_value.u=value; 114 } 115 116 uint32_t LiteralValue::sel() const 117 { 118 return ALU_SRC_LITERAL; 119 } 120 121 uint32_t LiteralValue::value() const 122 { 123 return m_value.u; 124 } 125 126 float LiteralValue::value_float() const 127 { 128 return m_value.f; 129 } 130 131 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 138 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 148 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 156 InlineConstValue::InlineConstValue(int value, int chan): 157 Value(Value::cinline, chan), 158 m_value(static_cast<AluInlineConstants>(value)) 159 { 160 } 161 162 uint32_t InlineConstValue::sel() const 163 { 164 return m_value; 165 } 166 167 void InlineConstValue::do_print(std::ostream& os) const 168 { 169 auto sv_info = alu_src_const.find(m_value); 170 if (sv_info != alu_src_const.end()) { 171 os << sv_info->second.descr; 172 if (sv_info->second.use_chan) 173 os << '.' << component_names[chan()]; 174 else if (chan() > 0) 175 os << "." << component_names[chan()] 176 << " (W: Channel ignored)"; 177 } else { 178 if (m_value >= ALU_SRC_PARAM_BASE && m_value < ALU_SRC_PARAM_BASE + 32) 179 os << " Param" << m_value - ALU_SRC_PARAM_BASE; 180 else 181 os << " E: unknown inline constant " << m_value; 182 } 183 } 184 185 bool InlineConstValue::is_equal_to(const Value& other) const 186 { 187 assert(other.type() == Value::Type::cinline); 188 const auto& rhs = static_cast<const InlineConstValue&>(other); 189 return sel() == rhs.sel(); 190 } 191 192 PValue Value::zero(new InlineConstValue(ALU_SRC_0, 0)); 193 PValue Value::one_f(new InlineConstValue(ALU_SRC_1, 0)); 194 PValue Value::one_i(new InlineConstValue(ALU_SRC_1_INT, 0)); 195 PValue Value::zero_dot_5(new InlineConstValue(ALU_SRC_0_5, 0)); 196 197 UniformValue::UniformValue(uint32_t sel, uint32_t chan, uint32_t kcache_bank): 198 Value(Value::kconst, chan) 199 { 200 m_index = sel; 201 m_kcache_bank = kcache_bank; 202 } 203 204 UniformValue::UniformValue(uint32_t sel, uint32_t chan, PValue addr): 205 Value(Value::kconst, chan), 206 m_index(sel), 207 m_kcache_bank(1), 208 m_addr(addr) 209 { 210 211 } 212 213 uint32_t UniformValue::sel() const 214 { 215 const int bank_base[4] = {128, 160, 256, 288}; 216 return m_index < 512 ? m_index + bank_base[m_kcache_bank] : m_index; 217 } 218 219 uint32_t UniformValue::kcache_bank() const 220 { 221 return m_kcache_bank; 222 } 223 224 bool UniformValue::is_equal_to(const Value& other) const 225 { 226 const UniformValue& o = static_cast<const UniformValue&>(other); 227 return sel() == o.sel() && 228 m_kcache_bank == o.kcache_bank(); 229 } 230 231 void UniformValue::do_print(std::ostream& os) const 232 { 233 if (m_index < 512) 234 os << "KC" << m_kcache_bank << "[" << m_index; 235 else if (m_addr) 236 os << "KC[" << *m_addr << "][" << m_index; 237 else 238 os << "KCx[" << m_index; 239 os << "]." << component_names[chan()]; 240 } 241 242 } 243