1#encoding=utf-8 2 3# Copyright (C) 2021 Collabora, Ltd. 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 24import sys 25from valhall import valhall_parse_isa 26from mako.template import Template 27from mako import exceptions 28 29(instructions, immediates, enums, typesize, safe_name) = valhall_parse_isa() 30 31SKIP = set([ 32 # Extra conversions 33 "S8_TO_S16", 34 "S8_TO_F16", 35 "U8_TO_U16", 36 "U8_TO_F16", 37 38 # Saturating multiplies 39 "IMUL.s32", 40 "IMUL.v2s16", 41 "IMUL.v4s8", 42 43 # 64-bit support 44 "IADD.u64", 45 "IADD.s64", 46 "ISUB.u64", 47 "ISUB.s64", 48 "IMULD.u64", 49 "SHADDX.u64", 50 "SHADDX.s64", 51 "IMULD.u64", 52 "CLPER.s64", 53 "CLPER.u64", 54 "LSHIFT_AND.i64", 55 "RSHIFT_AND.i64", 56 "LSHIFT_OR.i64", 57 "RSHIFT_OR.i64", 58 "LSHIFT_XOR.i64", 59 "RSHIFT_XOR.i64", 60 "ATOM.i64", 61 "ATOM_RETURN.i64", 62 "ATOM1_RETURN.i64", 63 64 # CLPER widens 65 "CLPER.s32", 66 "CLPER.v2s16", 67 "CLPER.v4s8", 68 "CLPER.v2u16", 69 "CLPER.v4u8", 70 71 # VAR_TEX 72 "VAR_TEX_SINGLE", 73 "VAR_TEX_GATHER", 74 "VAR_TEX_GRADIENT", 75 "VAR_TEX_DUAL", 76 "VAR_TEX_BUF_SINGLE", 77 "VAR_TEX_BUF_GATHER", 78 "VAR_TEX_BUF_GRADIENT", 79 "VAR_TEX_BUF_DUAL", 80 81 # Special cased 82 "FMA_RSCALE_N.f32", 83 "FMA_RSCALE_LEFT.f32", 84 "FMA_RSCALE_SCALE16.f32", 85 86 # Deprecated instruction 87 "NOT_OLD.i32", 88 "NOT_OLD.i64", 89 90 # TODO 91 "IDP.v4s8", 92 "IDP.v4u8", 93 "FATAN_ASSIST.f32", 94 "SEG_ADD.u64", 95 "TEX_DUAL", 96 ]) 97 98template = """ 99#include "valhall.h" 100#include "bi_opcodes.h" 101 102const uint32_t valhall_immediates[32] = { 103% for imm in immediates: 104 ${hex(imm)}, 105% endfor 106}; 107 108<% 109def ibool(x): 110 return '1' if x else '0' 111 112def hasmod(x, mod): 113 return ibool(any([x.name == mod for x in op.modifiers])) 114 115%> 116const struct va_opcode_info 117valhall_opcodes[BI_NUM_OPCODES] = { 118% for op in instructions: 119% if op.name not in skip: 120<% 121 name = op.name 122 if name == 'BRANCHZ': 123 name = 'BRANCHZ.i16' 124 125 sr_control = 0 126 127 if len(op.staging) > 0: 128 sr_control = op.staging[0].encoded_flags >> 6 129%> 130 [BI_OPCODE_${name.replace('.', '_').upper()}] = { 131 .exact = ${hex(exact(op))}ULL, 132 .srcs = { 133% for src in ([sr for sr in op.staging if sr.read] + op.srcs): 134 { 135 .absneg = ${ibool(src.absneg)}, 136 .swizzle = ${ibool(src.swizzle)}, 137 .notted = ${ibool(src.notted)}, 138 .widen = ${ibool(src.widen)}, 139 .lanes = ${ibool(src.lanes)}, 140 .halfswizzle = ${ibool(src.halfswizzle)}, 141 .lane = ${ibool(src.lane)}, 142 .combine = ${ibool(src.combine)}, 143% if src.size in [8, 16, 32, 64]: 144 .size = VA_SIZE_${src.size}, 145% endif 146 }, 147% endfor 148 }, 149 .type_size = ${typesize(op.name)}, 150 .has_dest = ${ibool(len(op.dests) > 0)}, 151 .is_signed = ${ibool(op.is_signed)}, 152 .unit = VA_UNIT_${op.unit}, 153 .nr_srcs = ${len(op.srcs)}, 154 .nr_staging_srcs = ${sum([sr.read for sr in op.staging])}, 155 .nr_staging_dests = ${sum([sr.write for sr in op.staging])}, 156 .clamp = ${hasmod(x, 'clamp')}, 157 .saturate = ${hasmod(x, 'saturate')}, 158 .rhadd = ${hasmod(x, 'rhadd')}, 159 .round_mode = ${hasmod(x, 'round_mode')}, 160 .condition = ${hasmod(x, 'condition')}, 161 .result_type = ${hasmod(x, 'result_type')}, 162 .vecsize = ${hasmod(x, 'vector_size')}, 163 .register_format = ${hasmod(x, 'register_format')}, 164 .slot = ${hasmod(x, 'slot')}, 165 .sr_count = ${hasmod(x, 'staging_register_count')}, 166 .sr_write_count = ${hasmod(x, 'staging_register_write_count')}, 167 .sr_control = ${sr_control}, 168 }, 169% endif 170% endfor 171}; 172""" 173 174# Exact value to be ORed in to every opcode 175def exact_op(op): 176 return (op.opcode << 48) | (op.opcode2 << op.secondary_shift) 177 178try: 179 print(Template(template).render(immediates = immediates, instructions = instructions, skip = SKIP, exact = exact_op, typesize = typesize)) 180except: 181 print(exceptions.text_error_template().render()) 182