• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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