gallivm: Fix TGSI_OPCODE_ARR's translation.
authorJosé Fonseca <jfonseca@vmware.com>
Mon, 20 Feb 2012 20:49:03 +0000 (20:49 +0000)
committerJosé Fonseca <jfonseca@vmware.com>
Tue, 21 Feb 2012 08:23:20 +0000 (08:23 +0000)
Like TGSI_OPCODE_ARL, destination should be an integer.

This fixes invalid LLVM IR on an internal state tracker (currently Mesa
never emits this opcode).

In the future consider making ADDR register also a integer-as-float array,
like all other register kinds, or simply replace ADDR & ARR/ARL with
integer temp and instructions.

Reviewed-by: Dave Airlie <airlied@redhat.com>
src/gallium/auxiliary/gallivm/lp_bld_tgsi_action.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/auxiliary/tgsi/tgsi_info.c

index 1390b2e99c59106525be677125fcc5f98b702150..65c2a6b6be8822a697bb3640a6801f54b134e70e 100644 (file)
@@ -102,8 +102,9 @@ arr_emit(
    struct lp_build_tgsi_context * bld_base,
    struct lp_build_emit_data * emit_data)
 {
-   emit_data->output[emit_data->chan] = lp_build_emit_llvm_unary(bld_base,
-                                         TGSI_OPCODE_ROUND, emit_data->args[0]);
+   LLVMValueRef tmp = lp_build_emit_llvm_unary(bld_base, TGSI_OPCODE_ROUND, emit_data->args[0]);
+   emit_data->output[emit_data->chan] = LLVMBuildFPToSI(bld_base->base.gallivm->builder, tmp,
+                                                       bld_base->uint_bld.vec_type, "");
 }
 
 /* TGSI_OPCODE_CLAMP */
@@ -820,6 +821,16 @@ arl_emit_cpu(
                                                        bld_base->uint_bld.vec_type, "");
 }
 
+/* TGSI_OPCODE_ARR (CPU Only) */
+static void
+arr_emit_cpu(
+   const struct lp_build_tgsi_action * action,
+   struct lp_build_tgsi_context * bld_base,
+   struct lp_build_emit_data * emit_data)
+{
+   emit_data->output[emit_data->chan] = lp_build_iround(&bld_base->base, emit_data->args[0]);
+}
+
 /* TGSI_OPCODE_CEIL (CPU Only) */
 static void
 ceil_emit_cpu(
@@ -1166,6 +1177,7 @@ lp_set_default_actions_cpu(
    bld_base->op_actions[TGSI_OPCODE_ABS].emit = abs_emit_cpu;
    bld_base->op_actions[TGSI_OPCODE_ADD].emit = add_emit_cpu;
    bld_base->op_actions[TGSI_OPCODE_ARL].emit = arl_emit_cpu;
+   bld_base->op_actions[TGSI_OPCODE_ARR].emit = arr_emit_cpu;
    bld_base->op_actions[TGSI_OPCODE_CEIL].emit = ceil_emit_cpu;
    bld_base->op_actions[TGSI_OPCODE_CND].emit = cnd_emit_cpu;
    bld_base->op_actions[TGSI_OPCODE_COS].emit = cos_emit_cpu;
index 9a12db7842df0b2a076073173dc7ee63a59274a7..1abee4044d9703e709596b01d1976a7a2282a832 100644 (file)
@@ -1027,6 +1027,8 @@ emit_store_chan(
       break;
 
    case TGSI_FILE_ADDRESS:
+      assert(dtype == TGSI_TYPE_SIGNED);
+      assert(LLVMTypeOf(value) == bld_base->base.int_vec_type);
       lp_exec_mask_store(&bld->exec_mask, bld_store, pred, value,
                          bld->addr[reg->Register.Index][chan_index]);
       break;
@@ -1377,6 +1379,11 @@ lp_emit_declaration_soa(
          break;
 
       case TGSI_FILE_ADDRESS:
+        /* ADDR registers are the only allocated with an integer LLVM IR type,
+         * as they are guaranteed to always have integers.
+         * XXX: Not sure if this exception is worthwhile (or the whole idea of
+         * an ADDR register for that matter).
+         */
          assert(idx < LP_MAX_TGSI_ADDRS);
          for (i = 0; i < TGSI_NUM_CHANNELS; i++)
             bld->addr[idx][i] = lp_build_alloca(gallivm, bld_base->base.int_vec_type, "addr");
index a44f48ca88192fdc8fa121472dd9308f80bbbb12..81df96b3c7a0799d069d660e98c5a8f48839170a 100644 (file)
@@ -333,6 +333,7 @@ tgsi_opcode_infer_dst_type( uint opcode )
    case TGSI_OPCODE_MOD:
    case TGSI_OPCODE_UARL:
    case TGSI_OPCODE_ARL:
+   case TGSI_OPCODE_ARR:
    case TGSI_OPCODE_IABS:
    case TGSI_OPCODE_ISSG:
       return TGSI_TYPE_SIGNED;