[Mesa-dev] [PATCH v2 5/6] radeonsi: prepare 64-bit integer support. (v2)

Nicolai Hähnle nhaehnle at gmail.com
Mon Sep 19 13:08:34 UTC 2016


From: Dave Airlie <airlied at redhat.com>

v2:
- no PIPE_CAP_INT64 yet
- emit DIV/MOD without the divide-by-zero workaround

Reviewed-by: Marek Olšák <marek.olsak at amd.com> (v1)
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 .../drivers/radeon/radeon_setup_tgsi_llvm.c        | 69 +++++++++++++++++++---
 1 file changed, 62 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index 4fa43cd..bcb3143 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -44,20 +44,23 @@
 
 LLVMTypeRef tgsi2llvmtype(struct lp_build_tgsi_context *bld_base,
 			  enum tgsi_opcode_type type)
 {
 	LLVMContextRef ctx = bld_base->base.gallivm->context;
 
 	switch (type) {
 	case TGSI_TYPE_UNSIGNED:
 	case TGSI_TYPE_SIGNED:
 		return LLVMInt32TypeInContext(ctx);
+	case TGSI_TYPE_UNSIGNED64:
+	case TGSI_TYPE_SIGNED64:
+		return LLVMInt64TypeInContext(ctx);
 	case TGSI_TYPE_DOUBLE:
 		return LLVMDoubleTypeInContext(ctx);
 	case TGSI_TYPE_UNTYPED:
 	case TGSI_TYPE_FLOAT:
 		return LLVMFloatTypeInContext(ctx);
 	default: break;
 	}
 	return 0;
 }
 
@@ -1173,26 +1176,32 @@ void radeon_llvm_emit_prepare_cube_coords(struct lp_build_tgsi_context *bld_base
 
 static void emit_icmp(const struct lp_build_tgsi_action *action,
 		      struct lp_build_tgsi_context *bld_base,
 		      struct lp_build_emit_data *emit_data)
 {
 	unsigned pred;
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 	LLVMContextRef context = bld_base->base.gallivm->context;
 
 	switch (emit_data->inst->Instruction.Opcode) {
-	case TGSI_OPCODE_USEQ: pred = LLVMIntEQ; break;
-	case TGSI_OPCODE_USNE: pred = LLVMIntNE; break;
-	case TGSI_OPCODE_USGE: pred = LLVMIntUGE; break;
-	case TGSI_OPCODE_USLT: pred = LLVMIntULT; break;
-	case TGSI_OPCODE_ISGE: pred = LLVMIntSGE; break;
-	case TGSI_OPCODE_ISLT: pred = LLVMIntSLT; break;
+	case TGSI_OPCODE_USEQ:
+	case TGSI_OPCODE_U64SEQ: pred = LLVMIntEQ; break;
+	case TGSI_OPCODE_USNE:
+	case TGSI_OPCODE_U64SNE: pred = LLVMIntNE; break;
+	case TGSI_OPCODE_USGE:
+	case TGSI_OPCODE_U64SGE: pred = LLVMIntUGE; break;
+	case TGSI_OPCODE_USLT:
+	case TGSI_OPCODE_U64SLT: pred = LLVMIntULT; break;
+	case TGSI_OPCODE_ISGE:
+	case TGSI_OPCODE_I64SGE: pred = LLVMIntSGE; break;
+	case TGSI_OPCODE_ISLT:
+	case TGSI_OPCODE_I64SLT: pred = LLVMIntSLT; break;
 	default:
 		assert(!"unknown instruction");
 		pred = 0;
 		break;
 	}
 
 	LLVMValueRef v = LLVMBuildICmp(builder, pred,
 			emit_data->args[0], emit_data->args[1],"");
 
 	v = LLVMBuildSExtOrBitCast(builder, v,
@@ -1434,21 +1443,26 @@ static void emit_xor(const struct lp_build_tgsi_action *action,
 }
 
 static void emit_ssg(const struct lp_build_tgsi_action *action,
 		     struct lp_build_tgsi_context *bld_base,
 		     struct lp_build_emit_data *emit_data)
 {
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 
 	LLVMValueRef cmp, val;
 
-	if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_ISSG) {
+	if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_I64SSG) {
+		cmp = LLVMBuildICmp(builder, LLVMIntSGT, emit_data->args[0], bld_base->int64_bld.zero, "");
+		val = LLVMBuildSelect(builder, cmp, bld_base->int64_bld.one, emit_data->args[0], "");
+		cmp = LLVMBuildICmp(builder, LLVMIntSGE, val, bld_base->int64_bld.zero, "");
+		val = LLVMBuildSelect(builder, cmp, val, LLVMConstInt(bld_base->int64_bld.elem_type, -1, true), "");
+	} else if (emit_data->inst->Instruction.Opcode == TGSI_OPCODE_ISSG) {
 		cmp = LLVMBuildICmp(builder, LLVMIntSGT, emit_data->args[0], bld_base->int_bld.zero, "");
 		val = LLVMBuildSelect(builder, cmp, bld_base->int_bld.one, emit_data->args[0], "");
 		cmp = LLVMBuildICmp(builder, LLVMIntSGE, val, bld_base->int_bld.zero, "");
 		val = LLVMBuildSelect(builder, cmp, val, LLVMConstInt(bld_base->int_bld.elem_type, -1, true), "");
 	} else { // float SSG
 		cmp = LLVMBuildFCmp(builder, LLVMRealOGT, emit_data->args[0], bld_base->base.zero, "");
 		val = LLVMBuildSelect(builder, cmp, bld_base->base.one, emit_data->args[0], "");
 		cmp = LLVMBuildFCmp(builder, LLVMRealOGE, val, bld_base->base.zero, "");
 		val = LLVMBuildSelect(builder, cmp, val, LLVMConstReal(bld_base->base.elem_type, -1), "");
 	}
@@ -1698,29 +1712,33 @@ static void emit_minmax_int(const struct lp_build_tgsi_action *action,
 			    struct lp_build_tgsi_context *bld_base,
 			    struct lp_build_emit_data *emit_data)
 {
 	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
 	LLVMIntPredicate op;
 
 	switch (emit_data->info->opcode) {
 	default:
 		assert(0);
 	case TGSI_OPCODE_IMAX:
+	case TGSI_OPCODE_I64MAX:
 		op = LLVMIntSGT;
 		break;
 	case TGSI_OPCODE_IMIN:
+	case TGSI_OPCODE_I64MIN:
 		op = LLVMIntSLT;
 		break;
 	case TGSI_OPCODE_UMAX:
+	case TGSI_OPCODE_U64MAX:
 		op = LLVMIntUGT;
 		break;
 	case TGSI_OPCODE_UMIN:
+	case TGSI_OPCODE_U64MIN:
 		op = LLVMIntULT;
 		break;
 	}
 
 	emit_data->output[emit_data->chan] =
 		LLVMBuildSelect(builder,
 				LLVMBuildICmp(builder, op, emit_data->args[0],
 					      emit_data->args[1], ""),
 				emit_data->args[0],
 				emit_data->args[1], "");
@@ -1869,20 +1887,32 @@ void radeon_llvm_context_init(struct radeon_llvm_context *ctx, const char *tripl
 
 	lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
 	lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
 	lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
 	{
 		struct lp_type dbl_type;
 		dbl_type = type;
 		dbl_type.width *= 2;
 		lp_build_context_init(&ctx->soa.bld_base.dbl_bld, &ctx->gallivm, dbl_type);
 	}
+	{
+		struct lp_type dtype;
+		dtype = lp_uint_type(type);
+		dtype.width *= 2;
+		lp_build_context_init(&ctx->soa.bld_base.uint64_bld, &ctx->gallivm, dtype);
+	}
+	{
+		struct lp_type dtype;
+		dtype = lp_int_type(type);
+		dtype.width *= 2;
+		lp_build_context_init(&ctx->soa.bld_base.int64_bld, &ctx->gallivm, dtype);
+	}
 
 	bld_base->soa = 1;
 	bld_base->emit_store = radeon_llvm_emit_store;
 	bld_base->emit_swizzle = emit_swizzle;
 	bld_base->emit_declaration = emit_declaration;
 	bld_base->emit_immediate = emit_immediate;
 
 	bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = radeon_llvm_emit_fetch;
 	bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = radeon_llvm_emit_fetch;
 	bld_base->emit_fetch_funcs[TGSI_FILE_TEMPORARY] = radeon_llvm_emit_fetch;
@@ -2013,20 +2043,45 @@ void radeon_llvm_context_init(struct radeon_llvm_context *ctx, const char *tripl
 	bld_base->op_actions[TGSI_OPCODE_USEQ].emit = emit_icmp;
 	bld_base->op_actions[TGSI_OPCODE_USGE].emit = emit_icmp;
 	bld_base->op_actions[TGSI_OPCODE_USHR].emit = emit_ushr;
 	bld_base->op_actions[TGSI_OPCODE_USLT].emit = emit_icmp;
 	bld_base->op_actions[TGSI_OPCODE_USNE].emit = emit_icmp;
 	bld_base->op_actions[TGSI_OPCODE_U2F].emit = emit_u2f;
 	bld_base->op_actions[TGSI_OPCODE_XOR].emit = emit_xor;
 	bld_base->op_actions[TGSI_OPCODE_UCMP].emit = emit_ucmp;
 	bld_base->op_actions[TGSI_OPCODE_UP2H].fetch_args = up2h_fetch_args;
 	bld_base->op_actions[TGSI_OPCODE_UP2H].emit = emit_up2h;
+
+	bld_base->op_actions[TGSI_OPCODE_I64MAX].emit = emit_minmax_int;
+	bld_base->op_actions[TGSI_OPCODE_I64MIN].emit = emit_minmax_int;
+	bld_base->op_actions[TGSI_OPCODE_U64MAX].emit = emit_minmax_int;
+	bld_base->op_actions[TGSI_OPCODE_U64MIN].emit = emit_minmax_int;
+	bld_base->op_actions[TGSI_OPCODE_I64ABS].emit = emit_iabs;
+	bld_base->op_actions[TGSI_OPCODE_I64SSG].emit = emit_ssg;
+	bld_base->op_actions[TGSI_OPCODE_I64NEG].emit = emit_ineg;
+
+	bld_base->op_actions[TGSI_OPCODE_U64SEQ].emit = emit_icmp;
+	bld_base->op_actions[TGSI_OPCODE_U64SNE].emit = emit_icmp;
+	bld_base->op_actions[TGSI_OPCODE_U64SGE].emit = emit_icmp;
+	bld_base->op_actions[TGSI_OPCODE_U64SLT].emit = emit_icmp;
+	bld_base->op_actions[TGSI_OPCODE_I64SGE].emit = emit_icmp;
+	bld_base->op_actions[TGSI_OPCODE_I64SLT].emit = emit_icmp;
+
+	bld_base->op_actions[TGSI_OPCODE_U64ADD].emit = emit_uadd;
+	bld_base->op_actions[TGSI_OPCODE_U64SHL].emit = emit_shl;
+	bld_base->op_actions[TGSI_OPCODE_U64SHR].emit = emit_ushr;
+	bld_base->op_actions[TGSI_OPCODE_I64SHR].emit = emit_ishr;
+
+	bld_base->op_actions[TGSI_OPCODE_U64MOD].emit = emit_umod;
+	bld_base->op_actions[TGSI_OPCODE_I64MOD].emit = emit_mod;
+	bld_base->op_actions[TGSI_OPCODE_U64DIV].emit = emit_udiv;
+	bld_base->op_actions[TGSI_OPCODE_I64DIV].emit = emit_idiv;
 }
 
 void radeon_llvm_create_func(struct radeon_llvm_context *ctx,
 			     LLVMTypeRef *return_types, unsigned num_return_elems,
 			     LLVMTypeRef *ParamTypes, unsigned ParamCount)
 {
 	LLVMTypeRef main_fn_type, ret_type;
 	LLVMBasicBlockRef main_fn_body;
 
 	if (num_return_elems)
-- 
2.7.4



More information about the mesa-dev mailing list