r600g/sb: fix handling of new multislot instructions on cayman
authorVadim Girlin <vadimgirlin@gmail.com>
Tue, 16 Jul 2013 08:28:52 +0000 (12:28 +0400)
committerVadim Girlin <vadimgirlin@gmail.com>
Wed, 17 Jul 2013 14:27:31 +0000 (18:27 +0400)
Ex-scalar instructions that became multislot on cayman do replicate result
to all channels - handle them similar to DOT4.

Signed-off-by: Vadim Girlin <vadimgirlin@gmail.com>
src/gallium/drivers/r600/sb/sb_ir.cpp
src/gallium/drivers/r600/sb/sb_ir.h
src/gallium/drivers/r600/sb/sb_ssa_builder.cpp

index 382fceed08c42f98a81c5e64ba4c25e38ff1bbb9..5226893de75cc033b27ba12c8d9beb74072a1541 100644 (file)
@@ -51,7 +51,7 @@ bool alu_packed_node::accept(vpass& p, bool enter) {
        return p.visit(*this, enter);
 }
 
-void alu_packed_node::init_args() {
+void alu_packed_node::init_args(bool repl) {
        alu_node *p = static_cast<alu_node*>(first);
        assert(p->is_valid());
        while (p) {
@@ -60,8 +60,6 @@ void alu_packed_node::init_args() {
                p = static_cast<alu_node*>(p->next);
        }
 
-       // if it's packed then it's always multislot, no need to check slot flags
-       bool repl = (op_ptr()->flags & AF_REPL);
        value *replicated_value = NULL;
 
        for (vvec::iterator I = dst.begin(), E = dst.end(); I != E; ++I) {
index d55f4de67b87d7cdd4b9e15f524b9469f8ee4861..c838f62b5674b54741c25ffcfeaec542e753e100 100644 (file)
@@ -1014,7 +1014,7 @@ public:
                return static_cast<alu_node*>(first)->bc.op_ptr;
        }
        unsigned op() { return static_cast<alu_node*>(first)->bc.op; }
-       void init_args();
+       void init_args(bool repl);
 
        virtual bool is_valid() { return subtype == NST_ALU_PACKED_INST; }
        virtual bool accept(vpass &p, bool enter);
index 87eafaee2476f9f939619479c4a06584423e00c7..3ad628bb68cc3e4ef06e8d60f5d342c555de985e 100644 (file)
@@ -218,7 +218,10 @@ bool ssa_rename::visit(alu_packed_node& n, bool enter) {
                        I->accept(*this, false);
                }
 
-               n.init_args();
+               bool repl = (n.op_ptr()->flags & AF_REPL) ||
+                               (ctx.is_cayman() && (n.first->alu_op_slot_flags() & AF_S));
+
+               n.init_args(repl);
        }
        return false;
 }