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 bool has_mask; 52 bool 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 bool 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 bool switch_in_default; /* if switch exec is currently in default */ 86 unsigned switch_pc; /* when used points to default or endswitch-1 */ 87 88 LLVMBasicBlockRef loop_block; 89 LLVMValueRef break_var; 90 struct { 91 LLVMBasicBlockRef loop_block; 92 LLVMValueRef cont_mask; 93 LLVMValueRef break_mask; 94 LLVMValueRef break_var; 95 } loop_stack[LP_MAX_TGSI_NESTING]; 96 int loop_stack_size; 97 int bgnloop_stack_size; 98 99 } *function_stack; 100 int function_stack_size; 101 }; 102 103 struct lp_build_mask_context; 104 105 void lp_exec_mask_function_init(struct lp_exec_mask *mask, int function_idx); 106 void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld); 107 void lp_exec_mask_fini(struct lp_exec_mask *mask); 108 void lp_exec_mask_store(struct lp_exec_mask *mask, 109 struct lp_build_context *bld_store, 110 LLVMValueRef val, 111 LLVMValueRef dst_ptr); 112 void lp_exec_mask_update(struct lp_exec_mask *mask); 113 void lp_exec_bgnloop_post_phi(struct lp_exec_mask *mask); 114 void lp_exec_bgnloop(struct lp_exec_mask *mask, bool load_mask); 115 void lp_exec_endloop(struct gallivm_state *gallivm, 116 struct lp_exec_mask *exec_mask, 117 struct lp_build_mask_context *mask); 118 void lp_exec_mask_cond_push(struct lp_exec_mask *mask, 119 LLVMValueRef val); 120 void lp_exec_mask_cond_invert(struct lp_exec_mask *mask); 121 void lp_exec_mask_cond_pop(struct lp_exec_mask *mask); 122 void lp_exec_continue(struct lp_exec_mask *mask); 123 124 void lp_exec_break(struct lp_exec_mask *mask, int *pc, bool break_always); 125 126 #ifdef __cplusplus 127 } 128 #endif 129 130 #endif 131