1 /* -*- mesa-c++  -*-
2  *
3  * Copyright (c) 2019 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_instruction_gds.h"
28 #include "sfn_liverange.h"
29 
30 namespace  r600 {
31 
GDSInstr(ESDOp op,const GPRVector & dest,const PValue & value,const PValue & value2,const PValue & uav_id,int uav_base)32 GDSInstr::GDSInstr(ESDOp op, const GPRVector& dest,  const PValue& value,
33                    const PValue& value2, const PValue& uav_id, int uav_base):
34    Instruction(gds),
35    m_op(op),
36    m_src(value),
37    m_src2(value2),
38    m_dest(dest),
39    m_dest_swizzle({PIPE_SWIZZLE_X,7,7,7}),
40    m_src_swizzle({PIPE_SWIZZLE_0, PIPE_SWIZZLE_X, PIPE_SWIZZLE_0}),
41    m_buffer_index_mode(bim_none),
42    m_uav_id(uav_id),
43    m_uav_base(uav_base),
44    m_flags(0)
45 {
46    add_remappable_src_value(&m_src);
47    add_remappable_src_value(&m_src2);
48    add_remappable_src_value(&m_uav_id);
49    add_remappable_dst_value(&m_dest);
50    m_dest_swizzle[0] = m_dest.chan_i(0);
51 }
52 
GDSInstr(ESDOp op,const GPRVector & dest,const PValue & value,const PValue & uav_id,int uav_base)53 GDSInstr::GDSInstr(ESDOp op, const GPRVector& dest,  const PValue& value,
54                    const PValue& uav_id, int uav_base):
55    GDSInstr(op, dest,  value, PValue(), uav_id, uav_base)
56 {
57       assert(value);
58       m_src_swizzle[1] = value->chan();
59       m_src_swizzle[2] = PIPE_SWIZZLE_0;
60 }
61 
GDSInstr(ESDOp op,const GPRVector & dest,const PValue & uav_id,int uav_base)62 GDSInstr::GDSInstr(ESDOp op, const GPRVector& dest,
63                    const PValue& uav_id, int uav_base):
64    GDSInstr(op, dest,  PValue(), PValue(), uav_id, uav_base)
65 {
66    m_src_swizzle[1] = PIPE_SWIZZLE_0;
67 }
68 
is_equal_to(UNUSED const Instruction & lhs) const69 bool GDSInstr::is_equal_to(UNUSED const Instruction& lhs) const
70 {
71    return false;
72 }
73 
do_print(std::ostream & os) const74 void GDSInstr::do_print(std::ostream& os) const
75 {
76    const char *swz = "xyzw01?_";
77    os << lds_ops.at(m_op).name << " R" << m_dest.sel() << ".";
78    for (int i = 0; i < 4; ++i) {
79       os << swz[m_dest_swizzle[i]];
80    }
81    if (m_src)
82       os << " " << *m_src;
83 
84    os << " UAV:" << *m_uav_id;
85 }
86 
RatInstruction(ECFOpCode cf_opcode,ERatOp rat_op,const GPRVector & data,const GPRVector & index,int rat_id,const PValue & rat_id_offset,int burst_count,int comp_mask,int element_size,bool ack)87 RatInstruction::RatInstruction(ECFOpCode cf_opcode, ERatOp rat_op,
88                                const GPRVector& data, const GPRVector& index,
89                                int rat_id, const PValue& rat_id_offset,
90                                int burst_count, int comp_mask, int element_size, bool ack):
91    Instruction(rat),
92    m_cf_opcode(cf_opcode),
93    m_rat_op(rat_op),
94    m_data(data),
95    m_index(index),
96    m_rat_id(rat_id),
97    m_rat_id_offset(rat_id_offset),
98    m_burst_count(burst_count),
99    m_comp_mask(comp_mask),
100    m_element_size(element_size),
101    m_need_ack(ack)
102 {
103    add_remappable_src_value(&m_data);
104    add_remappable_src_value(&m_rat_id_offset);
105    add_remappable_src_value(&m_index);
106 }
107 
is_equal_to(UNUSED const Instruction & lhs) const108 bool RatInstruction::is_equal_to(UNUSED const Instruction& lhs) const
109 {
110    return false;
111 }
112 
do_print(std::ostream & os) const113 void RatInstruction::do_print(std::ostream& os) const
114 {
115    os << "MEM_RAT RAT(" << m_rat_id;
116    if (m_rat_id_offset)
117       os << "+" << *m_rat_id_offset;
118    os << ") @" << m_index;
119    os << " OP:" << m_rat_op << " " << m_data;
120    os << " BC:" << m_burst_count
121       << " MASK:" << m_comp_mask
122       << " ES:" << m_element_size;
123    if (m_need_ack)
124       os << " ACK";
125 }
126 
opcode(nir_intrinsic_op opcode)127 RatInstruction::ERatOp RatInstruction::opcode(nir_intrinsic_op opcode)
128 {
129    switch (opcode) {
130    case nir_intrinsic_ssbo_atomic_add:
131       return ADD_RTN;
132    case nir_intrinsic_ssbo_atomic_and:
133       return AND_RTN;
134    case nir_intrinsic_ssbo_atomic_exchange:
135       return XCHG_RTN;
136    case nir_intrinsic_ssbo_atomic_umax:
137       return MAX_UINT_RTN;
138    case nir_intrinsic_ssbo_atomic_umin:
139       return MIN_UINT_RTN;
140    case nir_intrinsic_ssbo_atomic_imax:
141       return MAX_INT_RTN;
142    case nir_intrinsic_ssbo_atomic_imin:
143       return MIN_INT_RTN;
144    case nir_intrinsic_ssbo_atomic_xor:
145       return XOR_RTN;
146    default:
147       return UNSUPPORTED;
148    }
149 }
150 
GDSStoreTessFactor(GPRVector & value)151 GDSStoreTessFactor::GDSStoreTessFactor(GPRVector& value):
152    Instruction(tf_write),
153    m_value(value)
154 {
155    add_remappable_src_value(&m_value);
156 }
157 
replace_values(const ValueSet & candiates,PValue new_value)158 void GDSStoreTessFactor::replace_values(const ValueSet& candiates, PValue new_value)
159 {
160    for (auto& c: candiates) {
161       for (int i = 0; i < 4; ++i) {
162          if (*c == *m_value[i])
163             m_value[i] = new_value;
164       }
165    }
166 }
167 
168 
is_equal_to(const Instruction & lhs) const169 bool GDSStoreTessFactor::is_equal_to(const Instruction& lhs) const
170 {
171    auto& other = static_cast<const GDSStoreTessFactor&>(lhs);
172    return m_value == other.m_value;
173 }
174 
do_print(std::ostream & os) const175 void GDSStoreTessFactor::do_print(std::ostream& os) const
176 {
177    os << "TF_WRITE " << m_value;
178 }
179 
180 }
181