xref: /aosp_15_r20/external/mesa3d/src/compiler/isaspec/decode.py (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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