Signed-off-by: Rhys Perry <pendingchao...@gmail.com>
---
 src/amd/common/ac_llvm_build.c  | 123 ++++++++++++++++++++++++++++++--
 src/amd/common/ac_llvm_build.h  |  22 +++++-
 src/amd/common/ac_nir_to_llvm.c |  30 ++++----
 3 files changed, 154 insertions(+), 21 deletions(-)

diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index 154cc696a2..cc7c6da5a4 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -87,12 +87,16 @@ ac_llvm_context_init(struct ac_llvm_context *ctx,
        ctx->v4f32 = LLVMVectorType(ctx->f32, 4);
        ctx->v8i32 = LLVMVectorType(ctx->i32, 8);
 
+       ctx->i8_0 = LLVMConstInt(ctx->i8, 0, false);
+       ctx->i8_1 = LLVMConstInt(ctx->i8, 1, false);
        ctx->i16_0 = LLVMConstInt(ctx->i16, 0, false);
        ctx->i16_1 = LLVMConstInt(ctx->i16, 1, false);
        ctx->i32_0 = LLVMConstInt(ctx->i32, 0, false);
        ctx->i32_1 = LLVMConstInt(ctx->i32, 1, false);
        ctx->i64_0 = LLVMConstInt(ctx->i64, 0, false);
        ctx->i64_1 = LLVMConstInt(ctx->i64, 1, false);
+       ctx->f16_0 = LLVMConstReal(ctx->f16, 0.0);
+       ctx->f16_1 = LLVMConstReal(ctx->f16, 1.0);
        ctx->f32_0 = LLVMConstReal(ctx->f32, 0.0);
        ctx->f32_1 = LLVMConstReal(ctx->f32, 1.0);
        ctx->f64_0 = LLVMConstReal(ctx->f64, 0.0);
@@ -201,7 +205,9 @@ ac_get_type_size(LLVMTypeRef type)
 
 static LLVMTypeRef to_integer_type_scalar(struct ac_llvm_context *ctx, 
LLVMTypeRef t)
 {
-       if (t == ctx->f16 || t == ctx->i16)
+       if (t == ctx->i8)
+               return ctx->i8;
+       else if (t == ctx->f16 || t == ctx->i16)
                return ctx->i16;
        else if (t == ctx->f32 || t == ctx->i32)
                return ctx->i32;
@@ -268,6 +274,110 @@ ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v)
        return LLVMBuildBitCast(ctx->builder, v, ac_to_float_type(ctx, type), 
"");
 }
 
+LLVMValueRef ac_get_zerof(struct ac_llvm_context *ctx, LLVMTypeRef t)
+{
+       if (t == ctx->f16)
+               return ctx->f16_0;
+       else if (t == ctx->f32)
+               return ctx->f32_0;
+       else if (t == ctx->f64)
+               return ctx->f64_0;
+       else
+               unreachable("Unhandled float size");
+}
+
+LLVMValueRef ac_get_onef(struct ac_llvm_context *ctx, LLVMTypeRef t)
+{
+       if (t == ctx->f16)
+               return ctx->f16_1;
+       else if (t == ctx->f32)
+               return ctx->f32_1;
+       else if (t == ctx->f64)
+               return ctx->f64_1;
+       else
+               unreachable("Unhandled float size");
+}
+
+LLVMValueRef ac_get_zero(struct ac_llvm_context *ctx, LLVMTypeRef t)
+{
+       if (t == ctx->i8)
+               return ctx->i8_0;
+       else if (t == ctx->i16)
+               return ctx->i16_0;
+       else if (t == ctx->i32)
+               return ctx->i32_0;
+       else if (t == ctx->i64)
+               return ctx->i64_0;
+       else
+               unreachable("Unhandled bit size");
+}
+
+LLVMValueRef ac_get_one(struct ac_llvm_context *ctx, LLVMTypeRef t)
+{
+       if (t == ctx->i8)
+               return ctx->i8_1;
+       else if (t == ctx->i16)
+               return ctx->i16_1;
+       else if (t == ctx->i32)
+               return ctx->i32_1;
+       else if (t == ctx->i64)
+               return ctx->i64_1;
+       else
+               unreachable("Unhandled bit size");
+}
+
+LLVMTypeRef ac_float_of_size(struct ac_llvm_context *ctx, unsigned bit_size)
+{
+       switch (bit_size) {
+       case 16:
+               return ctx->f16;
+       case 32:
+               return ctx->f32;
+       case 64:
+               return ctx->f64;
+       default:
+               unreachable("Unhandled bit size");
+       }
+}
+
+LLVMTypeRef ac_int_of_size(struct ac_llvm_context *ctx, unsigned bit_size)
+{
+       switch (bit_size) {
+       case 8:
+               return ctx->i8;
+       case 16:
+               return ctx->i16;
+       case 32:
+               return ctx->i32;
+       case 64:
+               return ctx->i64;
+       default:
+               unreachable("Unhandled bit size");
+       }
+}
+
+LLVMValueRef ac_build_ui_cast(struct ac_llvm_context *ctx, LLVMValueRef v, 
LLVMTypeRef t)
+{
+       unsigned new_bit_size = ac_get_elem_bits(ctx, t);
+       unsigned old_bit_size = ac_get_elem_bits(ctx, LLVMTypeOf(v));
+       if (new_bit_size > old_bit_size)
+               return LLVMBuildZExt(ctx->builder, v, t, "");
+       else if (new_bit_size < old_bit_size)
+               return LLVMBuildTrunc(ctx->builder, v, t, "");
+       else
+               return v;
+}
+
+LLVMValueRef ac_build_reinterpret(struct ac_llvm_context *ctx, LLVMValueRef v, 
LLVMTypeRef t)
+{
+       if (LLVMTypeOf(v) == t)
+               return v;
+
+       v = ac_to_integer(ctx, v);
+       v = ac_build_ui_cast(ctx, v, ac_to_integer_type(ctx, t));
+       return LLVMBuildBitCast(ctx->builder, v, t, "");
+}
+
 
 LLVMValueRef
 ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name,
@@ -1309,15 +1419,18 @@ LLVMValueRef 
ac_build_buffer_load_format_gfx9_safe(struct ac_llvm_context *ctx,
 }
 
 LLVMValueRef
-ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
+ac_build_tbuffer_load_short_byte(struct ac_llvm_context *ctx,
                            LLVMValueRef rsrc,
                            LLVMValueRef vindex,
                            LLVMValueRef voffset,
                                LLVMValueRef soffset,
                                LLVMValueRef immoffset,
-                               LLVMValueRef glc)
+                               LLVMValueRef glc,
+                               unsigned size)
 {
+       assert(size == 1 || size == 2);
        const char *name = "llvm.amdgcn.tbuffer.load.i32";
+       int data_format = size == 1 ? V_008F0C_BUF_DATA_FORMAT_8 : 
V_008F0C_BUF_DATA_FORMAT_16;
        LLVMTypeRef type = ctx->i32;
        LLVMValueRef params[] = {
                                rsrc,
@@ -1325,13 +1438,13 @@ ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
                                voffset,
                                soffset,
                                immoffset,
-                               LLVMConstInt(ctx->i32, 
V_008F0C_BUF_DATA_FORMAT_16, false),
+                               LLVMConstInt(ctx->i32, data_format, false),
                                LLVMConstInt(ctx->i32, 
V_008F0C_BUF_NUM_FORMAT_UINT, false),
                                glc,
                                ctx->i1false,
        };
        LLVMValueRef res = ac_build_intrinsic(ctx, name, type, params, 9, 0);
-       return LLVMBuildTrunc(ctx->builder, res, ctx->i16, "");
+       return LLVMBuildTrunc(ctx->builder, res, ac_int_of_size(ctx, size * 8), 
"");
 }
 
 /**
diff --git a/src/amd/common/ac_llvm_build.h b/src/amd/common/ac_llvm_build.h
index e90c8c21ad..34622bda10 100644
--- a/src/amd/common/ac_llvm_build.h
+++ b/src/amd/common/ac_llvm_build.h
@@ -76,12 +76,16 @@ struct ac_llvm_context {
        LLVMTypeRef v4f32;
        LLVMTypeRef v8i32;
 
+       LLVMValueRef i8_0;
+       LLVMValueRef i8_1;
        LLVMValueRef i16_0;
        LLVMValueRef i16_1;
        LLVMValueRef i32_0;
        LLVMValueRef i32_1;
        LLVMValueRef i64_0;
        LLVMValueRef i64_1;
+       LLVMValueRef f16_0;
+       LLVMValueRef f16_1;
        LLVMValueRef f32_0;
        LLVMValueRef f32_1;
        LLVMValueRef f64_0;
@@ -132,6 +136,19 @@ LLVMValueRef ac_to_integer_or_pointer(struct 
ac_llvm_context *ctx, LLVMValueRef
 LLVMTypeRef ac_to_float_type(struct ac_llvm_context *ctx, LLVMTypeRef t);
 LLVMValueRef ac_to_float(struct ac_llvm_context *ctx, LLVMValueRef v);
 
+LLVMValueRef ac_get_zerof(struct ac_llvm_context *ctx, LLVMTypeRef t);
+LLVMValueRef ac_get_onef(struct ac_llvm_context *ctx, LLVMTypeRef t);
+
+LLVMValueRef ac_get_zero(struct ac_llvm_context *ctx, LLVMTypeRef t);
+LLVMValueRef ac_get_one(struct ac_llvm_context *ctx, LLVMTypeRef t);
+
+LLVMTypeRef ac_float_of_size(struct ac_llvm_context *ctx, unsigned bit_size);
+LLVMTypeRef ac_int_of_size(struct ac_llvm_context *ctx, unsigned bit_size);
+
+LLVMValueRef ac_build_ui_cast(struct ac_llvm_context *ctx, LLVMValueRef v, 
LLVMTypeRef t);
+
+LLVMValueRef ac_build_reinterpret(struct ac_llvm_context *ctx, LLVMValueRef v, 
LLVMTypeRef t);
+
 LLVMValueRef
 ac_build_intrinsic(struct ac_llvm_context *ctx, const char *name,
                   LLVMTypeRef return_type, LLVMValueRef *params,
@@ -290,13 +307,14 @@ LLVMValueRef ac_build_buffer_load_format_gfx9_safe(struct 
ac_llvm_context *ctx,
                                                   bool can_speculate);
 
 LLVMValueRef
-ac_build_tbuffer_load_short(struct ac_llvm_context *ctx,
+ac_build_tbuffer_load_short_byte(struct ac_llvm_context *ctx,
                            LLVMValueRef rsrc,
                            LLVMValueRef vindex,
                            LLVMValueRef voffset,
                                LLVMValueRef soffset,
                                LLVMValueRef immoffset,
-                               LLVMValueRef glc);
+                               LLVMValueRef glc,
+                               unsigned size);
 
 LLVMValueRef
 ac_get_thread_id(struct ac_llvm_context *ctx);
diff --git a/src/amd/common/ac_nir_to_llvm.c b/src/amd/common/ac_nir_to_llvm.c
index 4a4c09cf5f..2e9fd7b689 100644
--- a/src/amd/common/ac_nir_to_llvm.c
+++ b/src/amd/common/ac_nir_to_llvm.c
@@ -1652,13 +1652,14 @@ static LLVMValueRef visit_load_buffer(struct 
ac_nir_context *ctx,
 
                LLVMValueRef ret;
                if (load_bytes == 2) {
-                       ret = ac_build_tbuffer_load_short(&ctx->ac,
-                                                         rsrc,
-                                                         vindex,
-                                                         offset,
-                                                         ctx->ac.i32_0,
-                                                         immoffset,
-                                                         glc);
+                       ret = ac_build_tbuffer_load_short_byte(&ctx->ac,
+                                                              rsrc,
+                                                              vindex,
+                                                              offset,
+                                                              ctx->ac.i32_0,
+                                                              immoffset,
+                                                              glc,
+                                                              2);
                } else {
                        const char *load_name;
                        LLVMTypeRef data_type;
@@ -1723,13 +1724,14 @@ static LLVMValueRef visit_load_ubo_buffer(struct 
ac_nir_context *ctx,
        if (instr->dest.ssa.bit_size == 16) {
                LLVMValueRef results[num_components];
                for (unsigned i = 0; i < num_components; ++i) {
-                       results[i] = ac_build_tbuffer_load_short(&ctx->ac,
-                                                                rsrc,
-                                                                ctx->ac.i32_0,
-                                                                offset,
-                                                                ctx->ac.i32_0,
-                                                                
LLVMConstInt(ctx->ac.i32, 2 * i, 0),
-                                                                
ctx->ac.i1false);
+                       results[i] = ac_build_tbuffer_load_short_byte(&ctx->ac,
+                                                                     rsrc,
+                                                                     
ctx->ac.i32_0,
+                                                                     offset,
+                                                                     
ctx->ac.i32_0,
+                                                                     
LLVMConstInt(ctx->ac.i32, 2 * i, 0),
+                                                                     
ctx->ac.i1false,
+                                                                     2);
                }
                ret = ac_build_gather_values(&ctx->ac, results, num_components);
        } else {
-- 
2.19.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to