1COPYRIGHT = """\ 2/* 3 * Copyright (C) 2017 Intel Corporation 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24""" 25 26import argparse 27import json 28from sys import stdout 29from mako.template import Template 30 31def collect_data(spirv, kind): 32 for x in spirv["operand_kinds"]: 33 if x["kind"] == kind: 34 operands = x 35 break 36 37 values = {} 38 for x in operands["enumerants"]: 39 val = x["value"] 40 assert(val not in values) 41 names = [x["enumerant"]] 42 if "aliases" in x: 43 names.extend(x["aliases"]) 44 values[val] = names 45 46 return (kind, list(values.values()), operands["category"]) 47 48def collect_opcodes(spirv): 49 seen = set() 50 values = [] 51 for x in spirv["instructions"]: 52 opcode = x["opcode"] 53 assert(opcode not in seen) 54 seen.add(opcode) 55 56 name = x["opname"] 57 assert name.startswith("Op") 58 values.append([name[2:]]) 59 60 return ("Op", values, None) 61 62def parse_args(): 63 p = argparse.ArgumentParser() 64 p.add_argument('--out-c', required=True, help='Output C file.') 65 p.add_argument('--out-h', required=True, help='Output H file.') 66 p.add_argument('--json', required=True, help='SPIR-V JSON file.') 67 return p.parse_args() 68 69TEMPLATE_H = Template("""\ 70/* DO NOT EDIT - This file is generated automatically by spirv_info_c.py script */ 71 72""" + COPYRIGHT + """\ 73 74#ifndef _SPIRV_INFO_H_ 75#define _SPIRV_INFO_H_ 76 77#include <stdbool.h> 78 79#include "compiler/spirv/spirv.h" 80 81% for kind,values,category in info: 82% if kind == "Capability": 83struct spirv_capabilities { 84 % for names in values: 85 % if len(names) == 1: 86 bool ${names[0]}; 87 % else: 88 union { 89 % for name in names: 90 bool ${name}; 91 % endfor 92 }; 93 % endif 94 % endfor 95}; 96% endif 97% endfor 98 99bool spirv_capabilities_get(const struct spirv_capabilities *caps, 100 SpvCapability cap); 101void spirv_capabilities_set(struct spirv_capabilities *caps, 102 SpvCapability cap, bool enabled); 103 104% for kind,values,category in info: 105% if category == "BitEnum": 106const char *spirv_${kind.lower()}_to_string(Spv${kind}Mask v); 107% else: 108const char *spirv_${kind.lower()}_to_string(Spv${kind} v); 109% endif 110% endfor 111 112#endif /* SPIRV_INFO_H */ 113""") 114 115TEMPLATE_C = Template("""\ 116/* DO NOT EDIT - This file is generated automatically by spirv_info_c.py script */ 117 118""" + COPYRIGHT + """\ 119#include "spirv_info.h" 120 121#include "util/macros.h" 122 123% for kind,values,category in info: 124% if kind == "Capability": 125bool 126spirv_capabilities_get(const struct spirv_capabilities *caps, 127 SpvCapability cap) 128{ 129 switch (cap) { 130 % for names in values: 131 case SpvCapability${names[0]}: return caps->${names[0]}; 132 % endfor 133 default: 134 return false; 135 } 136} 137 138void 139spirv_capabilities_set(struct spirv_capabilities *caps, 140 SpvCapability cap, bool enabled) 141{ 142 switch (cap) { 143 % for names in values: 144 case SpvCapability${names[0]}: caps->${names[0]} = enabled; break; 145 % endfor 146 default: 147 unreachable("Unknown capability"); 148 } 149} 150% endif 151% endfor 152 153% for kind,values,category in info: 154 155% if category == "BitEnum": 156const char * 157spirv_${kind.lower()}_to_string(Spv${kind}Mask v) 158{ 159 switch (v) { 160 % for names in values: 161 %if names[0] != "None": 162 case Spv${kind}${names[0]}Mask: return "Spv${kind}${names[0]}"; 163 % else: 164 case Spv${kind}MaskNone: return "Spv${kind}${names[0]}"; 165 % endif 166 % endfor 167 } 168 169 return "unknown"; 170} 171% else: 172const char * 173spirv_${kind.lower()}_to_string(Spv${kind} v) 174{ 175 switch (v) { 176 % for names in values: 177 case Spv${kind}${names[0]}: return "Spv${kind}${names[0]}"; 178 % endfor 179 case Spv${kind}Max: break; /* silence warnings about unhandled enums. */ 180 } 181 182 return "unknown"; 183} 184% endif 185% endfor 186""") 187 188if __name__ == "__main__": 189 pargs = parse_args() 190 191 spirv_info = json.JSONDecoder().decode(open(pargs.json, "r").read()) 192 193 info = [ 194 collect_data(spirv_info, "AddressingModel"), 195 collect_data(spirv_info, "BuiltIn"), 196 collect_data(spirv_info, "Capability"), 197 collect_data(spirv_info, "Decoration"), 198 collect_data(spirv_info, "Dim"), 199 collect_data(spirv_info, "ExecutionMode"), 200 collect_data(spirv_info, "ExecutionModel"), 201 collect_data(spirv_info, "FPRoundingMode"), 202 collect_data(spirv_info, "FunctionParameterAttribute"), 203 collect_data(spirv_info, "ImageFormat"), 204 collect_data(spirv_info, "ImageOperands"), 205 collect_data(spirv_info, "MemoryModel"), 206 collect_data(spirv_info, "StorageClass"), 207 collect_opcodes(spirv_info), 208 ] 209 210 with open(pargs.out_h, 'w', encoding='utf-8') as f: 211 f.write(TEMPLATE_H.render(info=info)) 212 with open(pargs.out_c, 'w', encoding='utf-8') as f: 213 f.write(TEMPLATE_C.render(info=info)) 214