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 34namespace r600 { 35 36using std::unique_ptr; 37using std::make_shared; 38 39const char *Value::component_names = "xyzw01?_!"; 40 41Value::Value(): 42 m_type(gpr), 43 m_chan(0) 44{ 45} 46 47Value::Value(Type type, uint32_t chan): 48 m_type(type), 49 m_chan(chan) 50{ 51 52} 53 54 55 56Value::Value(Type type): 57 Value(type, 0) 58{ 59} 60 61Value::Type Value::type() const 62{ 63 return m_type; 64} 65 66void Value::set_chan(uint32_t chan) 67{ 68 m_chan = chan; 69} 70 71void Value::print(std::ostream& os) const 72{ 73 do_print(os); 74} 75 76void 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 84void Value::do_print(std::ostream& os, const PrintFlags& flags) const 85{ 86 (void)flags; 87 do_print(os); 88} 89 90bool Value::operator < (const Value& lhs) const 91{ 92 return sel() < lhs.sel() || 93 (sel() == lhs.sel() && chan() < lhs.chan()); 94} 95 96 97LiteralValue::LiteralValue(float value, uint32_t chan): 98 Value(Value::literal, chan) 99{ 100 m_value.f=value; 101} 102 103 104LiteralValue::LiteralValue(uint32_t value, uint32_t chan): 105 Value(Value::literal, chan) 106{ 107 m_value.u=value; 108} 109 110LiteralValue::LiteralValue(int value, uint32_t chan): 111 Value(Value::literal, chan) 112{ 113 m_value.u=value; 114} 115 116uint32_t LiteralValue::sel() const 117{ 118 return ALU_SRC_LITERAL; 119} 120 121uint32_t LiteralValue::value() const 122{ 123 return m_value.u; 124} 125 126float LiteralValue::value_float() const 127{ 128 return m_value.f; 129} 130 131void 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 138void 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 148bool 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 156InlineConstValue::InlineConstValue(int value, int chan): 157 Value(Value::cinline, chan), 158 m_value(static_cast<AluInlineConstants>(value)) 159{ 160} 161 162uint32_t InlineConstValue::sel() const 163{ 164 return m_value; 165} 166 167void 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 185bool 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 192PValue Value::zero(new InlineConstValue(ALU_SRC_0, 0)); 193PValue Value::one_f(new InlineConstValue(ALU_SRC_1, 0)); 194PValue Value::one_i(new InlineConstValue(ALU_SRC_1_INT, 0)); 195PValue Value::zero_dot_5(new InlineConstValue(ALU_SRC_0_5, 0)); 196 197UniformValue::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 204UniformValue::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 213uint32_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 219uint32_t UniformValue::kcache_bank() const 220{ 221 return m_kcache_bank; 222} 223 224bool 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 231void 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