About Social Code
aboutsummaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/gallivm/lp_bld_ir_common.h
blob: c46aa8cf5271229d26362ead2bb5fd7f35bfe28e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/**************************************************************************
 *
 * Copyright 2011-2012 Advanced Micro Devices, Inc.
 * Copyright 2009 VMware, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
 * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/

#ifndef LP_BLD_IR_COMMON_H
#define LP_BLD_IR_COMMON_H

#ifdef __cplusplus
extern "C" {
#endif

#include <llvm-c/Core.h>
#include "gallivm/lp_bld_limits.h"

struct gallivm_state;

/* SM 4.0 says that subroutines can nest 32 deep and
 * we need one more for our main function */
#define LP_MAX_NUM_FUNCS 33

enum lp_exec_mask_break_type {
   LP_EXEC_MASK_BREAK_TYPE_LOOP,
   LP_EXEC_MASK_BREAK_TYPE_SWITCH
};

struct lp_exec_mask {
   struct lp_build_context *bld;

   bool has_mask;
   bool ret_in_main;

   LLVMTypeRef int_vec_type;

   LLVMValueRef exec_mask;

   LLVMValueRef ret_mask;
   LLVMValueRef cond_mask;
   LLVMValueRef switch_mask;         /* current switch exec mask */
   LLVMValueRef cont_mask;
   LLVMValueRef break_mask;

   struct function_ctx {
      int pc;
      LLVMValueRef ret_mask;

      LLVMValueRef cond_stack[LP_MAX_TGSI_NESTING];
      int cond_stack_size;

      /* keep track if break belongs to switch or loop */
      enum lp_exec_mask_break_type break_type_stack[LP_MAX_TGSI_NESTING];
      enum lp_exec_mask_break_type break_type;

      struct {
         LLVMValueRef switch_val;
         LLVMValueRef switch_mask;
         LLVMValueRef switch_mask_default;
         bool switch_in_default;
         unsigned switch_pc;
      } switch_stack[LP_MAX_TGSI_NESTING];
      int switch_stack_size;
      LLVMValueRef switch_val;
      LLVMValueRef switch_mask_default; /* reverse of switch mask used for default */
      bool switch_in_default;        /* if switch exec is currently in default */
      unsigned switch_pc;               /* when used points to default or endswitch-1 */

      LLVMBasicBlockRef loop_block;
      LLVMValueRef break_var;
      struct {
         LLVMBasicBlockRef loop_block;
         LLVMValueRef cont_mask;
         LLVMValueRef break_mask;
         LLVMValueRef break_var;
      } loop_stack[LP_MAX_TGSI_NESTING];
      int loop_stack_size;
      int bgnloop_stack_size;

   } *function_stack;
   int function_stack_size;
};

struct lp_build_mask_context;

void lp_exec_mask_function_init(struct lp_exec_mask *mask, int function_idx);
void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context *bld);
void lp_exec_mask_fini(struct lp_exec_mask *mask);
void lp_exec_mask_store(struct lp_exec_mask *mask,
                        struct lp_build_context *bld_store,
                        LLVMValueRef val,
                        LLVMValueRef dst_ptr);
void lp_exec_mask_update(struct lp_exec_mask *mask);
void lp_exec_bgnloop_post_phi(struct lp_exec_mask *mask);
void lp_exec_bgnloop(struct lp_exec_mask *mask, bool load_mask);
void lp_exec_endloop(struct gallivm_state *gallivm,
                     struct lp_exec_mask *exec_mask,
                     struct lp_build_mask_context *mask);
void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
                            LLVMValueRef val);
void lp_exec_mask_cond_invert(struct lp_exec_mask *mask);
void lp_exec_mask_cond_pop(struct lp_exec_mask *mask);
void lp_exec_continue(struct lp_exec_mask *mask);

void lp_exec_break(struct lp_exec_mask *mask, int *pc, bool break_always);

#ifdef __cplusplus
}
#endif

#endif