1#!/usr/bin/env python3 2# 3# Copyright © 2020 Google, Inc. 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 DEALINGS 22# IN THE SOFTWARE. 23 24from mako.template import Template 25from isa import ISA 26import os 27import sys 28 29template = """\ 30/* Copyright (C) 2020 Google, Inc. 31 * 32 * Permission is hereby granted, free of charge, to any person obtaining a 33 * copy of this software and associated documentation files (the "Software"), 34 * to deal in the Software without restriction, including without limitation 35 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 36 * and/or sell copies of the Software, and to permit persons to whom the 37 * Software is furnished to do so, subject to the following conditions: 38 * 39 * The above copyright notice and this permission notice (including the next 40 * paragraph) shall be included in all copies or substantial portions of the 41 * Software. 42 * 43 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 44 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 46 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 47 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 48 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 49 * IN THE SOFTWARE. 50 */ 51 52#include "decode.h" 53 54/* 55 * enum tables, these don't have any link back to other tables so just 56 * dump them up front before the bitset tables 57 */ 58 59%for name, enum in isa.enums.items(): 60static const struct isa_enum ${enum.get_c_name()} = { 61 .num_values = ${len(enum.values)}, 62 .values = { 63% for val, display in enum.values.items(): 64 { .val = ${val}, .display = "${display}" }, 65% endfor 66 }, 67}; 68%endfor 69 70/* 71 * generated expression functions, can be linked from bitset tables, so 72 * also dump them up front 73 */ 74 75%for name, expr in isa.expressions.items(): 76static uint64_t 77${expr.get_c_name()}(struct decode_scope *scope) 78{ 79% for fieldname in sorted(expr.fieldnames): 80 int64_t ${fieldname} = isa_decode_field(scope, "${fieldname}"); 81% endfor 82 return ${expr.expr}; 83} 84%endfor 85 86/* 87 * Forward-declarations (so we don't have to figure out which order to 88 * emit various tables when they have pointers to each other) 89 */ 90 91%for name, bitset in isa.all_bitsets(): 92static const struct isa_bitset bitset_${bitset.get_c_name()}_gen_${bitset.gen_min}; 93%endfor 94 95%for root_name, root in isa.roots.items(): 96const struct isa_bitset *${root.get_c_name()}[]; 97%endfor 98 99/* 100 * bitset tables: 101 */ 102 103%for name, bitset in isa.all_bitsets(): 104% for case in bitset.cases: 105% for field_name, field in case.fields.items(): 106% if field.get_c_typename() == 'TYPE_BITSET': 107% if len(field.params) > 0: 108static const struct isa_field_params ${case.get_c_name()}_gen_${bitset.gen_min}_${field.get_c_name()} = { 109 .num_params = ${len(field.params)}, 110 .params = { 111% for param in field.params: 112 { .name= "${param[0]}", .as = "${param[1]}" }, 113% endfor 114 115 }, 116}; 117% endif 118% endif 119% endfor 120static const struct isa_case ${case.get_c_name()}_gen_${bitset.gen_min} = { 121% if case.expr is not None: 122 .expr = &${isa.expressions[case.expr].get_c_name()}, 123% endif 124% if case.display is not None: 125 .display = "${case.display}", 126% endif 127 .num_fields = ${len(case.fields)}, 128 .fields = { 129% for field_name, field in case.fields.items(): 130 { .name = "${field_name}", .low = ${field.low}, .high = ${field.high}, 131% if field.expr is not None: 132 .expr = &${isa.expressions[field.expr].get_c_name()}, 133% endif 134% if field.display is not None: 135 .display = "${field.display}", 136% endif 137 .type = ${field.get_c_typename()}, 138% if field.get_c_typename() == 'TYPE_BITSET': 139 .bitsets = ${isa.roots[field.type].get_c_name()}, 140% if len(field.params) > 0: 141 .params = &${case.get_c_name()}_gen_${bitset.gen_min}_${field.get_c_name()}, 142% endif 143% endif 144% if field.get_c_typename() == 'TYPE_ENUM': 145 .enums = &${isa.enums[field.type].get_c_name()}, 146% endif 147% if field.get_c_typename() == 'TYPE_ASSERT': 148 .val.bitset = { ${', '.join(isa.split_bits(field.val, 32))} }, 149% endif 150 }, 151% endfor 152 }, 153}; 154% endfor 155static const struct isa_bitset bitset_${bitset.get_c_name()}_gen_${bitset.gen_min} = { 156<% pattern = bitset.get_pattern() %> 157% if bitset.extends is not None: 158 .parent = &bitset_${isa.bitsets[bitset.extends].get_c_name()}_gen_${isa.bitsets[bitset.extends].gen_min}, 159% endif 160 .name = "${name}", 161 .gen = { 162 .min = ${bitset.get_gen_min()}, 163 .max = ${bitset.get_gen_max()}, 164 }, 165 .match.bitset = { ${', '.join(isa.split_bits(pattern.match, 32))} }, 166 .dontcare.bitset = { ${', '.join(isa.split_bits(pattern.dontcare, 32))} }, 167 .mask.bitset = { ${', '.join(isa.split_bits(pattern.mask, 32))} }, 168 .num_cases = ${len(bitset.cases)}, 169 .cases = { 170% for case in bitset.cases: 171 &${case.get_c_name()}_gen_${bitset.gen_min}, 172% endfor 173 }, 174}; 175%endfor 176 177/* 178 * bitset hierarchy root tables (where decoding starts from): 179 */ 180 181%for root_name, root in isa.roots.items(): 182const struct isa_bitset *${root.get_c_name()}[] = { 183% for leaf_name, leafs in isa.leafs.items(): 184% for leaf in leafs: 185% if leaf.get_root() == root: 186 &bitset_${leaf.get_c_name()}_gen_${leaf.gen_min}, 187% endif 188% endfor 189% endfor 190 (void *)0 191}; 192%endfor 193 194""" 195 196header = """\ 197/* Copyright (C) 2020 Google, Inc. 198 * 199 * Permission is hereby granted, free of charge, to any person obtaining a 200 * copy of this software and associated documentation files (the "Software"), 201 * to deal in the Software without restriction, including without limitation 202 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 203 * and/or sell copies of the Software, and to permit persons to whom the 204 * Software is furnished to do so, subject to the following conditions: 205 * 206 * The above copyright notice and this permission notice (including the next 207 * paragraph) shall be included in all copies or substantial portions of the 208 * Software. 209 * 210 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 211 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 212 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 213 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 214 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 215 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 216 * IN THE SOFTWARE. 217 */ 218 219#ifndef _${guard}_ 220#define _${guard}_ 221 222#include <stdint.h> 223#include <util/bitset.h> 224 225#define BITMASK_WORDS BITSET_WORDS(${isa.bitsize}) 226 227typedef struct { 228 BITSET_WORD bitset[BITMASK_WORDS]; 229} bitmask_t; 230 231 232#define BITSET_FORMAT ${isa.format()} 233#define BITSET_VALUE(v) ${isa.value()} 234 235static inline void 236next_instruction(bitmask_t *instr, BITSET_WORD *start) 237{ 238 %for i in range(0, int(isa.bitsize / 32)): 239 instr->bitset[${i}] = *(start + ${i}); 240 %endfor 241} 242 243static inline uint64_t 244bitmask_to_uint64_t(bitmask_t mask) 245{ 246 return ((uint64_t)mask.bitset[1] << 32) | mask.bitset[0]; 247} 248 249static inline bitmask_t 250uint64_t_to_bitmask(uint64_t val) 251{ 252 bitmask_t mask = { 253 .bitset[0] = val & 0xffffffff, 254 .bitset[1] = (val >> 32) & 0xffffffff, 255 }; 256 257 return mask; 258} 259 260#endif /* _${guard}_ */ 261 262""" 263 264glue = """\ 265/* Copyright (C) 2020 Google, Inc. 266 * 267 * Permission is hereby granted, free of charge, to any person obtaining a 268 * copy of this software and associated documentation files (the "Software"), 269 * to deal in the Software without restriction, including without limitation 270 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 271 * and/or sell copies of the Software, and to permit persons to whom the 272 * Software is furnished to do so, subject to the following conditions: 273 * 274 * The above copyright notice and this permission notice (including the next 275 * paragraph) shall be included in all copies or substantial portions of the 276 * Software. 277 * 278 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 279 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 280 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 281 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 282 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 283 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 284 * IN THE SOFTWARE. 285 */ 286 287#ifndef _${guard}_ 288#define _${guard}_ 289 290#include "${isa}" 291 292#endif /* _${guard}_ */ 293 294""" 295 296xml = sys.argv[1] 297glue_h = sys.argv[2] 298dst_c = sys.argv[3] 299dst_h = sys.argv[4] 300 301isa = ISA(xml) 302 303with open(glue_h, 'w') as f: 304 guard = os.path.basename(glue_h).upper().replace("-", "_").replace(".", "_") 305 f.write(Template(glue).render(guard=guard, isa=os.path.basename(dst_h))) 306 307with open(dst_c, 'w') as f: 308 f.write(Template(template).render(isa=isa)) 309 310with open(dst_h, 'w') as f: 311 guard = os.path.basename(dst_h).upper().replace("-", "_").replace(".", "_") 312 f.write(Template(header).render(isa=isa, guard=guard)) 313