1 /************************************************************************** 2 * 3 * Copyright 2011-2012 Advanced Micro Devices, Inc. 4 * Copyright 2009 VMware, Inc. 5 * All Rights Reserved. 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining a 8 * copy of this software and associated documentation files (the 9 * "Software"), to deal in the Software without restriction, including 10 * without limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sub license, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the 16 * next paragraph) shall be included in all copies or substantial portions 17 * of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR 23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 * 27 **************************************************************************/ 28 29 #ifndef LP_BLD_IR_COMMON_H 30 #define LP_BLD_IR_COMMON_H 31 32 #ifdef __cplusplus 33 extern "C" { 34 #endif 35 36 #include "gallivm/lp_bld.h" 37 #include "gallivm/lp_bld_limits.h" 38 39 /* SM 4.0 says that subroutines can nest 32 deep and 40 * we need one more for our main function */ 41 #define LP_MAX_NUM_FUNCS 33 42 43 enum lp_exec_mask_break_type { 44 LP_EXEC_MASK_BREAK_TYPE_LOOP, 45 LP_EXEC_MASK_BREAK_TYPE_SWITCH 46 }; 47 48 struct lp_exec_mask { 49 struct lp_build_context *bld; 50 51 boolean has_mask; 52 boolean ret_in_main; 53 54 LLVMTypeRef int_vec_type; 55 56 LLVMValueRef exec_mask; 57 58 LLVMValueRef ret_mask; 59 LLVMValueRef cond_mask; 60 LLVMValueRef switch_mask; /* current switch exec mask */ 61 LLVMValueRef cont_mask; 62 LLVMValueRef break_mask; 63 64 struct function_ctx { 65 int pc; 66 LLVMValueRef ret_mask; 67 68 LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING]; 69 int cond_stack_size; 70 71 /* keep track if break belongs to switch or loop */ 72 enum lp_exec_mask_break_type break_type_stack[LP_MAX_TGSI_NESTING]; 73 enum lp_exec_mask_break_type break_type; 74 75 struct { 76 LLVMValueRef switch_val; 77 LLVMValueRef switch_mask; 78 LLVMValueRef switch_mask_default; 79 boolean switch_in_default; 80 unsigned switch_pc; 81 } switch_stack[LP_MAX_TGSI_NESTING]; 82 int switch_stack_size; 83 LLVMValueRef switch_val; 84 LLVMValueRef switch_mask_default; /* reverse of switch mask used for default */ 85 boolean switch_in_default; /* if switch exec is currently in default */ 86 unsigned switch_pc; /* when used points to default or endswitch-1 */ 87 88 LLVMValueRef loop_limiter; 89 LLVMBasicBlockRef loop_block; 90 LLVMValueRef break_var; 91 struct { 92 LLVMBasicBlockRef loop_block; 93 LLVMValueRef cont_mask; 94 LLVMValueRef break_mask; 95 LLVMValueRef break_var; 96 } loop_stack[LP_MAX_TGSI_NESTING]; 97 int loop_stack_size; 98 int bgnloop_stack_size; 99 100 } *function_stack; 101 int function_stack_size; 102 }; 103 104 void lp_exec_mask_function_init(struct lp_exec_mask *mask, int function_idx); 105 void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld); 106 void lp_exec_mask_fini(struct lp_exec_mask *mask); 107 void lp_exec_mask_store(struct lp_exec_mask *mask, 108 struct lp_build_context *bld_store, 109 LLVMValueRef val, 110 LLVMValueRef dst_ptr); 111 void lp_exec_mask_update(struct lp_exec_mask *mask); 112 void lp_exec_bgnloop_post_phi(struct lp_exec_mask *mask); 113 void lp_exec_bgnloop(struct lp_exec_mask *mask, bool load_mask); 114 void lp_exec_endloop(struct gallivm_state *gallivm, 115 struct lp_exec_mask *mask); 116 void lp_exec_mask_cond_push(struct lp_exec_mask *mask, 117 LLVMValueRef val); 118 void lp_exec_mask_cond_invert(struct lp_exec_mask *mask); 119 void lp_exec_mask_cond_pop(struct lp_exec_mask *mask); 120 void lp_exec_continue(struct lp_exec_mask *mask); 121 122 void lp_exec_break(struct lp_exec_mask *mask, int *pc, bool break_always); 123 124 #ifdef __cplusplus 125 } 126 #endif 127 128 #endif 129