1template = """\ 2/* Copyright (C) 2015 Broadcom 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#ifndef _NIR_BUILDER_OPCODES_ 25#define _NIR_BUILDER_OPCODES_ 26 27<% 28def src_decl_list(num_srcs): 29 return ', '.join('nir_def *src' + str(i) for i in range(num_srcs)) 30 31def src_list(num_srcs): 32 return ', '.join('src' + str(i) for i in range(num_srcs)) 33 34def needs_num_components(opcode): 35 return "replicated" in opcode.name 36 37def intrinsic_prefix(name): 38 if name in build_prefixed_intrinsics: 39 return 'nir_build' 40 else: 41 return 'nir' 42%> 43 44% for name, opcode in sorted(opcodes.items()): 45% if not needs_num_components(opcode): 46static inline nir_def * 47nir_${name}(nir_builder *build, ${src_decl_list(opcode.num_inputs)}) 48{ 49% if opcode.is_conversion and \ 50 type_base_type(opcode.output_type) == opcode.input_types[0]: 51 if (src0->bit_size == ${type_size(opcode.output_type)}) 52 return src0; 53%endif 54% if opcode.num_inputs <= 4: 55 return nir_build_alu${opcode.num_inputs}(build, nir_op_${name}, ${src_list(opcode.num_inputs)}); 56% else: 57 nir_def *srcs[${opcode.num_inputs}] = {${src_list(opcode.num_inputs)}}; 58 return nir_build_alu_src_arr(build, nir_op_${name}, srcs); 59% endif 60} 61% endif 62% endfor 63 64% for name, opcode in sorted(INTR_OPCODES.items()): 65% if opcode.indices: 66struct _nir_${name}_indices { 67 int _; /* exists to avoid empty initializers */ 68% for index in opcode.indices: 69 ${index.c_data_type} ${index.name}; 70% endfor 71}; 72% endif 73% endfor 74 75<% 76def intrinsic_decl_list(opcode): 77 need_components = opcode.dest_components == 0 and \ 78 0 not in opcode.src_components 79 80 res = '' 81 if (opcode.has_dest or opcode.num_srcs) and need_components: 82 res += ', unsigned num_components' 83 if opcode.has_dest and len(opcode.bit_sizes) != 1 and opcode.bit_size_src == -1: 84 res += ', unsigned bit_size' 85 for i in range(opcode.num_srcs): 86 res += ', nir_def *src' + str(i) 87 if opcode.indices: 88 res += ', struct _nir_' + opcode.name + '_indices indices' 89 return res 90 91def intrinsic_macro_list(opcode): 92 need_components = opcode.dest_components == 0 and \ 93 0 not in opcode.src_components 94 95 res = '' 96 if (opcode.has_dest or opcode.num_srcs) and need_components: 97 res += ', num_components' 98 if opcode.has_dest and len(opcode.bit_sizes) != 1 and opcode.bit_size_src == -1: 99 res += ', bit_size' 100 for i in range(opcode.num_srcs): 101 res += ', src' + str(i) 102 return res 103 104def get_intrinsic_bitsize(opcode): 105 if len(opcode.bit_sizes) == 1: 106 return str(opcode.bit_sizes[0]) 107 elif opcode.bit_size_src != -1: 108 return 'src' + str(opcode.bit_size_src) + '->bit_size' 109 else: 110 return 'bit_size' 111%> 112 113% for name, opcode in sorted(INTR_OPCODES.items()): 114% if opcode.has_dest: 115static inline nir_def * 116% else: 117static inline nir_intrinsic_instr * 118% endif 119_nir_build_${name}(nir_builder *build${intrinsic_decl_list(opcode)}) 120{ 121 nir_intrinsic_instr *intrin = nir_intrinsic_instr_create( 122 build->shader, nir_intrinsic_${name}); 123 124 % if 0 in opcode.src_components: 125 intrin->num_components = src${opcode.src_components.index(0)}->num_components; 126 % elif opcode.dest_components == 0: 127 intrin->num_components = (uint8_t)num_components; 128 % endif 129 % if opcode.has_dest: 130 % if opcode.dest_components == 0: 131 nir_def_init(&intrin->instr, &intrin->def, intrin->num_components, ${get_intrinsic_bitsize(opcode)}); 132 % else: 133 nir_def_init(&intrin->instr, &intrin->def, ${opcode.dest_components}, ${get_intrinsic_bitsize(opcode)}); 134 % endif 135 % endif 136 % for i in range(opcode.num_srcs): 137 intrin->src[${i}] = nir_src_for_ssa(src${i}); 138 % endfor 139 % if WRITE_MASK in opcode.indices and 0 in opcode.src_components: 140 if (!indices.write_mask) 141 indices.write_mask = BITFIELD_MASK(intrin->num_components); 142 % endif 143 % if ALIGN_MUL in opcode.indices and 0 in opcode.src_components: 144 if (!indices.align_mul) 145 indices.align_mul = src${opcode.src_components.index(0)}->bit_size / 8u; 146 % elif ALIGN_MUL in opcode.indices and opcode.dest_components == 0: 147 if (!indices.align_mul) 148 indices.align_mul = intrin->def.bit_size / 8u; 149 % endif 150 % if IO_SEMANTICS in opcode.indices: 151 if (!indices.io_semantics.num_slots) 152 indices.io_semantics.num_slots = 1; 153 % endif 154 % if IO_SEMANTICS in opcode.indices and DEST_TYPE in opcode.indices and opcode.has_dest: 155 if (!indices.dest_type) 156 indices.dest_type = (nir_alu_type)(nir_type_float | bit_size); 157 % endif 158 % if IO_SEMANTICS in opcode.indices and SRC_TYPE in opcode.indices and opcode.num_srcs > 0: 159 if (!indices.src_type) 160 indices.src_type = (nir_alu_type)(nir_type_float | src0->bit_size); 161 % endif 162 % for index in opcode.indices: 163 nir_intrinsic_set_${index.name}(intrin, indices.${index.name}); 164 % endfor 165 166 nir_builder_instr_insert(build, &intrin->instr); 167 % if opcode.has_dest: 168 return &intrin->def; 169 % else: 170 return intrin; 171 % endif 172} 173% endfor 174 175% for name, opcode in sorted(INTR_OPCODES.items()): 176% if opcode.indices: 177#ifdef __cplusplus 178#define ${intrinsic_prefix(name)}_${name}(build${intrinsic_macro_list(opcode)}, ...) ${'\\\\'} 179_nir_build_${name}(build${intrinsic_macro_list(opcode)}, _nir_${name}_indices{0, __VA_ARGS__}) 180#else 181#define ${intrinsic_prefix(name)}_${name}(build${intrinsic_macro_list(opcode)}, ...) ${'\\\\'} 182_nir_build_${name}(build${intrinsic_macro_list(opcode)}, (struct _nir_${name}_indices){0, __VA_ARGS__}) 183#endif 184% else: 185#define nir_${name} _nir_build_${name} 186% endif 187% if name in build_prefixed_intrinsics: 188#define nir_${name} nir_build_${name} 189% endif 190% endfor 191 192% for name in ['flt', 'fge', 'feq', 'fneu']: 193static inline nir_def * 194nir_${name}_imm(nir_builder *build, nir_def *src1, double src2) 195{ 196 return nir_${name}(build, src1, nir_imm_floatN_t(build, src2, src1->bit_size)); 197} 198% endfor 199 200% for name in ['ilt', 'ige', 'ieq', 'ine', 'ult', 'uge']: 201static inline nir_def * 202nir_${name}_imm(nir_builder *build, nir_def *src1, uint64_t src2) 203{ 204 return nir_${name}(build, src1, nir_imm_intN_t(build, src2, src1->bit_size)); 205} 206% endfor 207 208% for prefix in ['i', 'u']: 209static inline nir_def * 210nir_${prefix}gt_imm(nir_builder *build, nir_def *src1, uint64_t src2) 211{ 212 return nir_${prefix}lt(build, nir_imm_intN_t(build, src2, src1->bit_size), src1); 213} 214 215static inline nir_def * 216nir_${prefix}le_imm(nir_builder *build, nir_def *src1, uint64_t src2) 217{ 218 return nir_${prefix}ge(build, nir_imm_intN_t(build, src2, src1->bit_size), src1); 219} 220% endfor 221 222#endif /* _NIR_BUILDER_OPCODES_ */""" 223 224from nir_opcodes import opcodes, type_size, type_base_type 225from nir_intrinsics import INTR_OPCODES, WRITE_MASK, ALIGN_MUL, IO_SEMANTICS, DEST_TYPE, SRC_TYPE 226from mako.template import Template 227 228# List of intrinsics that also need a nir_build_ prefixed factory macro. 229build_prefixed_intrinsics = [ 230 "load_deref", 231 "store_deref", 232 "copy_deref", 233 "memcpy_deref", 234 235 "load_param", 236 237 "load_global", 238 "load_global_constant", 239 "store_global", 240 241 "load_reg", 242 "store_reg", 243 244 "deref_mode_is", 245] 246 247print(Template(template).render(opcodes=opcodes, 248 type_size=type_size, 249 type_base_type=type_base_type, 250 INTR_OPCODES=INTR_OPCODES, 251 WRITE_MASK=WRITE_MASK, 252 ALIGN_MUL=ALIGN_MUL, 253 IO_SEMANTICS=IO_SEMANTICS, 254 DEST_TYPE=DEST_TYPE, 255 SRC_TYPE=SRC_TYPE, 256 build_prefixed_intrinsics=build_prefixed_intrinsics)) 257