r600/sfn: Add LDS IO instructions to r600 IR
Signed-off-by: Gert Wollny <gert.wollny@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>
This commit is contained in:
@@ -118,6 +118,8 @@ CXX_SOURCES = \
|
||||
sfn/sfn_instruction_export.h \
|
||||
sfn/sfn_instruction_fetch.cpp \
|
||||
sfn/sfn_instruction_fetch.h \
|
||||
sfn/sfn_instruction_lds.cpp \
|
||||
sfn/sfn_instruction_lds.h \
|
||||
sfn/sfn_instruction_gds.cpp \
|
||||
sfn/sfn_instruction_gds.h \
|
||||
sfn/sfn_instruction_misc.cpp \
|
||||
|
||||
@@ -137,6 +137,8 @@ files_r600 = files(
|
||||
'sfn/sfn_instruction_fetch.h',
|
||||
'sfn/sfn_instruction_gds.cpp',
|
||||
'sfn/sfn_instruction_gds.h',
|
||||
'sfn/sfn_instruction_lds.cpp',
|
||||
'sfn/sfn_instruction_lds.h',
|
||||
'sfn/sfn_instruction_misc.cpp',
|
||||
'sfn/sfn_instruction_misc.h',
|
||||
'sfn/sfn_instruction_tex.cpp',
|
||||
|
||||
@@ -77,6 +77,8 @@ public:
|
||||
cond_if,
|
||||
cond_else,
|
||||
cond_endif,
|
||||
lds_read,
|
||||
lds_write,
|
||||
loop_begin,
|
||||
loop_end,
|
||||
loop_break,
|
||||
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "sfn_instruction_lds.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
void LDSReadInstruction::do_print(std::ostream& os) const
|
||||
{
|
||||
os << "LDS Read [";
|
||||
for (unsigned i = 0; i < m_address.size(); ++i)
|
||||
os << *m_dest_value[i] << " ";
|
||||
os << "], ";
|
||||
for (unsigned i = 0; i < m_address.size(); ++i)
|
||||
os << *m_address[i] << " ";
|
||||
}
|
||||
|
||||
LDSReadInstruction::LDSReadInstruction(std::vector<PValue>& address, std::vector<PValue>& value):
|
||||
Instruction(lds_read),
|
||||
m_address(address),
|
||||
m_dest_value(value)
|
||||
{
|
||||
assert(address.size() == value.size());
|
||||
|
||||
for (unsigned i = 0; i < address.size(); ++i) {
|
||||
add_remappable_src_value(&m_address[i]);
|
||||
add_remappable_dst_value(&m_dest_value[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void LDSReadInstruction::replace_values(const ValueSet& candiates, PValue new_value)
|
||||
{
|
||||
for (auto& c : candiates) {
|
||||
for (auto& d: m_dest_value) {
|
||||
if (*c == *d)
|
||||
d = new_value;
|
||||
}
|
||||
|
||||
for (auto& a: m_address) {
|
||||
if (*c == *a)
|
||||
a = new_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LDSReadInstruction::is_equal_to(const Instruction& lhs) const
|
||||
{
|
||||
auto& other = static_cast<const LDSReadInstruction&>(lhs);
|
||||
return m_address == other.m_address &&
|
||||
m_dest_value == other.m_dest_value;
|
||||
}
|
||||
|
||||
LDSWriteInstruction::LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0):
|
||||
LDSWriteInstruction::LDSWriteInstruction(address, idx_offset, value0, PValue())
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
LDSWriteInstruction::LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0, PValue value1):
|
||||
Instruction(lds_write),
|
||||
m_address(address),
|
||||
m_value0(value0),
|
||||
m_value1(value1),
|
||||
m_idx_offset(idx_offset)
|
||||
{
|
||||
add_remappable_src_value(&m_address);
|
||||
add_remappable_src_value(&m_value0);
|
||||
if (m_value1)
|
||||
add_remappable_src_value(&m_value1);
|
||||
}
|
||||
|
||||
|
||||
void LDSWriteInstruction::do_print(std::ostream& os) const
|
||||
{
|
||||
os << "LDS Write" << num_components()
|
||||
<< " " << address() << ", " << value0();
|
||||
if (num_components() > 1)
|
||||
os << ", " << value1();
|
||||
}
|
||||
|
||||
void LDSWriteInstruction::replace_values(const ValueSet& candiates, PValue new_value)
|
||||
{
|
||||
for (auto c: candiates) {
|
||||
if (*c == *m_address)
|
||||
m_address = new_value;
|
||||
|
||||
if (*c == *m_value0)
|
||||
m_value0 = new_value;
|
||||
|
||||
if (*c == *m_value1)
|
||||
m_value1 = new_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool LDSWriteInstruction::is_equal_to(const Instruction& lhs) const
|
||||
{
|
||||
auto& other = static_cast<const LDSWriteInstruction&>(lhs);
|
||||
|
||||
if (m_value1) {
|
||||
if (!other.m_value1)
|
||||
return false;
|
||||
if (*m_value1 != *other.m_value1)
|
||||
return false;
|
||||
} else {
|
||||
if (other.m_value1)
|
||||
return false;
|
||||
}
|
||||
|
||||
return (m_value0 != other.m_value0 &&
|
||||
*m_address != *other.m_address);
|
||||
}
|
||||
|
||||
} // namespace r600
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef LDSINSTRUCTION_H
|
||||
#define LDSINSTRUCTION_H
|
||||
|
||||
#include "sfn_instruction_base.h"
|
||||
|
||||
namespace r600 {
|
||||
|
||||
class LDSReadInstruction : public Instruction {
|
||||
public:
|
||||
LDSReadInstruction(std::vector<PValue>& value, std::vector<PValue>& address);
|
||||
void replace_values(const ValueSet& candiates, PValue new_value) override;
|
||||
|
||||
unsigned num_values() const { return m_dest_value.size();}
|
||||
const Value& address(unsigned i) const { return *m_address[i];}
|
||||
const Value& dest(unsigned i) const { return *m_dest_value[i];}
|
||||
private:
|
||||
void do_print(std::ostream& os) const override;
|
||||
bool is_equal_to(const Instruction& lhs) const override;
|
||||
|
||||
std::vector<PValue> m_address;
|
||||
std::vector<PValue> m_dest_value;
|
||||
};
|
||||
|
||||
class LDSWriteInstruction : public Instruction {
|
||||
public:
|
||||
LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0);
|
||||
LDSWriteInstruction(PValue address, unsigned idx_offset, PValue value0, PValue value1);
|
||||
|
||||
const Value& address() const {return *m_address;};
|
||||
const Value& value0() const { return *m_value0;}
|
||||
const Value& value1() const { return *m_value1;}
|
||||
unsigned num_components() const { return m_value1 ? 2 : 1;}
|
||||
unsigned idx_offset() const {return m_idx_offset;};
|
||||
|
||||
void replace_values(const ValueSet& candiates, PValue new_value) override;
|
||||
|
||||
private:
|
||||
void do_print(std::ostream& os) const override;
|
||||
bool is_equal_to(const Instruction& lhs) const override;
|
||||
|
||||
PValue m_address;
|
||||
PValue m_value0;
|
||||
PValue m_value1;
|
||||
unsigned m_idx_offset;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // LDSINSTRUCTION_H
|
||||
Reference in New Issue
Block a user