The assembler allows people to do that and that's something available
since Crestline.

Signed-off-by: Damien Lespiau <[email protected]>
---
 assembler/brw_eu_emit.c |   39 +++++++++++++++++++++++++++------------
 1 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/assembler/brw_eu_emit.c b/assembler/brw_eu_emit.c
index 21c673e..c63f1fc 100644
--- a/assembler/brw_eu_emit.c
+++ b/assembler/brw_eu_emit.c
@@ -351,6 +351,9 @@ void brw_set_src1(struct brw_compile *p,
                  struct brw_instruction *insn,
                  struct brw_reg reg)
 {
+   struct brw_context *brw = p->brw;
+   struct intel_context *intel = &brw->intel;
+
    assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
 
    if (reg.file != BRW_ARCHITECTURE_REGISTER_FILE)
@@ -364,6 +367,7 @@ void brw_set_src1(struct brw_compile *p,
    insn->bits1.da1.src1_reg_type = reg.type;
    insn->bits3.da1.src1_abs = reg.abs;
    insn->bits3.da1.src1_negate = reg.negate;
+   insn->bits3.da1.src1_address_mode = reg.address_mode;
 
    /* Only src1 can be immediate in two-argument instructions.
     */
@@ -373,33 +377,44 @@ void brw_set_src1(struct brw_compile *p,
       insn->bits3.ud = reg.dw1.ud;
    }
    else {
-      /* This is a hardware restriction, which may or may not be lifted
-       * in the future:
-       */
-      assert (reg.address_mode == BRW_ADDRESS_DIRECT);
-      /* assert (reg.file == BRW_GENERAL_REGISTER_FILE); */
+      /* It's only BRW that does not support register-indirect addressing on
+       * src1 */
+      assert (intel->gen >= 4 || reg.address_mode == BRW_ADDRESS_DIRECT);
 
-      if (insn->header.access_mode == BRW_ALIGN_1) {
-        insn->bits3.da1.src1_subreg_nr = reg.subnr;
-        insn->bits3.da1.src1_reg_nr = reg.nr;
+      if (reg.address_mode == BRW_ADDRESS_DIRECT) {
+        if (insn->header.access_mode == BRW_ALIGN_1) {
+           insn->bits3.da1.src1_subreg_nr = reg.subnr;
+           insn->bits3.da1.src1_reg_nr = reg.nr;
+        }
+        else {
+           insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
+           insn->bits3.da16.src1_reg_nr = reg.nr;
+        }
       }
       else {
-        insn->bits3.da16.src1_subreg_nr = reg.subnr / 16;
-        insn->bits3.da16.src1_reg_nr = reg.nr;
+        insn->bits3.ia1.src1_subreg_nr = reg.subnr;
+
+        if (insn->header.access_mode == BRW_ALIGN_1)
+           insn->bits3.ia1.src1_indirect_offset = reg.dw1.bits.indirect_offset;
+        else
+           insn->bits3.ia16.src1_indirect_offset = 
reg.dw1.bits.indirect_offset / 16;
       }
 
       if (insn->header.access_mode == BRW_ALIGN_1) {
+        /* FIXME: While this is correct, if the assembler uses that code path
+         * the opcode generated are different and thus needs a validation
+         * pass.
         if (reg.width == BRW_WIDTH_1 && 
             insn->header.execution_size == BRW_EXECUTE_1) {
            insn->bits3.da1.src1_horiz_stride = BRW_HORIZONTAL_STRIDE_0;
            insn->bits3.da1.src1_width = BRW_WIDTH_1;
            insn->bits3.da1.src1_vert_stride = BRW_VERTICAL_STRIDE_0;
         }
-        else {
+        else { */
            insn->bits3.da1.src1_horiz_stride = reg.hstride;
            insn->bits3.da1.src1_width = reg.width;
            insn->bits3.da1.src1_vert_stride = reg.vstride;
-        }
+     /* } */
       }
       else {
         insn->bits3.da16.src1_swz_x = BRW_GET_SWZ(reg.dw1.bits.swizzle, 
BRW_CHANNEL_X);
-- 
1.7.7.5

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to