summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolai Hähnle <nicolai.haehnle@amd.com>2017-09-13 15:33:34 +0200
committerNicolai Hähnle <nicolai.haehnle@amd.com>2018-03-14 09:04:05 +0100
commit051fd50743c954d3cb6c6007e5a6fdfab418b119 (patch)
tree101f8994de391da98387a047a92dbfcf8603b636
parenta464357c82c07261e53f6adc75fd36367b6dc5bf (diff)
DBG add ac_emit_sethalt
-rw-r--r--src/amd/common/ac_llvm_build.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/src/amd/common/ac_llvm_build.c b/src/amd/common/ac_llvm_build.c
index a3afcb3586..553ee1060c 100644
--- a/src/amd/common/ac_llvm_build.c
+++ b/src/amd/common/ac_llvm_build.c
@@ -30,6 +30,7 @@
#include "c11/threads.h"
#include <assert.h>
+#include <stdarg.h>
#include <stdio.h>
#include "ac_llvm_util.h"
@@ -194,6 +195,51 @@ ac_get_type_size(LLVMTypeRef type)
}
}
+static void ac_emit_sethalt(struct ac_llvm_context *ctx, ...)
+{
+ LLVMValueRef *values;
+ LLVMTypeRef *types;
+ va_list va;
+
+ va_start(va, ctx);
+ unsigned count = 0;
+ while (va_arg(va, void *) != NULL) {
+ va_arg(va, int);
+ count++;
+ }
+ va_end(va);
+
+ values = alloca(sizeof(*values) * count);
+ types = alloca(sizeof(*types) * count);
+ va_start(va, ctx);
+ for (unsigned i = 0; i < count; ++i) {
+ values[i] = va_arg(va, LLVMValueRef);
+
+ int vgpr = va_arg(va, int);
+ types[i] = vgpr ? ctx->f32 : ctx->i32;
+ values[i] = LLVMBuildBitCast(ctx->builder, values[i], types[i], "");
+ }
+ va_end(va);
+
+ char *registers = alloca(1 + 7 * count);
+ char *p = registers;
+ unsigned vgprs = 0;
+ unsigned sgprs = 0;
+ for (unsigned i = 0; i < count; ++i) {
+ if (i > 0)
+ *p++ = ',';
+ if (types[i] == ctx->f32)
+ p += sprintf(p, "{v%u}", vgprs++);
+ else
+ p += sprintf(p, "{s%u}", sgprs++);
+ }
+ *p = 0;
+
+ LLVMTypeRef ftype = LLVMFunctionType(ctx->voidt, types, count, false);
+ LLVMValueRef inlineasm = LLVMConstInlineAsm(ftype, "s_sethalt 1", registers, true, false);
+ LLVMBuildCall(ctx->builder, inlineasm, values, count, "");
+}
+
static LLVMTypeRef to_integer_type_scalar(struct ac_llvm_context *ctx, LLVMTypeRef t)
{
if (t == ctx->f16 || t == ctx->i16)