freedreno/ir3: Use third register for offset for LDL and LDLV
authorKristian H. Kristensen <hoegsberg@google.com>
Thu, 10 Oct 2019 20:44:14 +0000 (13:44 -0700)
committerKristian H. Kristensen <hoegsberg@google.com>
Thu, 17 Oct 2019 20:43:53 +0000 (13:43 -0700)
Before, offset held the offset, which can be either immediate or a
register.  Use a third register to hold the offset so that we can use
a register.

Signed-off-by: Kristian H. Kristensen <hoegsberg@google.com>
src/freedreno/ir3/ir3.c
src/freedreno/ir3/ir3.h
src/freedreno/ir3/ir3_compiler_nir.c
src/freedreno/ir3/ir3_cp.c

index 68e83f7495e46b32c87738ba980970fc698ad822..72809c4a5486ad9b178e18209dd6f97248563a09 100644 (file)
@@ -794,17 +794,21 @@ static int emit_cat6(struct ir3_instruction *instr, void *ptr,
                return 0;
        } else if (instr->cat6.src_offset || (instr->opc == OPC_LDG) ||
                        (instr->opc == OPC_LDL)) {
+               struct ir3_register *src3 = instr->regs[3];
                instr_cat6a_t *cat6a = ptr;
 
                cat6->src_off = true;
 
                cat6a->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED);
                cat6a->src1_im = !!(src1->flags & IR3_REG_IMMED);
-               if (src2) {
-                       cat6a->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED);
-                       cat6a->src2_im = !!(src2->flags & IR3_REG_IMMED);
-               }
-               cat6a->off = instr->cat6.src_offset;
+
+               /* Num components */
+               cat6a->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED);
+               cat6a->src2_im = true;
+
+               /* Offset */
+               iassert(src3->flags & IR3_REG_IMMED);
+               cat6a->off = reg(src3, info, instr->repeat, IR3_REG_IMMED);
        } else {
                instr_cat6b_t *cat6b = ptr;
 
index 9d2a8d735285818f15c2ebea4f7347ef195619af..224ed4e5c6699290e6392d883ffe55019f0fe0c5 100644 (file)
@@ -1407,8 +1407,8 @@ ir3_SAM(struct ir3_block *block, opc_t opc, type_t type,
 
 /* cat6 instructions: */
 INSTR2(LDLV)
-INSTR2(LDG)
-INSTR2(LDL)
+INSTR3(LDG)
+INSTR3(LDL)
 INSTR3(STG)
 INSTR3(STL)
 INSTR1(RESINFO)
index 6ed24e41e2f88adf5d27fc8fcf7c1711d3e831df..aa9eaca7bdde48bcbc091ca3970468e9855430ec 100644 (file)
@@ -752,9 +752,9 @@ emit_intrinsic_load_ubo(struct ir3_context *ctx, nir_intrinsic_instr *intr,
 
        for (int i = 0; i < intr->num_components; i++) {
                struct ir3_instruction *load =
-                               ir3_LDG(b, addr, 0, create_immed(b, 1), 0);
+                       ir3_LDG(b, addr, 0, create_immed(b, 1), 0, /* num components */
+                                       create_immed(b, off + i * 4), 0);
                load->cat6.type = TYPE_U32;
-               load->cat6.src_offset = off + i * 4;     /* byte offset */
                dst[i] = load;
        }
 }
@@ -787,8 +787,10 @@ emit_intrinsic_load_shared(struct ir3_context *ctx, nir_intrinsic_instr *intr,
        offset = ir3_get_src(ctx, &intr->src[0])[0];
        base   = nir_intrinsic_base(intr);
 
-       ldl = ir3_LDL(b, offset, 0, create_immed(b, intr->num_components), 0);
-       ldl->cat6.src_offset = base;
+       ldl = ir3_LDL(b, offset, 0,
+                       create_immed(b, intr->num_components), 0,
+                       create_immed(b, base), 0);
+
        ldl->cat6.type = utype_dst(intr->dest);
        ldl->regs[0]->wrmask = MASK(intr->num_components);
 
index 1baf11971a88fd1c6b396072ecee1b93a36900ef..704ddf99937c63711cd6f882dd316250ce955a42 100644 (file)
@@ -210,7 +210,7 @@ static bool valid_flags(struct ir3_instruction *instr, unsigned n,
                        if (is_store(instr) && (n == 1))
                                return false;
 
-                       if ((instr->opc == OPC_LDL) && (n != 1))
+                       if ((instr->opc == OPC_LDL) && (n == 0))
                                return false;
 
                        if ((instr->opc == OPC_STL) && (n != 2))