util: Move gallium's PIPE_FORMAT utils to /util/format/
[mesa.git] / src / gallium / auxiliary / gallivm / lp_bld_flow.h
index c2b50e1b6020fc1fb7d4759e38aac8728239313c..ddb3fdfd7b754031a20299508307096574933dcd 100644 (file)
 
 #include "gallivm/lp_bld.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 struct lp_type;
 
 
-struct lp_build_flow_context;
-
-
-struct lp_build_flow_context *
-lp_build_flow_create(LLVMBuilderRef builder);
-
-void
-lp_build_flow_destroy(struct lp_build_flow_context *flow);
-
-void
-lp_build_flow_scope_begin(struct lp_build_flow_context *flow);
-
-void
-lp_build_flow_scope_declare(struct lp_build_flow_context *flow,
-                            LLVMValueRef *variable);
+/**
+ * Early exit. Useful to skip to the end of a function or block when
+ * the execution mask becomes zero or when there is an error condition.
+ */
+struct lp_build_skip_context
+{
+   struct gallivm_state *gallivm;
 
-void
-lp_build_flow_scope_end(struct lp_build_flow_context *flow);
+   /** Block to skip to */
+   LLVMBasicBlockRef block;
+};
 
 void
-lp_build_flow_skip_begin(struct lp_build_flow_context *flow);
+lp_build_flow_skip_begin(struct lp_build_skip_context *ctx,
+                         struct gallivm_state *gallivm);
 
 void
-lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
+lp_build_flow_skip_cond_break(struct lp_build_skip_context *ctx,
                               LLVMValueRef cond);
 
 void
-lp_build_flow_skip_end(struct lp_build_flow_context *flow);
+lp_build_flow_skip_end(struct lp_build_skip_context *ctx);
 
 
 struct lp_build_mask_context
 {
-   struct lp_build_flow_context *flow;
+   struct lp_build_skip_context skip;
 
    LLVMTypeRef reg_type;
 
-   LLVMValueRef value;
+   LLVMValueRef var;
 };
 
 
 void
 lp_build_mask_begin(struct lp_build_mask_context *mask,
-                    struct lp_build_flow_context *flow,
+                    struct gallivm_state *gallivm,
                     struct lp_type type,
                     LLVMValueRef value);
 
+LLVMValueRef
+lp_build_mask_value(struct lp_build_mask_context *mask);
+
 /**
  * Bitwise AND the mask with the given value, if a previous mask was set.
  */
@@ -94,6 +94,9 @@ void
 lp_build_mask_update(struct lp_build_mask_context *mask,
                      LLVMValueRef value);
 
+void
+lp_build_mask_check(struct lp_build_mask_context *mask);
+
 LLVMValueRef
 lp_build_mask_end(struct lp_build_mask_context *mask);
 
@@ -107,37 +110,81 @@ lp_build_mask_end(struct lp_build_mask_context *mask);
  */
 struct lp_build_loop_state
 {
-  LLVMBasicBlockRef block;
-  LLVMValueRef counter;
+   LLVMBasicBlockRef block;
+   LLVMValueRef counter_var;
+   LLVMValueRef counter;
+   struct gallivm_state *gallivm;
 };
 
 
 void
-lp_build_loop_begin(LLVMBuilderRef builder,
-                    LLVMValueRef start,
-                    struct lp_build_loop_state *state);
-
+lp_build_loop_begin(struct lp_build_loop_state *state,
+                    struct gallivm_state *gallivm,
+                    LLVMValueRef start);
 
 void
-lp_build_loop_end(LLVMBuilderRef builder,
+lp_build_loop_end(struct lp_build_loop_state *state,
                   LLVMValueRef end,
-                  LLVMValueRef step,
-                  struct lp_build_loop_state *state);
+                  LLVMValueRef step);
+
+void
+lp_build_loop_force_set_counter(struct lp_build_loop_state *state,
+                                LLVMValueRef end);
 
+void
+lp_build_loop_force_reload_counter(struct lp_build_loop_state *state);
+void
+lp_build_loop_end_cond(struct lp_build_loop_state *state,
+                       LLVMValueRef end,
+                       LLVMValueRef step,
+                       LLVMIntPredicate cond);
 
 
+/**
+ * Implementation of simple C-style for loops
+ */
+struct lp_build_for_loop_state
+{
+   LLVMBasicBlockRef begin;
+   LLVMBasicBlockRef body;
+   LLVMBasicBlockRef exit;
+   LLVMValueRef counter_var;
+   LLVMValueRef counter;
+   LLVMValueRef step;
+   LLVMIntPredicate cond;
+   LLVMValueRef end;
+   struct gallivm_state *gallivm;
+};
+
+void
+lp_build_for_loop_begin(struct lp_build_for_loop_state *state,
+                        struct gallivm_state *gallivm,
+                        LLVMValueRef start,
+                        LLVMIntPredicate llvm_cond,
+                        LLVMValueRef end,
+                        LLVMValueRef step);
 
+void
+lp_build_for_loop_end(struct lp_build_for_loop_state *state);
+
+
+/**
+ * if/else/endif.
+ */
 struct lp_build_if_state
 {
-   LLVMBuilderRef builder;
-   struct lp_build_flow_context *flow;
+   struct gallivm_state *gallivm;
+   LLVMValueRef condition;
+   LLVMBasicBlockRef entry_block;
+   LLVMBasicBlockRef true_block;
+   LLVMBasicBlockRef false_block;
+   LLVMBasicBlockRef merge_block;
 };
 
 
 void
 lp_build_if(struct lp_build_if_state *ctx,
-            struct lp_build_flow_context *flow,
-            LLVMBuilderRef builder,
+            struct gallivm_state *gallivm,
             LLVMValueRef condition);
 
 void
@@ -147,7 +194,26 @@ void
 lp_build_endif(struct lp_build_if_state *ctx);
 
 LLVMBasicBlockRef
-lp_build_insert_new_block(LLVMBuilderRef builder, const char *name);
+lp_build_insert_new_block(struct gallivm_state *gallivm, const char *name);
 
+LLVMValueRef
+lp_build_alloca(struct gallivm_state *gallivm,
+                LLVMTypeRef type,
+                const char *name);
+
+LLVMValueRef
+lp_build_alloca_undef(struct gallivm_state *gallivm,
+                      LLVMTypeRef type,
+                      const char *name);
+
+LLVMValueRef
+lp_build_array_alloca(struct gallivm_state *gallivm,
+                      LLVMTypeRef type,
+                      LLVMValueRef count,
+                      const char *name);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* !LP_BLD_FLOW_H */