summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/llvmpipe/lp_bld_flow.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/llvmpipe/lp_bld_flow.c')
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_flow.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.c b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
index 5fc85a19b8..d94af0dea4 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_flow.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
@@ -31,9 +31,93 @@
* @author Jose Fonseca <jfonseca@vmware.com>
*/
+#include "util/u_debug.h"
+
+#include "lp_bld_type.h"
#include "lp_bld_flow.h"
+void
+lp_build_mask_begin(struct lp_build_mask_context *mask,
+ LLVMBuilderRef builder,
+ union lp_type type,
+ LLVMValueRef value)
+{
+ memset(mask, 0, sizeof *mask);
+
+ mask->builder = builder;
+ mask->reg_type = LLVMIntType(type.width * type.length);
+ mask->value = value;
+}
+
+
+void
+lp_build_mask_update(struct lp_build_mask_context *mask,
+ LLVMValueRef value)
+{
+
+ LLVMValueRef cond;
+ LLVMBasicBlockRef current_block;
+ LLVMBasicBlockRef next_block;
+ LLVMBasicBlockRef new_block;
+
+ if(mask->value)
+ mask->value = LLVMBuildAnd(mask->builder, mask->value, value, "");
+ else
+ mask->value = value;
+
+ cond = LLVMBuildICmp(mask->builder,
+ LLVMIntEQ,
+ LLVMBuildBitCast(mask->builder, mask->value, mask->reg_type, ""),
+ LLVMConstNull(mask->reg_type),
+ "");
+
+ current_block = LLVMGetInsertBlock(mask->builder);
+
+ if(!mask->skip_block) {
+ LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
+ mask->skip_block = LLVMAppendBasicBlock(function, "skip");
+
+ mask->phi = LLVMBuildPhi(mask->builder, LLVMTypeOf(mask->value), "");
+ }
+
+ next_block = LLVMGetNextBasicBlock(current_block);
+ assert(next_block);
+ if(next_block) {
+ new_block = LLVMInsertBasicBlock(next_block, "");
+ }
+ else {
+ LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
+ new_block = LLVMAppendBasicBlock(function, "");
+ }
+
+ LLVMAddIncoming(mask->phi, &mask->value, &current_block, 1);
+ LLVMBuildCondBr(mask->builder, cond, mask->skip_block, new_block);
+
+ LLVMPositionBuilderAtEnd(mask->builder, new_block);
+}
+
+
+LLVMValueRef
+lp_build_mask_end(struct lp_build_mask_context *mask)
+{
+ if(mask->skip_block) {
+ LLVMBasicBlockRef current_block = LLVMGetInsertBlock(mask->builder);
+
+ LLVMAddIncoming(mask->phi, &mask->value, &current_block, 1);
+ LLVMBuildBr(mask->builder, mask->skip_block);
+
+ LLVMPositionBuilderAtEnd(mask->builder, mask->skip_block);
+
+ mask->value = mask->phi;
+ mask->phi = NULL;
+ mask->skip_block = NULL;
+ }
+
+ return mask->value;
+}
+
+
void
lp_build_loop_begin(LLVMBuilderRef builder,