Path: blob/21.2-virgl/src/panfrost/bifrost/bi_builder.h.py
4564 views
# Copyright (C) 2020 Collabora, Ltd.1#2# Permission is hereby granted, free of charge, to any person obtaining a3# copy of this software and associated documentation files (the "Software"),4# to deal in the Software without restriction, including without limitation5# the rights to use, copy, modify, merge, publish, distribute, sublicense,6# and/or sell copies of the Software, and to permit persons to whom the7# Software is furnished to do so, subject to the following conditions:8#9# The above copyright notice and this permission notice (including the next10# paragraph) shall be included in all copies or substantial portions of the11# Software.12#13# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR14# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,15# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL16# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER17# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING18# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS19# IN THE SOFTWARE.2021SKIP = set(["lane", "lane_dest", "lanes", "lanes", "replicate", "swz", "widen", "swap", "neg", "abs", "not", "sign", "extend", "divzero", "clamp", "sem", "not_result", "skip"])2223TEMPLATE = """24#ifndef _BI_BUILDER_H_25#define _BI_BUILDER_H_2627#include "compiler.h"2829<%30# For <32-bit loads/stores, the default extend `none` with a natural sized31# input is not encodeable! To avoid a footgun, swap the default to `zext` which32# will work as expected33ZEXT_DEFAULT = set(["LOAD.i8", "LOAD.i16", "LOAD.i24", "STORE.i8", "STORE.i16", "STORE.i24"])3435def nirtypes(opcode):36split = opcode.split('.', 1)37if len(split) < 2:38split = opcode.split('_')3940if len(split) <= 1:41return None4243assert len(split) > 14445type = split[1]46if type[0] == 'v':47type = type[2:]4849if type[0] == 'f':50return ['nir_type_float']51elif type[0] == 's':52return ['nir_type_int']53elif type[0] == 'u':54return ['nir_type_uint']55elif type[0] == 'i':56return ['nir_type_uint', 'nir_type_int']57else:58return None5960def condition(opcode, typecheck, sizecheck):61cond = ''62if typecheck == True:63cond += '('64types = nirtypes(opcode)65assert types != None66for T in types:67cond += "{}type == {}".format(' || ' if cond[-1] != '(' else '', T)68cond += ')'6970if sizecheck == True:71cond += "{}bitsize == {}".format(' && ' if cond != '' else '', typesize(opcode))7273cmpf_mods = ops[opcode]["modifiers"]["cmpf"] if "cmpf" in ops[opcode]["modifiers"] else None74if "cmpf" in ops[opcode]["modifiers"]:75cond += "{}(".format(' && ' if cond != '' else '')76for cmpf in ops[opcode]["modifiers"]["cmpf"]:77if cmpf != 'reserved':78cond += "{}cmpf == BI_CMPF_{}".format(' || ' if cond[-1] != '(' else '', cmpf.upper())79cond += ')'8081return 'true' if cond == '' else cond8283def to_suffix(op):84return "_to" if op["dests"] > 0 else ""8586%>8788% for opcode in ops:89static inline90bi_instr * bi_${opcode.replace('.', '_').lower()}${to_suffix(ops[opcode])}(${signature(ops[opcode], modifiers)})91{92bi_instr *I = rzalloc(b->shader, bi_instr);93I->op = BI_OPCODE_${opcode.replace('.', '_').upper()};94% for dest in range(ops[opcode]["dests"]):95I->dest[${dest}] = dest${dest};96% endfor97% for src in range(src_count(ops[opcode])):98I->src[${src}] = src${src};99% endfor100% for mod in ops[opcode]["modifiers"]:101% if mod[0:-1] not in SKIP and mod not in SKIP:102I->${mod} = ${mod};103% endif104% endfor105% for imm in ops[opcode]["immediates"]:106I->${imm} = ${imm};107% endfor108% if opcode in ZEXT_DEFAULT:109I->extend = BI_EXTEND_ZEXT;110% endif111bi_builder_insert(&b->cursor, I);112return I;113}114115% if ops[opcode]["dests"] == 1:116static inline117bi_index bi_${opcode.replace('.', '_').lower()}(${signature(ops[opcode], modifiers, no_dests=True)})118{119return (bi_${opcode.replace('.', '_').lower()}_to(${arguments(ops[opcode])}))->dest[0];120}121122%endif123<%124common_op = opcode.split('.')[0]125variants = [a for a in ops.keys() if a.split('.')[0] == common_op]126signatures = [signature(ops[op], modifiers, no_dests=True) for op in variants]127homogenous = all([sig == signatures[0] for sig in signatures])128types = [nirtypes(x) for x in variants]129typeful = False130for t in types:131if t != types[0]:132typeful = True133134sizes = [typesize(x) for x in variants]135sized = False136for size in sizes:137if size != sizes[0]:138sized = True139140last = opcode == variants[-1]141%>142% if homogenous and len(variants) > 1 and last:143% for (suffix, temp, dests, ret) in (('_to', False, 1, 'instr *'), ('', True, 0, 'index')):144% if not temp or ops[opcode]["dests"] > 0:145static inline146bi_${ret} bi_${common_op.replace('.', '_').lower()}${suffix if ops[opcode]['dests'] > 0 else ''}(${signature(ops[opcode], modifiers, typeful=typeful, sized=sized, no_dests=not dests)})147{148% for i, variant in enumerate(variants):149${"{}if ({})".format("else " if i > 0 else "", condition(variant, typeful, sized))}150return (bi_${variant.replace('.', '_').lower()}${to_suffix(ops[opcode])}(${arguments(ops[opcode], temp_dest = temp)}))${"->dest[0]" if temp else ""};151% endfor152else153unreachable("Invalid parameters for ${common_op}");154}155156%endif157%endfor158%endif159%endfor160#endif"""161162import sys163from bifrost_isa import *164from mako.template import Template165166instructions = parse_instructions(sys.argv[1], include_pseudo = True)167ir_instructions = partition_mnemonics(instructions)168modifier_lists = order_modifiers(ir_instructions)169170# Generate type signature for a builder routine171172def should_skip(mod):173return mod in SKIP or mod[0:-1] in SKIP174175def modifier_signature(op):176return sorted([m for m in op["modifiers"].keys() if not should_skip(m)])177178def signature(op, modifiers, typeful = False, sized = False, no_dests = False):179return ", ".join(180["bi_builder *b"] +181(["nir_alu_type type"] if typeful == True else []) +182(["unsigned bitsize"] if sized == True else []) +183["bi_index dest{}".format(i) for i in range(0 if no_dests else op["dests"])] +184["bi_index src{}".format(i) for i in range(src_count(op))] +185["{} {}".format(186"bool" if len(modifiers[T[0:-1]] if T[-1] in "0123" else modifiers[T]) == 2 else187"enum bi_" + T[0:-1] if T[-1] in "0123" else188"enum bi_" + T,189T) for T in modifier_signature(op)] +190["uint32_t {}".format(imm) for imm in op["immediates"]])191192def arguments(op, temp_dest = True):193return ", ".join(194["b"] +195["bi_temp(b->shader)" if temp_dest else 'dest{}'.format(i) for i in range(op["dests"])] +196["src{}".format(i) for i in range(src_count(op))] +197modifier_signature(op) +198op["immediates"])199200print(Template(COPYRIGHT + TEMPLATE).render(ops = ir_instructions, modifiers = modifier_lists, signature = signature, arguments = arguments, src_count = src_count, typesize = typesize, SKIP = SKIP))201202203