1*61046927SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*61046927SAndroid Build Coastguard Worker# 3*61046927SAndroid Build Coastguard Worker# Copyright © 2020 Google, Inc. 4*61046927SAndroid Build Coastguard Worker# 5*61046927SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a 6*61046927SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the "Software"), 7*61046927SAndroid Build Coastguard Worker# to deal in the Software without restriction, including without limitation 8*61046927SAndroid Build Coastguard Worker# the rights to use, copy, modify, merge, publish, distribute, sublicense, 9*61046927SAndroid Build Coastguard Worker# and/or sell copies of the Software, and to permit persons to whom the 10*61046927SAndroid Build Coastguard Worker# Software is furnished to do so, subject to the following conditions: 11*61046927SAndroid Build Coastguard Worker# 12*61046927SAndroid Build Coastguard Worker# The above copyright notice and this permission notice (including the next 13*61046927SAndroid Build Coastguard Worker# paragraph) shall be included in all copies or substantial portions of the 14*61046927SAndroid Build Coastguard Worker# Software. 15*61046927SAndroid Build Coastguard Worker# 16*61046927SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*61046927SAndroid Build Coastguard Worker# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*61046927SAndroid Build Coastguard Worker# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*61046927SAndroid Build Coastguard Worker# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20*61046927SAndroid Build Coastguard Worker# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21*61046927SAndroid Build Coastguard Worker# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22*61046927SAndroid Build Coastguard Worker# IN THE SOFTWARE. 23*61046927SAndroid Build Coastguard Worker 24*61046927SAndroid Build Coastguard Workerfrom mako.template import Template 25*61046927SAndroid Build Coastguard Workerfrom isa import ISA 26*61046927SAndroid Build Coastguard Workerimport argparse 27*61046927SAndroid Build Coastguard Workerimport os 28*61046927SAndroid Build Coastguard Workerimport sys 29*61046927SAndroid Build Coastguard Worker 30*61046927SAndroid Build Coastguard Workerclass FieldDecode(object): 31*61046927SAndroid Build Coastguard Worker def __init__(self, name, map_expr): 32*61046927SAndroid Build Coastguard Worker self.name = name 33*61046927SAndroid Build Coastguard Worker self.map_expr = map_expr 34*61046927SAndroid Build Coastguard Worker 35*61046927SAndroid Build Coastguard Worker def get_c_name(self): 36*61046927SAndroid Build Coastguard Worker return self.name.lower().replace('-', '_') 37*61046927SAndroid Build Coastguard Worker 38*61046927SAndroid Build Coastguard Worker# State and helpers used by the template: 39*61046927SAndroid Build Coastguard Workerclass State(object): 40*61046927SAndroid Build Coastguard Worker def __init__(self, isa): 41*61046927SAndroid Build Coastguard Worker self.isa = isa 42*61046927SAndroid Build Coastguard Worker 43*61046927SAndroid Build Coastguard Worker def case_name(self, bitset, name): 44*61046927SAndroid Build Coastguard Worker return bitset.encode.case_prefix + name.upper().replace('.', '_').replace('-', '_').replace('#', '') 45*61046927SAndroid Build Coastguard Worker 46*61046927SAndroid Build Coastguard Worker # Return a list of all <map> entries for a leaf bitset, with the child 47*61046927SAndroid Build Coastguard Worker # bitset overriding the parent bitset's entries. Because we can't resolve 48*61046927SAndroid Build Coastguard Worker # which <map>s are used until we resolve which overload is used, we 49*61046927SAndroid Build Coastguard Worker # generate code for encoding all of these and then at runtime select which 50*61046927SAndroid Build Coastguard Worker # one to call based on the display. 51*61046927SAndroid Build Coastguard Worker def decode_fields(self, bitset): 52*61046927SAndroid Build Coastguard Worker if bitset.get_root().decode is None: 53*61046927SAndroid Build Coastguard Worker return 54*61046927SAndroid Build Coastguard Worker 55*61046927SAndroid Build Coastguard Worker seen_fields = set() 56*61046927SAndroid Build Coastguard Worker if bitset.encode is not None: 57*61046927SAndroid Build Coastguard Worker for name, expr in bitset.encode.maps.items(): 58*61046927SAndroid Build Coastguard Worker seen_fields.add(name) 59*61046927SAndroid Build Coastguard Worker yield FieldDecode(name, expr) 60*61046927SAndroid Build Coastguard Worker 61*61046927SAndroid Build Coastguard Worker if bitset.extends is not None: 62*61046927SAndroid Build Coastguard Worker for field in self.decode_fields(self.isa.bitsets[bitset.extends]): 63*61046927SAndroid Build Coastguard Worker if field.name not in seen_fields: 64*61046927SAndroid Build Coastguard Worker yield field 65*61046927SAndroid Build Coastguard Worker 66*61046927SAndroid Build Coastguard Worker # A limited resolver for field type which doesn't properly account for 67*61046927SAndroid Build Coastguard Worker # overrides. In particular, if a field is defined differently in multiple 68*61046927SAndroid Build Coastguard Worker # different cases, this just blindly picks the last one. 69*61046927SAndroid Build Coastguard Worker # 70*61046927SAndroid Build Coastguard Worker # TODO to do this properly, I don't think there is an alternative than 71*61046927SAndroid Build Coastguard Worker # to emit code which evaluates the case.expr 72*61046927SAndroid Build Coastguard Worker def resolve_simple_field(self, bitset, name): 73*61046927SAndroid Build Coastguard Worker field = None 74*61046927SAndroid Build Coastguard Worker for case in bitset.cases: 75*61046927SAndroid Build Coastguard Worker if name in case.fields: 76*61046927SAndroid Build Coastguard Worker field = case.fields[name] 77*61046927SAndroid Build Coastguard Worker if field is not None: 78*61046927SAndroid Build Coastguard Worker return field 79*61046927SAndroid Build Coastguard Worker if bitset.extends is not None: 80*61046927SAndroid Build Coastguard Worker return self.resolve_simple_field(bitset.isa.bitsets[bitset.extends], name) 81*61046927SAndroid Build Coastguard Worker return None 82*61046927SAndroid Build Coastguard Worker 83*61046927SAndroid Build Coastguard Workertemplate = """\ 84*61046927SAndroid Build Coastguard Worker/* Copyright (C) 2020 Google, Inc. 85*61046927SAndroid Build Coastguard Worker * 86*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a 87*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"), 88*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation 89*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense, 90*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the 91*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions: 92*61046927SAndroid Build Coastguard Worker * 93*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next 94*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the 95*61046927SAndroid Build Coastguard Worker * Software. 96*61046927SAndroid Build Coastguard Worker * 97*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 98*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 99*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 100*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 101*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 102*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 103*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE. 104*61046927SAndroid Build Coastguard Worker */ 105*61046927SAndroid Build Coastguard Worker 106*61046927SAndroid Build Coastguard Worker#include "${header}" 107*61046927SAndroid Build Coastguard Worker 108*61046927SAndroid Build Coastguard Worker#include <stdint.h> 109*61046927SAndroid Build Coastguard Worker#include <util/bitset.h> 110*61046927SAndroid Build Coastguard Worker 111*61046927SAndroid Build Coastguard Worker#define BITMASK_WORDS BITSET_WORDS(${isa.bitsize}) 112*61046927SAndroid Build Coastguard Worker 113*61046927SAndroid Build Coastguard Workertypedef struct { 114*61046927SAndroid Build Coastguard Worker BITSET_WORD bitset[BITMASK_WORDS]; 115*61046927SAndroid Build Coastguard Worker} bitmask_t; 116*61046927SAndroid Build Coastguard Worker 117*61046927SAndroid Build Coastguard Worker 118*61046927SAndroid Build Coastguard Worker#define BITSET_FORMAT ${isa.format()} 119*61046927SAndroid Build Coastguard Worker#define BITSET_VALUE(v) ${isa.value()} 120*61046927SAndroid Build Coastguard Worker 121*61046927SAndroid Build Coastguard Workerstatic inline void 122*61046927SAndroid Build Coastguard Workernext_instruction(bitmask_t *instr, BITSET_WORD *start) 123*61046927SAndroid Build Coastguard Worker{ 124*61046927SAndroid Build Coastguard Worker %for i in range(0, int(isa.bitsize / 32)): 125*61046927SAndroid Build Coastguard Worker instr->bitset[${i}] = *(start + ${i}); 126*61046927SAndroid Build Coastguard Worker %endfor 127*61046927SAndroid Build Coastguard Worker} 128*61046927SAndroid Build Coastguard Worker 129*61046927SAndroid Build Coastguard Workerstatic inline uint64_t 130*61046927SAndroid Build Coastguard Workerbitmask_to_uint64_t(bitmask_t mask) 131*61046927SAndroid Build Coastguard Worker{ 132*61046927SAndroid Build Coastguard Worker% if isa.bitsize <= 32: 133*61046927SAndroid Build Coastguard Worker return mask.bitset[0]; 134*61046927SAndroid Build Coastguard Worker% else: 135*61046927SAndroid Build Coastguard Worker return ((uint64_t)mask.bitset[1] << 32) | mask.bitset[0]; 136*61046927SAndroid Build Coastguard Worker% endif 137*61046927SAndroid Build Coastguard Worker} 138*61046927SAndroid Build Coastguard Worker 139*61046927SAndroid Build Coastguard Workerstatic inline bitmask_t 140*61046927SAndroid Build Coastguard Workeruint64_t_to_bitmask(uint64_t val) 141*61046927SAndroid Build Coastguard Worker{ 142*61046927SAndroid Build Coastguard Worker bitmask_t mask = { 143*61046927SAndroid Build Coastguard Worker .bitset[0] = val & 0xffffffff, 144*61046927SAndroid Build Coastguard Worker% if isa.bitsize > 32: 145*61046927SAndroid Build Coastguard Worker .bitset[1] = (val >> 32) & 0xffffffff, 146*61046927SAndroid Build Coastguard Worker% endif 147*61046927SAndroid Build Coastguard Worker }; 148*61046927SAndroid Build Coastguard Worker 149*61046927SAndroid Build Coastguard Worker return mask; 150*61046927SAndroid Build Coastguard Worker} 151*61046927SAndroid Build Coastguard Worker 152*61046927SAndroid Build Coastguard Worker#include "isaspec_decode_decl.h" 153*61046927SAndroid Build Coastguard Worker 154*61046927SAndroid Build Coastguard Workerstatic uint64_t 155*61046927SAndroid Build Coastguard Workerisa_decode_field(struct decode_scope *scope, const char *field_name); 156*61046927SAndroid Build Coastguard Worker 157*61046927SAndroid Build Coastguard Worker/* 158*61046927SAndroid Build Coastguard Worker * enum tables, these don't have any link back to other tables so just 159*61046927SAndroid Build Coastguard Worker * dump them up front before the bitset tables 160*61046927SAndroid Build Coastguard Worker */ 161*61046927SAndroid Build Coastguard Worker 162*61046927SAndroid Build Coastguard Worker%for name, enum in isa.enums.items(): 163*61046927SAndroid Build Coastguard Workerstatic const struct isa_enum ${enum.get_c_name()} = { 164*61046927SAndroid Build Coastguard Worker .num_values = ${len(enum.values)}, 165*61046927SAndroid Build Coastguard Worker .values = { 166*61046927SAndroid Build Coastguard Worker% for val, display in enum.values.items(): 167*61046927SAndroid Build Coastguard Worker { .val = ${val}, .display = "${display}" }, 168*61046927SAndroid Build Coastguard Worker% endfor 169*61046927SAndroid Build Coastguard Worker }, 170*61046927SAndroid Build Coastguard Worker}; 171*61046927SAndroid Build Coastguard Worker%endfor 172*61046927SAndroid Build Coastguard Worker 173*61046927SAndroid Build Coastguard Worker/* 174*61046927SAndroid Build Coastguard Worker * generated expression functions, can be linked from bitset tables, so 175*61046927SAndroid Build Coastguard Worker * also dump them up front 176*61046927SAndroid Build Coastguard Worker */ 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Worker%for name, expr in isa.expressions.items(): 179*61046927SAndroid Build Coastguard Workerstatic uint64_t 180*61046927SAndroid Build Coastguard Worker${expr.get_c_name()}(struct decode_scope *scope) 181*61046927SAndroid Build Coastguard Worker{ 182*61046927SAndroid Build Coastguard Worker% for fieldname in sorted(expr.fieldnames): 183*61046927SAndroid Build Coastguard Worker int64_t ${fieldname} = isa_decode_field(scope, "${fieldname}"); 184*61046927SAndroid Build Coastguard Worker% endfor 185*61046927SAndroid Build Coastguard Worker return ${expr.expr}; 186*61046927SAndroid Build Coastguard Worker} 187*61046927SAndroid Build Coastguard Worker%endfor 188*61046927SAndroid Build Coastguard Worker 189*61046927SAndroid Build Coastguard Worker/* forward-declarations of bitset decode functions */ 190*61046927SAndroid Build Coastguard Worker%for name, bitset in isa.all_bitsets(): 191*61046927SAndroid Build Coastguard Worker% for df in s.decode_fields(bitset): 192*61046927SAndroid Build Coastguard Workerstatic void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_${df.get_c_name()}(void *out, struct decode_scope *scope, uint64_t val); 193*61046927SAndroid Build Coastguard Worker% endfor 194*61046927SAndroid Build Coastguard Workerstatic const struct isa_field_decode decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_fields[] = { 195*61046927SAndroid Build Coastguard Worker% for df in s.decode_fields(bitset): 196*61046927SAndroid Build Coastguard Worker { 197*61046927SAndroid Build Coastguard Worker .name = "${df.name}", 198*61046927SAndroid Build Coastguard Worker .decode = decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_${df.get_c_name()}, 199*61046927SAndroid Build Coastguard Worker }, 200*61046927SAndroid Build Coastguard Worker% endfor 201*61046927SAndroid Build Coastguard Worker}; 202*61046927SAndroid Build Coastguard Workerstatic void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}(void *out, struct decode_scope *scope); 203*61046927SAndroid Build Coastguard Worker%endfor 204*61046927SAndroid Build Coastguard Worker 205*61046927SAndroid Build Coastguard Worker/* 206*61046927SAndroid Build Coastguard Worker * Forward-declarations (so we don't have to figure out which order to 207*61046927SAndroid Build Coastguard Worker * emit various tables when they have pointers to each other) 208*61046927SAndroid Build Coastguard Worker */ 209*61046927SAndroid Build Coastguard Worker 210*61046927SAndroid Build Coastguard Worker%for name, bitset in isa.all_bitsets(): 211*61046927SAndroid Build Coastguard Workerstatic const struct isa_bitset bitset_${bitset.get_c_name()}_gen_${bitset.gen_min}; 212*61046927SAndroid Build Coastguard Worker%endfor 213*61046927SAndroid Build Coastguard Worker 214*61046927SAndroid Build Coastguard Worker%for root_name, root in isa.roots.items(): 215*61046927SAndroid Build Coastguard Workerstatic const struct isa_bitset *${root.get_c_name()}[]; 216*61046927SAndroid Build Coastguard Worker%endfor 217*61046927SAndroid Build Coastguard Worker 218*61046927SAndroid Build Coastguard Worker/* 219*61046927SAndroid Build Coastguard Worker * bitset tables: 220*61046927SAndroid Build Coastguard Worker */ 221*61046927SAndroid Build Coastguard Worker 222*61046927SAndroid Build Coastguard Worker%for name, bitset in isa.all_bitsets(): 223*61046927SAndroid Build Coastguard Worker% for case in bitset.cases: 224*61046927SAndroid Build Coastguard Worker% for field_name, field in case.fields.items(): 225*61046927SAndroid Build Coastguard Worker% if field.get_c_typename() == 'TYPE_BITSET': 226*61046927SAndroid Build Coastguard Worker% if len(field.params) > 0: 227*61046927SAndroid Build Coastguard Workerstatic const struct isa_field_params ${case.get_c_name()}_gen_${bitset.gen_min}_${field.get_c_name()} = { 228*61046927SAndroid Build Coastguard Worker .num_params = ${len(field.params)}, 229*61046927SAndroid Build Coastguard Worker .params = { 230*61046927SAndroid Build Coastguard Worker% for param in field.params: 231*61046927SAndroid Build Coastguard Worker { .name= "${param[0]}", .as = "${param[1]}" }, 232*61046927SAndroid Build Coastguard Worker% endfor 233*61046927SAndroid Build Coastguard Worker 234*61046927SAndroid Build Coastguard Worker }, 235*61046927SAndroid Build Coastguard Worker}; 236*61046927SAndroid Build Coastguard Worker% endif 237*61046927SAndroid Build Coastguard Worker% endif 238*61046927SAndroid Build Coastguard Worker% endfor 239*61046927SAndroid Build Coastguard Workerstatic const struct isa_case ${case.get_c_name()}_gen_${bitset.gen_min} = { 240*61046927SAndroid Build Coastguard Worker% if case.expr is not None: 241*61046927SAndroid Build Coastguard Worker .expr = &${isa.expressions[case.expr].get_c_name()}, 242*61046927SAndroid Build Coastguard Worker% endif 243*61046927SAndroid Build Coastguard Worker% if case.display is not None: 244*61046927SAndroid Build Coastguard Worker .display = "${case.display}", 245*61046927SAndroid Build Coastguard Worker% endif 246*61046927SAndroid Build Coastguard Worker .num_fields = ${len(case.fields)}, 247*61046927SAndroid Build Coastguard Worker .fields = { 248*61046927SAndroid Build Coastguard Worker% for field_name, field in case.fields.items(): 249*61046927SAndroid Build Coastguard Worker { .name = "${field_name}", .low = ${field.low}, .high = ${field.high}, 250*61046927SAndroid Build Coastguard Worker% if field.expr is not None: 251*61046927SAndroid Build Coastguard Worker .expr = &${isa.expressions[field.expr].get_c_name()}, 252*61046927SAndroid Build Coastguard Worker% endif 253*61046927SAndroid Build Coastguard Worker% if field.display is not None: 254*61046927SAndroid Build Coastguard Worker .display = "${field.display}", 255*61046927SAndroid Build Coastguard Worker% endif 256*61046927SAndroid Build Coastguard Worker .type = ${field.get_c_typename()}, 257*61046927SAndroid Build Coastguard Worker% if field.get_c_typename() == 'TYPE_BITSET': 258*61046927SAndroid Build Coastguard Worker .bitsets = ${isa.roots[field.type].get_c_name()}, 259*61046927SAndroid Build Coastguard Worker% if len(field.params) > 0: 260*61046927SAndroid Build Coastguard Worker .params = &${case.get_c_name()}_gen_${bitset.gen_min}_${field.get_c_name()}, 261*61046927SAndroid Build Coastguard Worker% endif 262*61046927SAndroid Build Coastguard Worker% endif 263*61046927SAndroid Build Coastguard Worker% if field.get_c_typename() == 'TYPE_ENUM': 264*61046927SAndroid Build Coastguard Worker .enums = &${isa.enums[field.type].get_c_name()}, 265*61046927SAndroid Build Coastguard Worker% endif 266*61046927SAndroid Build Coastguard Worker% if field.get_c_typename() == 'TYPE_ASSERT': 267*61046927SAndroid Build Coastguard Worker .val.bitset = { ${', '.join(isa.split_bits(field.val, 32))} }, 268*61046927SAndroid Build Coastguard Worker% endif 269*61046927SAndroid Build Coastguard Worker% if field.get_c_typename() == 'TYPE_BRANCH' or field.get_c_typename() == 'TYPE_ABSBRANCH': 270*61046927SAndroid Build Coastguard Worker .call = ${str(field.call).lower()}, 271*61046927SAndroid Build Coastguard Worker% endif 272*61046927SAndroid Build Coastguard Worker }, 273*61046927SAndroid Build Coastguard Worker% endfor 274*61046927SAndroid Build Coastguard Worker }, 275*61046927SAndroid Build Coastguard Worker}; 276*61046927SAndroid Build Coastguard Worker% endfor 277*61046927SAndroid Build Coastguard Workerstatic const struct isa_bitset bitset_${bitset.get_c_name()}_gen_${bitset.gen_min} = { 278*61046927SAndroid Build Coastguard Worker<% pattern = bitset.get_pattern() %> 279*61046927SAndroid Build Coastguard Worker% if bitset.extends is not None: 280*61046927SAndroid Build Coastguard Worker .parent = &bitset_${isa.bitsets[bitset.extends].get_c_name()}_gen_${isa.bitsets[bitset.extends].gen_min}, 281*61046927SAndroid Build Coastguard Worker% endif 282*61046927SAndroid Build Coastguard Worker .name = "${bitset.display_name}", 283*61046927SAndroid Build Coastguard Worker .gen = { 284*61046927SAndroid Build Coastguard Worker .min = ${bitset.get_gen_min()}, 285*61046927SAndroid Build Coastguard Worker .max = ${bitset.get_gen_max()}, 286*61046927SAndroid Build Coastguard Worker }, 287*61046927SAndroid Build Coastguard Worker .match.bitset = { ${', '.join(isa.split_bits(pattern.match, 32))} }, 288*61046927SAndroid Build Coastguard Worker .dontcare.bitset = { ${', '.join(isa.split_bits(pattern.dontcare, 32))} }, 289*61046927SAndroid Build Coastguard Worker .mask.bitset = { ${', '.join(isa.split_bits(pattern.mask, 32))} }, 290*61046927SAndroid Build Coastguard Worker .decode = decode_${bitset.get_c_name()}_gen_${bitset.gen_min}, 291*61046927SAndroid Build Coastguard Worker .num_decode_fields = ARRAY_SIZE(decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_fields), 292*61046927SAndroid Build Coastguard Worker .decode_fields = decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_fields, 293*61046927SAndroid Build Coastguard Worker .num_cases = ${len(bitset.cases)}, 294*61046927SAndroid Build Coastguard Worker .cases = { 295*61046927SAndroid Build Coastguard Worker% for case in bitset.cases: 296*61046927SAndroid Build Coastguard Worker &${case.get_c_name()}_gen_${bitset.gen_min}, 297*61046927SAndroid Build Coastguard Worker% endfor 298*61046927SAndroid Build Coastguard Worker }, 299*61046927SAndroid Build Coastguard Worker}; 300*61046927SAndroid Build Coastguard Worker%endfor 301*61046927SAndroid Build Coastguard Worker 302*61046927SAndroid Build Coastguard Worker/* 303*61046927SAndroid Build Coastguard Worker * bitset hierarchy root tables (where decoding starts from): 304*61046927SAndroid Build Coastguard Worker */ 305*61046927SAndroid Build Coastguard Worker 306*61046927SAndroid Build Coastguard Worker%for root_name, root in isa.roots.items(): 307*61046927SAndroid Build Coastguard Workerstatic const struct isa_bitset *${root.get_c_name()}[] = { 308*61046927SAndroid Build Coastguard Worker% for leaf_name, leafs in isa.leafs.items(): 309*61046927SAndroid Build Coastguard Worker% for leaf in leafs: 310*61046927SAndroid Build Coastguard Worker% if leaf.get_root() == root: 311*61046927SAndroid Build Coastguard Worker &bitset_${leaf.get_c_name()}_gen_${leaf.gen_min}, 312*61046927SAndroid Build Coastguard Worker% endif 313*61046927SAndroid Build Coastguard Worker% endfor 314*61046927SAndroid Build Coastguard Worker% endfor 315*61046927SAndroid Build Coastguard Worker (void *)0 316*61046927SAndroid Build Coastguard Worker}; 317*61046927SAndroid Build Coastguard Worker%endfor 318*61046927SAndroid Build Coastguard Worker 319*61046927SAndroid Build Coastguard Worker#include "isaspec_decode_impl.c" 320*61046927SAndroid Build Coastguard Worker 321*61046927SAndroid Build Coastguard Worker%for name, bitset in isa.all_bitsets(): 322*61046927SAndroid Build Coastguard Worker% for df in s.decode_fields(bitset): 323*61046927SAndroid Build Coastguard Worker<% field = s.resolve_simple_field(bitset, df.name) %> 324*61046927SAndroid Build Coastguard Workerstatic void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}_${df.get_c_name()}(void *out, struct decode_scope *scope, uint64_t val) 325*61046927SAndroid Build Coastguard Worker{ 326*61046927SAndroid Build Coastguard Worker% if bitset.get_root().decode is not None and field is not None: 327*61046927SAndroid Build Coastguard Worker ${bitset.get_root().encode.type} src = *(${bitset.get_root().encode.type} *)out; 328*61046927SAndroid Build Coastguard Worker% if field.get_c_typename() == 'TYPE_BITSET': 329*61046927SAndroid Build Coastguard Worker isa_decode_bitset(&${df.map_expr}, ${isa.roots[field.type].get_c_name()}, scope, uint64_t_to_bitmask(val)); 330*61046927SAndroid Build Coastguard Worker% elif field.get_c_typename() in ['TYPE_BRANCH', 'TYPE_INT', 'TYPE_OFFSET']: 331*61046927SAndroid Build Coastguard Worker ${df.map_expr} = util_sign_extend(val, ${field.get_size()}); 332*61046927SAndroid Build Coastguard Worker% else: 333*61046927SAndroid Build Coastguard Worker ${df.map_expr} = val; 334*61046927SAndroid Build Coastguard Worker% endif 335*61046927SAndroid Build Coastguard Worker *(${bitset.get_root().encode.type} *)out = src; 336*61046927SAndroid Build Coastguard Worker% endif 337*61046927SAndroid Build Coastguard Worker} 338*61046927SAndroid Build Coastguard Worker 339*61046927SAndroid Build Coastguard Worker% endfor 340*61046927SAndroid Build Coastguard Workerstatic void decode_${bitset.get_c_name()}_gen_${bitset.gen_min}(void *out, struct decode_scope *scope) 341*61046927SAndroid Build Coastguard Worker{ 342*61046927SAndroid Build Coastguard Worker% if bitset.get_root().decode is not None: 343*61046927SAndroid Build Coastguard Worker UNUSED ${bitset.get_root().encode.type} src; 344*61046927SAndroid Build Coastguard Worker% if bitset.get_root().encode.type.endswith('*') and name in isa.leafs and bitset.get_root().encode.case_prefix is not None: 345*61046927SAndroid Build Coastguard Worker src = ${bitset.get_root().get_c_name()}_create(${s.case_name(bitset.get_root(), bitset.name)}); 346*61046927SAndroid Build Coastguard Worker *(${bitset.get_root().encode.type} *)out = src; 347*61046927SAndroid Build Coastguard Worker% endif 348*61046927SAndroid Build Coastguard Worker% endif 349*61046927SAndroid Build Coastguard Worker} 350*61046927SAndroid Build Coastguard Worker%endfor 351*61046927SAndroid Build Coastguard Worker 352*61046927SAndroid Build Coastguard Workervoid ${prefix}_isa_disasm(void *bin, int sz, FILE *out, const struct isa_decode_options *options) 353*61046927SAndroid Build Coastguard Worker{ 354*61046927SAndroid Build Coastguard Worker isa_disasm(bin, sz, out, options); 355*61046927SAndroid Build Coastguard Worker} 356*61046927SAndroid Build Coastguard Worker 357*61046927SAndroid Build Coastguard Workerbool ${prefix}_isa_decode(void *out, void *bin, const struct isa_decode_options *options) 358*61046927SAndroid Build Coastguard Worker{ 359*61046927SAndroid Build Coastguard Worker return isa_decode(out, bin, options); 360*61046927SAndroid Build Coastguard Worker} 361*61046927SAndroid Build Coastguard Worker 362*61046927SAndroid Build Coastguard Workeruint32_t ${prefix}_isa_get_gpu_id(struct decode_scope *scope) 363*61046927SAndroid Build Coastguard Worker{ 364*61046927SAndroid Build Coastguard Worker return isa_get_gpu_id(scope); 365*61046927SAndroid Build Coastguard Worker} 366*61046927SAndroid Build Coastguard Worker""" 367*61046927SAndroid Build Coastguard Worker 368*61046927SAndroid Build Coastguard Workerheader = """\ 369*61046927SAndroid Build Coastguard Worker/* Copyright (C) 2020 Google, Inc. 370*61046927SAndroid Build Coastguard Worker * 371*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a 372*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"), 373*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation 374*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense, 375*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the 376*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions: 377*61046927SAndroid Build Coastguard Worker * 378*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next 379*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the 380*61046927SAndroid Build Coastguard Worker * Software. 381*61046927SAndroid Build Coastguard Worker * 382*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 383*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 384*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 385*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 386*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 387*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 388*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE. 389*61046927SAndroid Build Coastguard Worker */ 390*61046927SAndroid Build Coastguard Worker 391*61046927SAndroid Build Coastguard Worker#ifndef _${guard}_ 392*61046927SAndroid Build Coastguard Worker#define _${guard}_ 393*61046927SAndroid Build Coastguard Worker 394*61046927SAndroid Build Coastguard Worker#include "compiler/isaspec/isaspec.h" 395*61046927SAndroid Build Coastguard Worker 396*61046927SAndroid Build Coastguard Worker#ifdef __cplusplus 397*61046927SAndroid Build Coastguard Workerextern "C" { 398*61046927SAndroid Build Coastguard Worker#endif 399*61046927SAndroid Build Coastguard Worker 400*61046927SAndroid Build Coastguard Workervoid ${prefix}_isa_disasm(void *bin, int sz, FILE *out, const struct isa_decode_options *options); 401*61046927SAndroid Build Coastguard Workerbool ${prefix}_isa_decode(void *out, void *bin, const struct isa_decode_options *options); 402*61046927SAndroid Build Coastguard Worker 403*61046927SAndroid Build Coastguard Workerstruct decode_scope; 404*61046927SAndroid Build Coastguard Worker 405*61046927SAndroid Build Coastguard Workeruint32_t ${prefix}_isa_get_gpu_id(struct decode_scope *scope); 406*61046927SAndroid Build Coastguard Worker 407*61046927SAndroid Build Coastguard Worker/** 408*61046927SAndroid Build Coastguard Worker * Allows to use gpu_id in expr functions 409*61046927SAndroid Build Coastguard Worker */ 410*61046927SAndroid Build Coastguard Worker#define ISA_GPU_ID() ${prefix}_isa_get_gpu_id(scope) 411*61046927SAndroid Build Coastguard Worker 412*61046927SAndroid Build Coastguard Worker#ifdef __cplusplus 413*61046927SAndroid Build Coastguard Worker} 414*61046927SAndroid Build Coastguard Worker#endif 415*61046927SAndroid Build Coastguard Worker 416*61046927SAndroid Build Coastguard Worker#endif /* _${guard}_ */ 417*61046927SAndroid Build Coastguard Worker 418*61046927SAndroid Build Coastguard Worker""" 419*61046927SAndroid Build Coastguard Worker 420*61046927SAndroid Build Coastguard Workerdef guard(p): 421*61046927SAndroid Build Coastguard Worker return os.path.basename(p).upper().replace("-", "_").replace(".", "_") 422*61046927SAndroid Build Coastguard Worker 423*61046927SAndroid Build Coastguard Workerdef prefix(p): 424*61046927SAndroid Build Coastguard Worker return os.path.basename(p).lower().replace("-", "_").replace(".", "_").split('_')[0] 425*61046927SAndroid Build Coastguard Worker 426*61046927SAndroid Build Coastguard Workerdef main(): 427*61046927SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 428*61046927SAndroid Build Coastguard Worker parser.add_argument('--xml', required=True, help='isaspec XML file.') 429*61046927SAndroid Build Coastguard Worker parser.add_argument('--out-c', required=True, help='Output C file.') 430*61046927SAndroid Build Coastguard Worker parser.add_argument('--out-h', required=True, help='Output H file.') 431*61046927SAndroid Build Coastguard Worker args = parser.parse_args() 432*61046927SAndroid Build Coastguard Worker 433*61046927SAndroid Build Coastguard Worker isa = ISA(args.xml) 434*61046927SAndroid Build Coastguard Worker s = State(isa) 435*61046927SAndroid Build Coastguard Worker 436*61046927SAndroid Build Coastguard Worker try: 437*61046927SAndroid Build Coastguard Worker with open(args.out_c, 'w', encoding='utf-8') as f: 438*61046927SAndroid Build Coastguard Worker out_h_basename = os.path.basename(args.out_h) 439*61046927SAndroid Build Coastguard Worker f.write(Template(template).render(isa=isa, s=s, header=out_h_basename, prefix=prefix(args.out_h))) 440*61046927SAndroid Build Coastguard Worker 441*61046927SAndroid Build Coastguard Worker with open(args.out_h, 'w', encoding='utf-8') as f: 442*61046927SAndroid Build Coastguard Worker f.write(Template(header).render(isa=isa, guard=guard(args.out_h), prefix=prefix(args.out_h))) 443*61046927SAndroid Build Coastguard Worker 444*61046927SAndroid Build Coastguard Worker except Exception: 445*61046927SAndroid Build Coastguard Worker # In the event there's an error, this imports some helpers from mako 446*61046927SAndroid Build Coastguard Worker # to print a useful stack trace and prints it, then exits with 447*61046927SAndroid Build Coastguard Worker # status 1, if python is run with debug; otherwise it just raises 448*61046927SAndroid Build Coastguard Worker # the exception 449*61046927SAndroid Build Coastguard Worker import sys 450*61046927SAndroid Build Coastguard Worker from mako import exceptions 451*61046927SAndroid Build Coastguard Worker print(exceptions.text_error_template().render(), file=sys.stderr) 452*61046927SAndroid Build Coastguard Worker sys.exit(1) 453*61046927SAndroid Build Coastguard Worker 454*61046927SAndroid Build Coastguard Workerif __name__ == '__main__': 455*61046927SAndroid Build Coastguard Worker main() 456