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 #ifndef SFN_VALUE_H 28 #define SFN_VALUE_H 29 30 #include "sfn_alu_defines.h" 31 #include "nir.h" 32 33 #include <memory> 34 #include <set> 35 #include <bitset> 36 #include <iostream> 37 38 namespace r600 { 39 40 class Value { 41 public: 42 using Pointer=std::shared_ptr<Value>; 43 44 struct PrintFlags { PrintFlagsPrintFlags45 PrintFlags():index_mode(0), 46 flags(0) 47 { 48 } PrintFlagsPrintFlags49 PrintFlags(int im, int f):index_mode(im), 50 flags(f) 51 { 52 } 53 int index_mode; 54 int flags; 55 static const int is_rel = 1; 56 static const int has_abs = 2; 57 static const int has_neg = 4; 58 static const int literal_is_float = 8; 59 static const int index_ar = 16; 60 static const int index_loopidx = 32; 61 }; 62 63 enum Type { 64 gpr, 65 kconst, 66 literal, 67 cinline, 68 lds_direct, 69 gpr_vector, 70 gpr_array_value, 71 unknown 72 }; 73 74 static const char *component_names; 75 76 using LiteralFlags=std::bitset<4>; 77 78 Value(); 79 80 Value(Type type); 81 ~Value()82 virtual ~Value(){} 83 84 Type type() const; 85 virtual uint32_t sel() const = 0; chan()86 uint32_t chan() const {return m_chan;} 87 88 void set_chan(uint32_t chan); set_pin_to_channel()89 virtual void set_pin_to_channel() { assert(0 && "Only GPRs can be pinned to a channel ");} 90 void print(std::ostream& os, const PrintFlags& flags) const; 91 92 void print(std::ostream& os) const; 93 94 bool operator < (const Value& lhs) const; 95 96 static Value::Pointer zero; 97 static Value::Pointer one_f; 98 static Value::Pointer zero_dot_5; 99 static Value::Pointer one_i; 100 101 protected: 102 Value(Type type, uint32_t chan); 103 104 private: 105 virtual void do_print(std::ostream& os) const = 0; 106 virtual void do_print(std::ostream& os, const PrintFlags& flags) const; 107 108 virtual bool is_equal_to(const Value& other) const = 0; 109 110 Type m_type; 111 uint32_t m_chan; 112 113 friend bool operator == (const Value& lhs, const Value& rhs); 114 }; 115 116 117 inline std::ostream& operator << (std::ostream& os, const Value& v) 118 { 119 v.print(os); 120 return os; 121 } 122 123 124 inline bool operator == (const Value& lhs, const Value& rhs) 125 { 126 if (lhs.type() == rhs.type()) 127 return lhs.is_equal_to(rhs); 128 return false; 129 } 130 131 inline bool operator != (const Value& lhs, const Value& rhs) 132 { 133 return !(lhs == rhs); 134 } 135 136 using PValue=Value::Pointer; 137 138 struct value_less { operatorvalue_less139 inline bool operator () (PValue lhs, PValue rhs) const { 140 return *lhs < *rhs; 141 } 142 }; 143 144 using ValueSet = std::set<PValue, value_less>; 145 146 147 class LiteralValue: public Value { 148 public: 149 LiteralValue(float value, uint32_t chan= 0); 150 LiteralValue(uint32_t value, uint32_t chan= 0); 151 LiteralValue(int value, uint32_t chan= 0); 152 uint32_t sel() const override final; 153 uint32_t value() const; 154 float value_float() const; 155 private: 156 void do_print(std::ostream& os) const override; 157 void do_print(std::ostream& os, const PrintFlags& flags) const override; 158 bool is_equal_to(const Value& other) const override; 159 union { 160 uint32_t u; 161 float f; 162 } m_value; 163 }; 164 165 class InlineConstValue: public Value { 166 public: 167 InlineConstValue(int value, int chan); 168 uint32_t sel() const override final; 169 private: 170 void do_print(std::ostream& os) const override; 171 bool is_equal_to(const Value& other) const override; 172 AluInlineConstants m_value; 173 }; 174 175 class UniformValue: public Value { 176 public: 177 UniformValue(uint32_t sel, uint32_t chan, uint32_t kcache_bank = 0); 178 UniformValue(uint32_t sel, uint32_t chan, PValue addr); 179 uint32_t sel() const override; 180 uint32_t kcache_bank() const; addr()181 PValue addr() const {return m_addr;} reset_addr(PValue v)182 void reset_addr(PValue v) {m_addr = v;} 183 private: 184 void do_print(std::ostream& os) const override; 185 bool is_equal_to(const Value& other) const override; 186 187 uint32_t m_index; 188 uint32_t m_kcache_bank; 189 PValue m_addr; 190 }; 191 192 } // end ns r600 193 194 #endif 195