Home | History | Annotate | Line # | Download | only in sfn
      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