xref: /aosp_15_r20/external/mesa3d/src/microsoft/compiler/dxil_function.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright © Microsoft Corporation
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker  *
11*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker  * Software.
14*61046927SAndroid Build Coastguard Worker  *
15*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker  */
23*61046927SAndroid Build Coastguard Worker 
24*61046927SAndroid Build Coastguard Worker #include "dxil_function.h"
25*61046927SAndroid Build Coastguard Worker #include "dxil_module.h"
26*61046927SAndroid Build Coastguard Worker 
27*61046927SAndroid Build Coastguard Worker #define MAX_FUNC_PARAMS 18
28*61046927SAndroid Build Coastguard Worker 
29*61046927SAndroid Build Coastguard Worker struct predefined_func_descr {
30*61046927SAndroid Build Coastguard Worker    const char *base_name;
31*61046927SAndroid Build Coastguard Worker    const char *retval_descr;
32*61046927SAndroid Build Coastguard Worker    const char *param_descr;
33*61046927SAndroid Build Coastguard Worker    enum dxil_attr_kind attr;
34*61046927SAndroid Build Coastguard Worker };
35*61046927SAndroid Build Coastguard Worker 
36*61046927SAndroid Build Coastguard Worker static struct  predefined_func_descr predefined_funcs[] = {
37*61046927SAndroid Build Coastguard Worker {"dx.op.atomicBinOp", "O", "i@iiiii", DXIL_ATTR_KIND_READ_NONE},
38*61046927SAndroid Build Coastguard Worker {"dx.op.cbufferLoad", "O", "i@ii", DXIL_ATTR_KIND_READ_ONLY},
39*61046927SAndroid Build Coastguard Worker {"dx.op.cbufferLoadLegacy", "B", "i@i", DXIL_ATTR_KIND_READ_ONLY},
40*61046927SAndroid Build Coastguard Worker {"dx.op.createHandle", "@", "iciib", DXIL_ATTR_KIND_READ_ONLY},
41*61046927SAndroid Build Coastguard Worker {"dx.op.storeOutput", "v", "iiicO", DXIL_ATTR_KIND_NO_UNWIND},
42*61046927SAndroid Build Coastguard Worker {"dx.op.loadInput", "O", "iiici", DXIL_ATTR_KIND_READ_NONE},
43*61046927SAndroid Build Coastguard Worker {"dx.op.tertiary", "O", "iOOO", DXIL_ATTR_KIND_READ_NONE},
44*61046927SAndroid Build Coastguard Worker {"dx.op.quaternary", "O", "iOOOO", DXIL_ATTR_KIND_READ_NONE},
45*61046927SAndroid Build Coastguard Worker {"dx.op.threadId", "i", "ii", DXIL_ATTR_KIND_READ_NONE},
46*61046927SAndroid Build Coastguard Worker {"dx.op.threadIdInGroup", "i", "ii", DXIL_ATTR_KIND_READ_NONE},
47*61046927SAndroid Build Coastguard Worker {"dx.op.flattenedThreadIdInGroup", "i", "i", DXIL_ATTR_KIND_READ_NONE},
48*61046927SAndroid Build Coastguard Worker {"dx.op.groupId", "i", "ii", DXIL_ATTR_KIND_READ_NONE},
49*61046927SAndroid Build Coastguard Worker {"dx.op.unary", "O", "iO", DXIL_ATTR_KIND_READ_NONE},
50*61046927SAndroid Build Coastguard Worker {"dx.op.unaryBits", "i", "iO", DXIL_ATTR_KIND_READ_NONE},
51*61046927SAndroid Build Coastguard Worker {"dx.op.isSpecialFloat", "b", "iO", DXIL_ATTR_KIND_READ_NONE},
52*61046927SAndroid Build Coastguard Worker {"dx.op.binary", "O", "iOO", DXIL_ATTR_KIND_READ_NONE},
53*61046927SAndroid Build Coastguard Worker {"dx.op.bufferStore", "v", "i@iiOOOOc", DXIL_ATTR_KIND_NONE},
54*61046927SAndroid Build Coastguard Worker {"dx.op.rawBufferStore", "v", "i@iiOOOOci", DXIL_ATTR_KIND_NONE},
55*61046927SAndroid Build Coastguard Worker {"dx.op.bufferLoad", "R", "i@ii", DXIL_ATTR_KIND_READ_ONLY},
56*61046927SAndroid Build Coastguard Worker {"dx.op.rawBufferLoad", "R", "i@iici", DXIL_ATTR_KIND_READ_ONLY},
57*61046927SAndroid Build Coastguard Worker {"dx.op.attributeAtVertex", "O", "iiicc", DXIL_ATTR_KIND_READ_NONE},
58*61046927SAndroid Build Coastguard Worker {"dx.op.sample", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
59*61046927SAndroid Build Coastguard Worker {"dx.op.sampleBias", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY},
60*61046927SAndroid Build Coastguard Worker {"dx.op.sampleLevel", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
61*61046927SAndroid Build Coastguard Worker {"dx.op.sampleGrad", "R", "i@@ffffiiifffffff", DXIL_ATTR_KIND_READ_ONLY},
62*61046927SAndroid Build Coastguard Worker {"dx.op.sampleCmp", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY},
63*61046927SAndroid Build Coastguard Worker {"dx.op.sampleCmpLevel", "R", "i@@ffffiiiff", DXIL_ATTR_KIND_READ_ONLY},
64*61046927SAndroid Build Coastguard Worker {"dx.op.sampleCmpLevelZero", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
65*61046927SAndroid Build Coastguard Worker {"dx.op.sampleCmpBias", "R", "i@@ffffiiifff", DXIL_ATTR_KIND_READ_ONLY},
66*61046927SAndroid Build Coastguard Worker {"dx.op.sampleCmpGrad", "R", "i@@ffffiiiffffffff", DXIL_ATTR_KIND_READ_ONLY},
67*61046927SAndroid Build Coastguard Worker {"dx.op.textureLoad", "R", "i@iiiiiii", DXIL_ATTR_KIND_READ_ONLY},
68*61046927SAndroid Build Coastguard Worker {"dx.op.textureGather", "R", "i@@ffffiii", DXIL_ATTR_KIND_READ_ONLY},
69*61046927SAndroid Build Coastguard Worker {"dx.op.textureGatherCmp", "R", "i@@ffffiiif", DXIL_ATTR_KIND_READ_ONLY},
70*61046927SAndroid Build Coastguard Worker {"dx.op.discard", "v", "ib", DXIL_ATTR_KIND_NO_UNWIND},
71*61046927SAndroid Build Coastguard Worker {"dx.op.sampleIndex", "i", "i", DXIL_ATTR_KIND_READ_NONE},
72*61046927SAndroid Build Coastguard Worker {"dx.op.emitStream", "v", "ic", DXIL_ATTR_KIND_NONE},
73*61046927SAndroid Build Coastguard Worker {"dx.op.cutStream", "v", "ic", DXIL_ATTR_KIND_NONE},
74*61046927SAndroid Build Coastguard Worker {"dx.op.getDimensions", "D", "i@i", DXIL_ATTR_KIND_READ_ONLY},
75*61046927SAndroid Build Coastguard Worker {"dx.op.calculateLOD", "f", "i@@fffb", DXIL_ATTR_KIND_READ_ONLY},
76*61046927SAndroid Build Coastguard Worker {"dx.op.barrier", "v", "ii", DXIL_ATTR_KIND_NO_DUPLICATE},
77*61046927SAndroid Build Coastguard Worker {"dx.op.atomicCompareExchange", "O", "i@iiiii", DXIL_ATTR_KIND_READ_NONE},
78*61046927SAndroid Build Coastguard Worker {"dx.op.textureStore", "v", "i@iiiOOOOc", DXIL_ATTR_KIND_NONE},
79*61046927SAndroid Build Coastguard Worker {"dx.op.primitiveID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
80*61046927SAndroid Build Coastguard Worker {"dx.op.outputControlPointID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
81*61046927SAndroid Build Coastguard Worker {"dx.op.gsInstanceID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
82*61046927SAndroid Build Coastguard Worker {"dx.op.viewID", "i", "i", DXIL_ATTR_KIND_READ_NONE},
83*61046927SAndroid Build Coastguard Worker {"dx.op.domainLocation", "f", "ic", DXIL_ATTR_KIND_READ_NONE},
84*61046927SAndroid Build Coastguard Worker {"dx.op.legacyF16ToF32", "f", "ii", DXIL_ATTR_KIND_READ_ONLY},
85*61046927SAndroid Build Coastguard Worker {"dx.op.legacyF32ToF16", "i", "if", DXIL_ATTR_KIND_READ_ONLY},
86*61046927SAndroid Build Coastguard Worker {"dx.op.makeDouble", "g", "iii", DXIL_ATTR_KIND_READ_NONE},
87*61046927SAndroid Build Coastguard Worker {"dx.op.splitDouble", "G", "ig", DXIL_ATTR_KIND_READ_NONE},
88*61046927SAndroid Build Coastguard Worker {"dx.op.texture2DMSGetSamplePosition", "S", "i@i", DXIL_ATTR_KIND_READ_ONLY},
89*61046927SAndroid Build Coastguard Worker {"dx.op.renderTargetGetSamplePosition", "S", "ii", DXIL_ATTR_KIND_READ_ONLY},
90*61046927SAndroid Build Coastguard Worker {"dx.op.evalSnapped", "O", "iiicii", DXIL_ATTR_KIND_READ_NONE},
91*61046927SAndroid Build Coastguard Worker {"dx.op.evalCentroid", "O", "iiic", DXIL_ATTR_KIND_READ_NONE},
92*61046927SAndroid Build Coastguard Worker {"dx.op.evalSampleIndex", "O", "iiici", DXIL_ATTR_KIND_READ_NONE},
93*61046927SAndroid Build Coastguard Worker {"dx.op.coverage", "i", "i", DXIL_ATTR_KIND_READ_NONE},
94*61046927SAndroid Build Coastguard Worker {"dx.op.storePatchConstant", "v", "iiicO", DXIL_ATTR_KIND_NO_UNWIND},
95*61046927SAndroid Build Coastguard Worker {"dx.op.loadPatchConstant", "O", "iiic", DXIL_ATTR_KIND_READ_NONE},
96*61046927SAndroid Build Coastguard Worker {"dx.op.loadOutputControlPoint", "O", "iiici", DXIL_ATTR_KIND_READ_NONE},
97*61046927SAndroid Build Coastguard Worker {"dx.op.createHandleFromBinding", "@", "i#ib", DXIL_ATTR_KIND_READ_NONE},
98*61046927SAndroid Build Coastguard Worker {"dx.op.createHandleFromHeap", "@", "iibb", DXIL_ATTR_KIND_READ_NONE},
99*61046927SAndroid Build Coastguard Worker {"dx.op.annotateHandle", "@", "i@P", DXIL_ATTR_KIND_READ_NONE},
100*61046927SAndroid Build Coastguard Worker {"dx.op.isHelperLane", "b", "i", DXIL_ATTR_KIND_READ_ONLY},
101*61046927SAndroid Build Coastguard Worker {"dx.op.waveIsFirstLane", "b", "i", DXIL_ATTR_KIND_NO_UNWIND},
102*61046927SAndroid Build Coastguard Worker {"dx.op.waveGetLaneIndex", "i", "i", DXIL_ATTR_KIND_READ_NONE},
103*61046927SAndroid Build Coastguard Worker {"dx.op.waveGetLaneCount", "i", "i", DXIL_ATTR_KIND_READ_NONE},
104*61046927SAndroid Build Coastguard Worker {"dx.op.waveReadLaneFirst", "O", "iO", DXIL_ATTR_KIND_NO_UNWIND},
105*61046927SAndroid Build Coastguard Worker {"dx.op.waveReadLaneAt", "O", "iOi", DXIL_ATTR_KIND_NO_UNWIND},
106*61046927SAndroid Build Coastguard Worker {"dx.op.waveAnyTrue", "b", "ib", DXIL_ATTR_KIND_NO_UNWIND},
107*61046927SAndroid Build Coastguard Worker {"dx.op.waveAllTrue", "b", "ib", DXIL_ATTR_KIND_NO_UNWIND},
108*61046927SAndroid Build Coastguard Worker {"dx.op.waveActiveAllEqual", "b", "iO", DXIL_ATTR_KIND_NO_UNWIND},
109*61046927SAndroid Build Coastguard Worker {"dx.op.waveActiveBallot", "F", "ib", DXIL_ATTR_KIND_NO_UNWIND},
110*61046927SAndroid Build Coastguard Worker {"dx.op.waveActiveOp", "O", "iOcc", DXIL_ATTR_KIND_NO_UNWIND},
111*61046927SAndroid Build Coastguard Worker {"dx.op.waveActiveBit", "O", "iOc", DXIL_ATTR_KIND_NO_UNWIND},
112*61046927SAndroid Build Coastguard Worker {"dx.op.wavePrefixOp", "O", "iOcc", DXIL_ATTR_KIND_NO_UNWIND},
113*61046927SAndroid Build Coastguard Worker {"dx.op.quadReadLaneAt", "O", "iOi", DXIL_ATTR_KIND_NO_UNWIND},
114*61046927SAndroid Build Coastguard Worker {"dx.op.quadOp", "O", "iOc", DXIL_ATTR_KIND_NO_UNWIND},
115*61046927SAndroid Build Coastguard Worker {"dx.op.dot4AddPacked", "i", "iiii", DXIL_ATTR_KIND_READ_NONE},
116*61046927SAndroid Build Coastguard Worker {"dx.op.startVertexLocation", "i", "i", DXIL_ATTR_KIND_READ_NONE},
117*61046927SAndroid Build Coastguard Worker {"dx.op.startInstanceLocation", "i", "i", DXIL_ATTR_KIND_READ_NONE},
118*61046927SAndroid Build Coastguard Worker };
119*61046927SAndroid Build Coastguard Worker 
120*61046927SAndroid Build Coastguard Worker struct func_descr {
121*61046927SAndroid Build Coastguard Worker    const char *name;
122*61046927SAndroid Build Coastguard Worker    enum overload_type overload;
123*61046927SAndroid Build Coastguard Worker };
124*61046927SAndroid Build Coastguard Worker 
125*61046927SAndroid Build Coastguard Worker struct func_rb_node {
126*61046927SAndroid Build Coastguard Worker    struct rb_node node;
127*61046927SAndroid Build Coastguard Worker    const struct dxil_func *func;
128*61046927SAndroid Build Coastguard Worker    struct func_descr descr;
129*61046927SAndroid Build Coastguard Worker };
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker static inline
132*61046927SAndroid Build Coastguard Worker const struct func_rb_node *
func_rb_node(const struct rb_node * n)133*61046927SAndroid Build Coastguard Worker func_rb_node(const struct rb_node *n)
134*61046927SAndroid Build Coastguard Worker {
135*61046927SAndroid Build Coastguard Worker    return (const struct func_rb_node *)n;
136*61046927SAndroid Build Coastguard Worker }
137*61046927SAndroid Build Coastguard Worker 
138*61046927SAndroid Build Coastguard Worker static int
func_compare_to_name_and_overload(const struct rb_node * node,const void * data)139*61046927SAndroid Build Coastguard Worker func_compare_to_name_and_overload(const struct rb_node *node, const void *data)
140*61046927SAndroid Build Coastguard Worker {
141*61046927SAndroid Build Coastguard Worker    const struct func_descr *descr = (const struct func_descr *)data;
142*61046927SAndroid Build Coastguard Worker    const struct func_rb_node *f = func_rb_node(node);
143*61046927SAndroid Build Coastguard Worker    if (f->descr.overload < descr->overload)
144*61046927SAndroid Build Coastguard Worker       return -1;
145*61046927SAndroid Build Coastguard Worker    if (f->descr.overload > descr->overload)
146*61046927SAndroid Build Coastguard Worker       return 1;
147*61046927SAndroid Build Coastguard Worker 
148*61046927SAndroid Build Coastguard Worker    return strcmp(f->descr.name, descr->name);
149*61046927SAndroid Build Coastguard Worker }
150*61046927SAndroid Build Coastguard Worker 
151*61046927SAndroid Build Coastguard Worker static const struct dxil_func *
allocate_function_from_predefined(struct dxil_module * mod,const char * name,enum overload_type overload)152*61046927SAndroid Build Coastguard Worker allocate_function_from_predefined(struct dxil_module *mod,
153*61046927SAndroid Build Coastguard Worker                                        const char *name,
154*61046927SAndroid Build Coastguard Worker                                        enum overload_type overload)
155*61046927SAndroid Build Coastguard Worker {
156*61046927SAndroid Build Coastguard Worker    for (unsigned i = 0; i < ARRAY_SIZE(predefined_funcs); ++i) {
157*61046927SAndroid Build Coastguard Worker       if (!strcmp(predefined_funcs[i].base_name, name)) {
158*61046927SAndroid Build Coastguard Worker          return dxil_alloc_func(mod, name, overload,
159*61046927SAndroid Build Coastguard Worker                                 predefined_funcs[i].retval_descr,
160*61046927SAndroid Build Coastguard Worker                                 predefined_funcs[i].param_descr,
161*61046927SAndroid Build Coastguard Worker                                 predefined_funcs[i].attr);
162*61046927SAndroid Build Coastguard Worker       }
163*61046927SAndroid Build Coastguard Worker    }
164*61046927SAndroid Build Coastguard Worker    unreachable("Invalid function name");
165*61046927SAndroid Build Coastguard Worker }
166*61046927SAndroid Build Coastguard Worker 
167*61046927SAndroid Build Coastguard Worker const struct dxil_func *
dxil_get_function(struct dxil_module * mod,const char * name,enum overload_type overload)168*61046927SAndroid Build Coastguard Worker dxil_get_function(struct dxil_module *mod,
169*61046927SAndroid Build Coastguard Worker                   const char *name, enum overload_type overload)
170*61046927SAndroid Build Coastguard Worker {
171*61046927SAndroid Build Coastguard Worker    struct func_descr descr = { name, overload };
172*61046927SAndroid Build Coastguard Worker    const struct rb_node *node = rb_tree_search(mod->functions, &descr,
173*61046927SAndroid Build Coastguard Worker                                                func_compare_to_name_and_overload);
174*61046927SAndroid Build Coastguard Worker    if (node)
175*61046927SAndroid Build Coastguard Worker       return func_rb_node(node)->func;
176*61046927SAndroid Build Coastguard Worker 
177*61046927SAndroid Build Coastguard Worker    return allocate_function_from_predefined(mod, name, overload);
178*61046927SAndroid Build Coastguard Worker }
179*61046927SAndroid Build Coastguard Worker 
func_compare_name(const struct rb_node * lhs,const struct rb_node * rhs)180*61046927SAndroid Build Coastguard Worker static int func_compare_name(const struct rb_node *lhs, const struct rb_node *rhs)
181*61046927SAndroid Build Coastguard Worker {
182*61046927SAndroid Build Coastguard Worker    const struct func_rb_node *node = func_rb_node(rhs);
183*61046927SAndroid Build Coastguard Worker    return func_compare_to_name_and_overload(lhs, &node->descr);
184*61046927SAndroid Build Coastguard Worker }
185*61046927SAndroid Build Coastguard Worker 
186*61046927SAndroid Build Coastguard Worker static void
dxil_add_function(struct rb_tree * functions,const struct dxil_func * func,const char * name,enum overload_type overload)187*61046927SAndroid Build Coastguard Worker dxil_add_function(struct rb_tree *functions, const struct dxil_func *func,
188*61046927SAndroid Build Coastguard Worker                   const char *name, enum overload_type overload)
189*61046927SAndroid Build Coastguard Worker {
190*61046927SAndroid Build Coastguard Worker    struct func_rb_node *f = rzalloc(functions, struct func_rb_node);
191*61046927SAndroid Build Coastguard Worker    f->func = func;
192*61046927SAndroid Build Coastguard Worker    f->descr.name = name;
193*61046927SAndroid Build Coastguard Worker    f->descr.overload = overload;
194*61046927SAndroid Build Coastguard Worker    rb_tree_insert(functions, &f->node, func_compare_name);
195*61046927SAndroid Build Coastguard Worker }
196*61046927SAndroid Build Coastguard Worker 
197*61046927SAndroid Build Coastguard Worker static const struct dxil_type *
get_type_from_string(struct dxil_module * mod,const char * param_descr,enum overload_type overload,int * idx)198*61046927SAndroid Build Coastguard Worker get_type_from_string(struct dxil_module *mod, const char *param_descr,
199*61046927SAndroid Build Coastguard Worker                      enum overload_type overload,  int *idx)
200*61046927SAndroid Build Coastguard Worker {
201*61046927SAndroid Build Coastguard Worker    assert(param_descr);
202*61046927SAndroid Build Coastguard Worker    char type_id = param_descr[(*idx)++];
203*61046927SAndroid Build Coastguard Worker    assert(*idx <= (int)strlen(param_descr));
204*61046927SAndroid Build Coastguard Worker 
205*61046927SAndroid Build Coastguard Worker    switch (type_id) {
206*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_INT64: return dxil_module_get_int_type(mod, 64);
207*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_INT32: return dxil_module_get_int_type(mod, 32);
208*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_INT16: return dxil_module_get_int_type(mod, 16);
209*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_INT8: return dxil_module_get_int_type(mod, 8);
210*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_BOOL: return dxil_module_get_int_type(mod, 1);
211*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_FLOAT64: return dxil_module_get_float_type(mod, 64);
212*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_FLOAT32: return dxil_module_get_float_type(mod, 32);
213*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_FLOAT16: return dxil_module_get_float_type(mod, 16);
214*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_HANDLE: return dxil_module_get_handle_type(mod);
215*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_VOID: return dxil_module_get_void_type(mod);
216*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_FROM_OVERLOAD:  return dxil_get_overload_type(mod, overload);
217*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_RESRET: return dxil_module_get_resret_type(mod, overload);
218*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_DIM: return dxil_module_get_dimret_type(mod);
219*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_SAMPLE_POS: return dxil_module_get_samplepos_type(mod);
220*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_CBUF_RET: return dxil_module_get_cbuf_ret_type(mod, overload);
221*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_SPLIT_DOUBLE: return dxil_module_get_split_double_ret_type(mod);
222*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_RES_BIND: return dxil_module_get_res_bind_type(mod);
223*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_RES_PROPS: return dxil_module_get_res_props_type(mod);
224*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_POINTER: {
225*61046927SAndroid Build Coastguard Worker          const struct dxil_type *target = get_type_from_string(mod, param_descr, overload, idx);
226*61046927SAndroid Build Coastguard Worker          return dxil_module_get_pointer_type(mod, target);
227*61046927SAndroid Build Coastguard Worker       }
228*61046927SAndroid Build Coastguard Worker    case DXIL_FUNC_PARAM_FOURI32: return dxil_module_get_fouri32_type(mod);
229*61046927SAndroid Build Coastguard Worker    default:
230*61046927SAndroid Build Coastguard Worker       assert(0 && "unknown type identifier");
231*61046927SAndroid Build Coastguard Worker    }
232*61046927SAndroid Build Coastguard Worker    return NULL;
233*61046927SAndroid Build Coastguard Worker }
234*61046927SAndroid Build Coastguard Worker 
235*61046927SAndroid Build Coastguard Worker const struct dxil_func *
dxil_alloc_func_with_rettype(struct dxil_module * mod,const char * name,enum overload_type overload,const struct dxil_type * retval_type,const char * param_descr,enum dxil_attr_kind attr)236*61046927SAndroid Build Coastguard Worker dxil_alloc_func_with_rettype(struct dxil_module *mod, const char *name,
237*61046927SAndroid Build Coastguard Worker                              enum overload_type overload,
238*61046927SAndroid Build Coastguard Worker                              const struct dxil_type *retval_type,
239*61046927SAndroid Build Coastguard Worker                              const char *param_descr,
240*61046927SAndroid Build Coastguard Worker                              enum dxil_attr_kind attr)
241*61046927SAndroid Build Coastguard Worker {
242*61046927SAndroid Build Coastguard Worker    assert(param_descr);
243*61046927SAndroid Build Coastguard Worker    const struct dxil_type *arg_types[MAX_FUNC_PARAMS];
244*61046927SAndroid Build Coastguard Worker 
245*61046927SAndroid Build Coastguard Worker    int index = 0;
246*61046927SAndroid Build Coastguard Worker    unsigned num_params = 0;
247*61046927SAndroid Build Coastguard Worker 
248*61046927SAndroid Build Coastguard Worker    while (param_descr[num_params]) {
249*61046927SAndroid Build Coastguard Worker       const struct dxil_type *t = get_type_from_string(mod, param_descr, overload, &index);
250*61046927SAndroid Build Coastguard Worker       if (!t)
251*61046927SAndroid Build Coastguard Worker          return false;
252*61046927SAndroid Build Coastguard Worker       assert(num_params < MAX_FUNC_PARAMS);
253*61046927SAndroid Build Coastguard Worker       arg_types[num_params++] = t;
254*61046927SAndroid Build Coastguard Worker    }
255*61046927SAndroid Build Coastguard Worker 
256*61046927SAndroid Build Coastguard Worker    const struct dxil_type *func_type =
257*61046927SAndroid Build Coastguard Worker       dxil_module_add_function_type(mod, retval_type,
258*61046927SAndroid Build Coastguard Worker                                     arg_types, num_params);
259*61046927SAndroid Build Coastguard Worker    if (!func_type) {
260*61046927SAndroid Build Coastguard Worker       fprintf(stderr, "%s: Func type allocation failed\n", __func__);
261*61046927SAndroid Build Coastguard Worker       return false;
262*61046927SAndroid Build Coastguard Worker    }
263*61046927SAndroid Build Coastguard Worker 
264*61046927SAndroid Build Coastguard Worker    char full_name[100];
265*61046927SAndroid Build Coastguard Worker    snprintf(full_name, sizeof (full_name), "%s%s%s", name,
266*61046927SAndroid Build Coastguard Worker             overload == DXIL_NONE ? "" : ".", dxil_overload_suffix(overload));
267*61046927SAndroid Build Coastguard Worker    const struct dxil_func *func = dxil_add_function_decl(mod, full_name, func_type, attr);
268*61046927SAndroid Build Coastguard Worker 
269*61046927SAndroid Build Coastguard Worker    if (func)
270*61046927SAndroid Build Coastguard Worker       dxil_add_function(mod->functions, func, name, overload);
271*61046927SAndroid Build Coastguard Worker 
272*61046927SAndroid Build Coastguard Worker    return func;
273*61046927SAndroid Build Coastguard Worker }
274*61046927SAndroid Build Coastguard Worker 
275*61046927SAndroid Build Coastguard Worker const struct dxil_func *
dxil_alloc_func(struct dxil_module * mod,const char * name,enum overload_type overload,const char * retval_type_descr,const char * param_descr,enum dxil_attr_kind attr)276*61046927SAndroid Build Coastguard Worker dxil_alloc_func(struct dxil_module *mod, const char *name, enum overload_type overload,
277*61046927SAndroid Build Coastguard Worker                 const char *retval_type_descr,
278*61046927SAndroid Build Coastguard Worker                 const char *param_descr, enum dxil_attr_kind attr)
279*61046927SAndroid Build Coastguard Worker {
280*61046927SAndroid Build Coastguard Worker 
281*61046927SAndroid Build Coastguard Worker    int index = 0;
282*61046927SAndroid Build Coastguard Worker    const struct dxil_type *retval_type = get_type_from_string(mod, retval_type_descr, overload, &index);
283*61046927SAndroid Build Coastguard Worker    assert(retval_type_descr[index] == 0);
284*61046927SAndroid Build Coastguard Worker 
285*61046927SAndroid Build Coastguard Worker    return dxil_alloc_func_with_rettype(mod, name, overload, retval_type,
286*61046927SAndroid Build Coastguard Worker                                        param_descr, attr);
287*61046927SAndroid Build Coastguard Worker }
288