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