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 SpecialValue: public Value {
166 protected:
167    SpecialValue(Type type, int value, int chan);
168    uint32_t sel() const override final;
169 private:
170    void do_print(std::ostream& os) const override;
171    AluInlineConstants m_value;
172 };
173 
174 class InlineConstValue: public SpecialValue {
175 public:
176    InlineConstValue(int value, int chan);
177    bool is_equal_to(const Value& other) const override;
178 
179 private:
180    AluInlineConstants m_value;
181 };
182 
183 class UniformValue: public Value {
184 public:
185    UniformValue(uint32_t sel, uint32_t chan, uint32_t kcache_bank = 0);
186    UniformValue(uint32_t sel, uint32_t chan, PValue addr);
187    uint32_t sel() const override;
188    uint32_t kcache_bank() const;
addr()189    PValue addr() const {return m_addr;}
reset_addr(PValue v)190    void reset_addr(PValue v) {m_addr = v;}
191 private:
192    void do_print(std::ostream& os) const override;
193    bool is_equal_to(const Value& other) const override;
194 
195    uint32_t m_index;
196    uint32_t m_kcache_bank;
197    PValue m_addr;
198 };
199 
200 } // end ns r600
201 
202 #endif
203