#encoding=utf-8 # Copyright (C) 2021 Collabora, Ltd. # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), # to deal in the Software without restriction, including without limitation # the rights to use, copy, modify, merge, publish, distribute, sublicense, # and/or sell copies of the Software, and to permit persons to whom the # Software is furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice (including the next # paragraph) shall be included in all copies or substantial portions of the # Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. import sys from valhall import valhall_parse_isa from mako.template import Template from mako import exceptions (instructions, immediates, enums, typesize, safe_name) = valhall_parse_isa() SKIP = set([ # Extra conversions "S8_TO_S16", "S8_TO_F16", "U8_TO_U16", "U8_TO_F16", # Saturating multiplies "IMUL.s32", "IMUL.v2s16", "IMUL.v4s8", # 64-bit support "IADD.u64", "IADD.s64", "ISUB.u64", "ISUB.s64", "IMULD.u64", "SHADDX.u64", "SHADDX.s64", "IMULD.u64", "CLPER.s64", "CLPER.u64", "LSHIFT_AND.i64", "RSHIFT_AND.i64", "LSHIFT_OR.i64", "RSHIFT_OR.i64", "LSHIFT_XOR.i64", "RSHIFT_XOR.i64", "ATOM.i64", "ATOM_RETURN.i64", "ATOM1_RETURN.i64", # CLPER widens "CLPER.s32", "CLPER.v2s16", "CLPER.v4s8", "CLPER.v2u16", "CLPER.v4u8", # VAR_TEX "VAR_TEX_SINGLE", "VAR_TEX_GATHER", "VAR_TEX_GRADIENT", "VAR_TEX_DUAL", "VAR_TEX_BUF_SINGLE", "VAR_TEX_BUF_GATHER", "VAR_TEX_BUF_GRADIENT", "VAR_TEX_BUF_DUAL", # Special cased "FMA_RSCALE_N.f32", "FMA_RSCALE_LEFT.f32", "FMA_RSCALE_SCALE16.f32", # Deprecated instruction "NOT_OLD.i32", "NOT_OLD.i64", # TODO "IDP.v4s8", "IDP.v4u8", "FATAN_ASSIST.f32", "SEG_ADD.u64", "TEX_DUAL", ]) template = """ #include "valhall.h" #include "bi_opcodes.h" const uint32_t valhall_immediates[32] = { % for imm in immediates: ${hex(imm)}, % endfor }; <% def ibool(x): return '1' if x else '0' def hasmod(x, mod): return ibool(any([x.name == mod for x in op.modifiers])) %> const struct va_opcode_info valhall_opcodes[BI_NUM_OPCODES] = { % for op in instructions: % if op.name not in skip: <% name = op.name if name == 'BRANCHZ': name = 'BRANCHZ.i16' sr_control = 0 if len(op.staging) > 0: sr_control = op.staging[0].encoded_flags >> 6 %> [BI_OPCODE_${name.replace('.', '_').upper()}] = { .exact = ${hex(exact(op))}ULL, .srcs = { % for src in ([sr for sr in op.staging if sr.read] + op.srcs): { .absneg = ${ibool(src.absneg)}, .swizzle = ${ibool(src.swizzle)}, .notted = ${ibool(src.notted)}, .widen = ${ibool(src.widen)}, .lanes = ${ibool(src.lanes)}, .halfswizzle = ${ibool(src.halfswizzle)}, .lane = ${ibool(src.lane)}, .combine = ${ibool(src.combine)}, % if src.size in [8, 16, 32, 64]: .size = VA_SIZE_${src.size}, % endif }, % endfor }, .type_size = ${typesize(op.name)}, .has_dest = ${ibool(len(op.dests) > 0)}, .is_signed = ${ibool(op.is_signed)}, .unit = VA_UNIT_${op.unit}, .nr_srcs = ${len(op.srcs)}, .nr_staging_srcs = ${sum([sr.read for sr in op.staging])}, .nr_staging_dests = ${sum([sr.write for sr in op.staging])}, .clamp = ${hasmod(x, 'clamp')}, .saturate = ${hasmod(x, 'saturate')}, .rhadd = ${hasmod(x, 'rhadd')}, .round_mode = ${hasmod(x, 'round_mode')}, .condition = ${hasmod(x, 'condition')}, .result_type = ${hasmod(x, 'result_type')}, .vecsize = ${hasmod(x, 'vector_size')}, .register_format = ${hasmod(x, 'register_format')}, .slot = ${hasmod(x, 'slot')}, .sr_count = ${hasmod(x, 'staging_register_count')}, .sr_write_count = ${hasmod(x, 'staging_register_write_count')}, .sr_control = ${sr_control}, }, % endif % endfor }; """ # Exact value to be ORed in to every opcode def exact_op(op): return (op.opcode << 48) | (op.opcode2 << op.secondary_shift) try: print(Template(template).render(immediates = immediates, instructions = instructions, skip = SKIP, exact = exact_op, typesize = typesize)) except: print(exceptions.text_error_template().render())