1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2009 VMware, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci/**
29bf215546Sopenharmony_ci * LLVM control flow build helpers.
30bf215546Sopenharmony_ci *
31bf215546Sopenharmony_ci * @author Jose Fonseca <jfonseca@vmware.com>
32bf215546Sopenharmony_ci */
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#ifndef LP_BLD_FLOW_H
35bf215546Sopenharmony_ci#define LP_BLD_FLOW_H
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_ci#include "gallivm/lp_bld.h"
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_ci#ifdef __cplusplus
41bf215546Sopenharmony_ciextern "C" {
42bf215546Sopenharmony_ci#endif
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_cistruct lp_type;
45bf215546Sopenharmony_ci
46bf215546Sopenharmony_ci
47bf215546Sopenharmony_ci/**
48bf215546Sopenharmony_ci * Early exit. Useful to skip to the end of a function or block when
49bf215546Sopenharmony_ci * the execution mask becomes zero or when there is an error condition.
50bf215546Sopenharmony_ci */
51bf215546Sopenharmony_cistruct lp_build_skip_context
52bf215546Sopenharmony_ci{
53bf215546Sopenharmony_ci   struct gallivm_state *gallivm;
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   /** Block to skip to */
56bf215546Sopenharmony_ci   LLVMBasicBlockRef block;
57bf215546Sopenharmony_ci};
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_civoid
60bf215546Sopenharmony_cilp_build_flow_skip_begin(struct lp_build_skip_context *ctx,
61bf215546Sopenharmony_ci                         struct gallivm_state *gallivm);
62bf215546Sopenharmony_ci
63bf215546Sopenharmony_civoid
64bf215546Sopenharmony_cilp_build_flow_skip_cond_break(struct lp_build_skip_context *ctx,
65bf215546Sopenharmony_ci                              LLVMValueRef cond);
66bf215546Sopenharmony_ci
67bf215546Sopenharmony_civoid
68bf215546Sopenharmony_cilp_build_flow_skip_end(struct lp_build_skip_context *ctx);
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_ci
71bf215546Sopenharmony_cistruct lp_build_mask_context
72bf215546Sopenharmony_ci{
73bf215546Sopenharmony_ci   struct lp_build_skip_context skip;
74bf215546Sopenharmony_ci
75bf215546Sopenharmony_ci   LLVMTypeRef reg_type;
76bf215546Sopenharmony_ci   LLVMTypeRef var_type;
77bf215546Sopenharmony_ci   /* 'var' is a pointer (alloca) pointing to 'var_type' */
78bf215546Sopenharmony_ci   LLVMValueRef var;
79bf215546Sopenharmony_ci};
80bf215546Sopenharmony_ci
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_civoid
83bf215546Sopenharmony_cilp_build_mask_begin(struct lp_build_mask_context *mask,
84bf215546Sopenharmony_ci                    struct gallivm_state *gallivm,
85bf215546Sopenharmony_ci                    struct lp_type type,
86bf215546Sopenharmony_ci                    LLVMValueRef value);
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ciLLVMValueRef
89bf215546Sopenharmony_cilp_build_mask_value(struct lp_build_mask_context *mask);
90bf215546Sopenharmony_ci
91bf215546Sopenharmony_ci/**
92bf215546Sopenharmony_ci * Bitwise AND the mask with the given value, if a previous mask was set.
93bf215546Sopenharmony_ci */
94bf215546Sopenharmony_civoid
95bf215546Sopenharmony_cilp_build_mask_update(struct lp_build_mask_context *mask,
96bf215546Sopenharmony_ci                     LLVMValueRef value);
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_civoid
99bf215546Sopenharmony_cilp_build_mask_force(struct lp_build_mask_context *mask,
100bf215546Sopenharmony_ci                    LLVMValueRef value);
101bf215546Sopenharmony_ci
102bf215546Sopenharmony_civoid
103bf215546Sopenharmony_cilp_build_mask_check(struct lp_build_mask_context *mask);
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ciLLVMValueRef
106bf215546Sopenharmony_cilp_build_mask_end(struct lp_build_mask_context *mask);
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci
109bf215546Sopenharmony_ci/**
110bf215546Sopenharmony_ci * LLVM's IR doesn't represent for-loops directly. Furthermore it
111bf215546Sopenharmony_ci * requires creating code blocks, branches, phi variables, so it
112bf215546Sopenharmony_ci * requires a fair amount of code.
113bf215546Sopenharmony_ci *
114bf215546Sopenharmony_ci * @sa http://www.llvm.org/docs/tutorial/LangImpl5.html#for
115bf215546Sopenharmony_ci */
116bf215546Sopenharmony_cistruct lp_build_loop_state
117bf215546Sopenharmony_ci{
118bf215546Sopenharmony_ci   LLVMBasicBlockRef block;
119bf215546Sopenharmony_ci   LLVMValueRef counter_var;
120bf215546Sopenharmony_ci   LLVMValueRef counter;
121bf215546Sopenharmony_ci   LLVMTypeRef counter_type;
122bf215546Sopenharmony_ci   struct gallivm_state *gallivm;
123bf215546Sopenharmony_ci};
124bf215546Sopenharmony_ci
125bf215546Sopenharmony_ci
126bf215546Sopenharmony_civoid
127bf215546Sopenharmony_cilp_build_loop_begin(struct lp_build_loop_state *state,
128bf215546Sopenharmony_ci                    struct gallivm_state *gallivm,
129bf215546Sopenharmony_ci                    LLVMValueRef start);
130bf215546Sopenharmony_ci
131bf215546Sopenharmony_civoid
132bf215546Sopenharmony_cilp_build_loop_end(struct lp_build_loop_state *state,
133bf215546Sopenharmony_ci                  LLVMValueRef end,
134bf215546Sopenharmony_ci                  LLVMValueRef step);
135bf215546Sopenharmony_ci
136bf215546Sopenharmony_civoid
137bf215546Sopenharmony_cilp_build_loop_force_set_counter(struct lp_build_loop_state *state,
138bf215546Sopenharmony_ci                                LLVMValueRef end);
139bf215546Sopenharmony_ci
140bf215546Sopenharmony_civoid
141bf215546Sopenharmony_cilp_build_loop_force_reload_counter(struct lp_build_loop_state *state);
142bf215546Sopenharmony_civoid
143bf215546Sopenharmony_cilp_build_loop_end_cond(struct lp_build_loop_state *state,
144bf215546Sopenharmony_ci                       LLVMValueRef end,
145bf215546Sopenharmony_ci                       LLVMValueRef step,
146bf215546Sopenharmony_ci                       LLVMIntPredicate cond);
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci
149bf215546Sopenharmony_ci/**
150bf215546Sopenharmony_ci * Implementation of simple C-style for loops
151bf215546Sopenharmony_ci */
152bf215546Sopenharmony_cistruct lp_build_for_loop_state
153bf215546Sopenharmony_ci{
154bf215546Sopenharmony_ci   LLVMBasicBlockRef begin;
155bf215546Sopenharmony_ci   LLVMBasicBlockRef body;
156bf215546Sopenharmony_ci   LLVMBasicBlockRef exit;
157bf215546Sopenharmony_ci   LLVMValueRef counter_var;
158bf215546Sopenharmony_ci   LLVMValueRef counter;
159bf215546Sopenharmony_ci   LLVMTypeRef counter_type;
160bf215546Sopenharmony_ci   LLVMValueRef step;
161bf215546Sopenharmony_ci   LLVMIntPredicate cond;
162bf215546Sopenharmony_ci   LLVMValueRef end;
163bf215546Sopenharmony_ci   struct gallivm_state *gallivm;
164bf215546Sopenharmony_ci};
165bf215546Sopenharmony_ci
166bf215546Sopenharmony_civoid
167bf215546Sopenharmony_cilp_build_for_loop_begin(struct lp_build_for_loop_state *state,
168bf215546Sopenharmony_ci                        struct gallivm_state *gallivm,
169bf215546Sopenharmony_ci                        LLVMValueRef start,
170bf215546Sopenharmony_ci                        LLVMIntPredicate llvm_cond,
171bf215546Sopenharmony_ci                        LLVMValueRef end,
172bf215546Sopenharmony_ci                        LLVMValueRef step);
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_civoid
175bf215546Sopenharmony_cilp_build_for_loop_end(struct lp_build_for_loop_state *state);
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci
178bf215546Sopenharmony_ci/**
179bf215546Sopenharmony_ci * if/else/endif.
180bf215546Sopenharmony_ci */
181bf215546Sopenharmony_cistruct lp_build_if_state
182bf215546Sopenharmony_ci{
183bf215546Sopenharmony_ci   struct gallivm_state *gallivm;
184bf215546Sopenharmony_ci   LLVMValueRef condition;
185bf215546Sopenharmony_ci   LLVMBasicBlockRef entry_block;
186bf215546Sopenharmony_ci   LLVMBasicBlockRef true_block;
187bf215546Sopenharmony_ci   LLVMBasicBlockRef false_block;
188bf215546Sopenharmony_ci   LLVMBasicBlockRef merge_block;
189bf215546Sopenharmony_ci};
190bf215546Sopenharmony_ci
191bf215546Sopenharmony_ci
192bf215546Sopenharmony_civoid
193bf215546Sopenharmony_cilp_build_if(struct lp_build_if_state *ctx,
194bf215546Sopenharmony_ci            struct gallivm_state *gallivm,
195bf215546Sopenharmony_ci            LLVMValueRef condition);
196bf215546Sopenharmony_ci
197bf215546Sopenharmony_civoid
198bf215546Sopenharmony_cilp_build_else(struct lp_build_if_state *ctx);
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_civoid
201bf215546Sopenharmony_cilp_build_endif(struct lp_build_if_state *ctx);
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ciLLVMBasicBlockRef
204bf215546Sopenharmony_cilp_build_insert_new_block(struct gallivm_state *gallivm, const char *name);
205bf215546Sopenharmony_ci
206bf215546Sopenharmony_ciLLVMValueRef
207bf215546Sopenharmony_cilp_build_alloca(struct gallivm_state *gallivm,
208bf215546Sopenharmony_ci                LLVMTypeRef type,
209bf215546Sopenharmony_ci                const char *name);
210bf215546Sopenharmony_ci
211bf215546Sopenharmony_ciLLVMValueRef
212bf215546Sopenharmony_cilp_build_alloca_undef(struct gallivm_state *gallivm,
213bf215546Sopenharmony_ci                      LLVMTypeRef type,
214bf215546Sopenharmony_ci                      const char *name);
215bf215546Sopenharmony_ci
216bf215546Sopenharmony_ciLLVMValueRef
217bf215546Sopenharmony_cilp_build_array_alloca(struct gallivm_state *gallivm,
218bf215546Sopenharmony_ci                      LLVMTypeRef type,
219bf215546Sopenharmony_ci                      LLVMValueRef count,
220bf215546Sopenharmony_ci                      const char *name);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci#ifdef __cplusplus
223bf215546Sopenharmony_ci}
224bf215546Sopenharmony_ci#endif
225bf215546Sopenharmony_ci
226bf215546Sopenharmony_ci#endif /* !LP_BLD_FLOW_H */
227