Hi Jose,

I updated the patch(see below), I am using python samples, modifying
the tri.py to use it because the regress tests are outdated.
Now we have we can get the msb and the lsb values from double operations.

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 441aeba..70330dc 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -963,6 +963,68 @@ emit_kil(
       lp_build_mask_update(bld->mask, mask);
 }

+static LLVMValueRef
+lp_cast_to_double(struct lp_build_context *bld,
+                   LLVMValueRef a,
+                   LLVMValueRef b)
+{
+   struct lp_type type;
+   LLVMValueRef res;
+   LLVMTypeRef vec_type;
+   LLVMTypeRef vec_double_type;
+
+   type = lp_type_uint_vec(64);
+   vec_type = lp_build_vec_type(type);
+
+   a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
+   b = LLVMBuildBitCast(bld->builder, b, vec_type, "");
+
+   res = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type, 32),"");
+   res = LLVMBuildOr(bld->builder, res, b, "");
+
+   a = LLVMBuildBitCast(bld->builder, a, bld->vec_type, "");
+   b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, "");
+
+   type = lp_type_float_vec(64);
+   bld->type = type;
+   vec_double_type = lp_build_vec_type(type);
+   res = LLVMBuildBitCast(bld->builder, res, vec_double_type, "");
+
+   return res;
+}
+
+static LLVMValueRef
+lp_cast_from_double_msb(struct lp_build_context *bld,
+                        LLVMValueRef double_value)
+{
+   LLVMTypeRef double_type;
+   LLVMValueRef res;
+   struct lp_type type = lp_type_uint_vec(64);
+
+   double_type = lp_build_vec_type(type);
+   res = LLVMBuildBitCast(bld->builder, double_value, double_type, "");
+   res = LLVMBuildLShr(bld->builder, res,
lp_build_const_int_vec(type, 32), "");
+   res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+
+   return res;
+}
+
+
+static LLVMValueRef
+lp_cast_from_double_lsb(struct lp_build_context *bld,
+                        LLVMValueRef double_value)
+{
+   LLVMTypeRef double_type;
+   LLVMValueRef res;
+   struct lp_type type = lp_type_uint_vec(64);
+
+   double_type = lp_build_vec_type(type);
+   res = LLVMBuildBitCast(bld->builder, double_value, double_type, "");
+   res = LLVMBuildAnd(bld->builder, res, lp_build_const_int_vec(type,
0x00000000FFFFFFFF), "");
+   res = LLVMBuildBitCast(bld->builder, res, bld->vec_type, "");
+
+   return res;
+}

 /**
  * Predicated fragment kill.
@@ -1982,6 +2044,37 @@ emit_instruction(
    case TGSI_OPCODE_NOP:
       break;

+   case TGSI_OPCODE_DMUL:
+      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) &&
IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
+         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
+
+         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
+         tmp3 = emit_fetch( bld, inst, 1, CHAN_Y );
+
+         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
+         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
+         tmp4 = lp_build_mul(&bld->base, src0, src1);
+         dst0[CHAN_X] = lp_cast_from_double_msb(&bld->base, tmp4);
+         dst0[CHAN_Y] = lp_cast_from_double_lsb(&bld->base, tmp4);
+      }
+
+      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) &&
IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
+         tmp0 = emit_fetch( bld, inst, 0, CHAN_Z );
+         tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
+
+         tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
+         tmp3 = emit_fetch( bld, inst, 1, CHAN_W );
+
+         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
+         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
+         tmp4 = lp_build_mul(&bld->base, src0, src1);
+         dst0[CHAN_Z] = lp_cast_from_double_msb(&bld->base, tmp4);
+         dst0[CHAN_W] = lp_cast_from_double_lsb(&bld->base, tmp4);
+
+      }
+      break;
+
    default:
       return FALSE;
    }
-- 
1.7.0.4



On Tue, Sep 28, 2010 at 5:32 PM, Jose Fonseca <jfons...@vmware.com> wrote:
> Sorry Igor. I dropped the ball on your previous submission.
>
> I still don't understand what the code does, nor how the generated code will 
> look like. Granted, your implementation is better than no implementation, but 
> I'd like to go a bit further and get this nailed, and not have to redo this 
> code.
>
> Is there a simple test case I can use to exercise and test this?
>
> Jose
>
> ________________________________________
> From: mesa-dev-bounces+jfonseca=vmware....@lists.freedesktop.org 
> [mesa-dev-bounces+jfonseca=vmware....@lists.freedesktop.org] On Behalf Of 
> Igor Oliveira [igor.olive...@openbossa.org]
> Sent: Tuesday, September 28, 2010 20:34
> To: mesa-dev@lists.freedesktop.org
> Subject: [Mesa-dev] [PATCH] llvmpipe: add initial support to double opcodes   
>   in llvmpipe.
>
> - create helper function
> - implement DMUL opcode
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |   78 
> +++++++++++++++++++++++
>  1 files changed, 78 insertions(+), 0 deletions(-)
>
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index ca8db9c..c9174ce 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -970,6 +970,56 @@ emit_kil(
>       lp_build_mask_update(bld->mask, mask);
>  }
>
> +static LLVMValueRef
> +lp_cast_to_double(struct lp_build_context *bld,
> +                   LLVMValueRef a,
> +                   LLVMValueRef b)
> +{
> +   struct lp_type type;
> +   LLVMValueRef res;
> +   LLVMTypeRef vec_type;
> +   LLVMTypeRef vec_double_type;
> +
> +   assert(lp_check_value(bld->type, a));
> +   assert(lp_check_value(bld->type, b));
> +
> +   type = lp_type_uint_vec(64);
> +   vec_type = lp_build_vec_type(type);
> +
> +   a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
> +   b = LLVMBuildBitCast(bld->builder, b, vec_type, "");
> +
> +   res = LLVMBuildShl(bld->builder, a, lp_build_const_int_vec(type, 32),"");
> +   res = LLVMBuildOr(bld->builder, res, b, "");
> +
> +   a = LLVMBuildBitCast(bld->builder, a, bld->vec_type, "");
> +   b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, "");
> +
> +   type = lp_type_float_vec(64);
> +   vec_double_type = lp_build_vec_type(type);
> +   res = LLVMBuildBitCast(bld->builder, res, vec_double_type, "");
> +
> +   return res;
> +}
> +
> +static void
> +lp_cast_from_double(struct lp_build_context *bld,
> +                    LLVMValueRef double_value,
> +                    LLVMValueRef a,
> +                    LLVMValueRef b)
> +{
> +   LLVMTypeRef double_type;
> +   struct lp_type type = lp_type_uint_vec(64);
> +
> +   double_type = lp_build_vec_type(type);
> +   a = LLVMBuildBitCast(bld->builder, double_value, double_type, "");
> +
> +   b = LLVMBuildAnd(bld->builder, a, lp_build_const_int_vec(type,
> 0x00000000FFFFFFFF), "");
> +
> +   a = LLVMBuildBitCast(bld->builder, a, bld->vec_type, "");
> +   b = LLVMBuildBitCast(bld->builder, b, bld->vec_type, "");
> +}
> +
>
>  /**
>  * Predicated fragment kill.
> @@ -1988,6 +2038,34 @@ emit_instruction(
>    case TGSI_OPCODE_NOP:
>       break;
>
> +   case TGSI_OPCODE_DMUL:
> +      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) &&
> IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
> +         tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
> +         tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
> +
> +         tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
> +         tmp3 = emit_fetch( bld, inst, 1, CHAN_Y );
> +
> +         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
> +         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
> +         tmp4 = lp_build_mul(&bld->base, src0, src1);
> +         lp_cast_from_double(&bld->base, tmp4, dst0[CHAN_X], dst0[CHAN_Y]);
> +      }
> +
> +      if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) &&
> IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
> +         tmp0 = emit_fetch( bld, inst, 0, CHAN_Z );
> +         tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
> +
> +         tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
> +         tmp3 = emit_fetch( bld, inst, 1, CHAN_W );
> +
> +         src0 = lp_cast_to_double(&bld->base, tmp0, tmp1);
> +         src1 = lp_cast_to_double(&bld->base, tmp2, tmp3);
> +         tmp4 = lp_build_mul(&bld->base, src0, src1);
> +         lp_cast_from_double(&bld->base, tmp4, dst0[CHAN_Z], dst0[CHAN_W]);
> +      }
> +      break;
> +
>    default:
>       return FALSE;
>    }
> --
> 1.7.0.4
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to