mesa/src/intel/compiler/jay/jay_builder_opcodes.h.py

153 lines
4.3 KiB
Python

# Copyright 2026 Intel Corporation
# SPDX-License-Identifier: MIT
from typing import TYPE_CHECKING
import argparse
import sys
from mako import exceptions
from mako.template import Template
from jay_opcodes import OPCODES
if TYPE_CHECKING:
from jay_opcodes import Opcode
def infer_type(op: 'Opcode') -> bool:
return op.has_dest and (set(op.types) <= set(["u1", "u32", "u64"]) or
op.name == 'mov')
def signature(op: 'Opcode', with_dest: bool = True, with_types: bool = False,
mode: str = 'prototype', type_: str = 't', src: str = '{}') -> str:
arr = [('jay_builder *', 'b')]
if with_types and len(op.types) > 1 and not infer_type(op):
arr += [('enum jay_type', type_)]
if with_dest and op.has_dest:
arr += [('jay_def', 'dst')]
arr += [('jay_def', src.format(f'src{i}')) for i in range(op.num_srcs)]
arr += [x for x in op.extra_struct if not x[1].startswith('pad')]
return ', '.join([(t + ' ' if mode == 'prototype' else '') + v for t, v in arr])
TEMPLATE = """
/*
* Copyright 2026 Intel Corporation
* SPDX-License-Identifier: MIT
*/
#pragma once
#include "jay_private.h"
#ifndef NDEBUG
#define type_assert(op, ...) if (!(__VA_ARGS__)) { fprintf(stderr, "%s does not allow type: ", #op); jay_print_type(stderr, t); fprintf(stderr, "\\n"); } assert(__VA_ARGS__)
#else
#define type_assert(...)
#endif
% for op in opcodes.values():
<%
OPCODE = op.name.upper()
num_srcs = op.num_srcs
has_dest = op.has_dest
multi_type = len(op.types) > 1
info_size = f'sizeof(jay_{op.name}_info)' if op.extra_struct else '0'
operands = ["dst"] + [f"src{i}" for i in range(num_srcs)]
if num_srcs > 0 and op.name != 'gpr_from_ugprs':
uniform = " && " .join([f"jay_is_uniform(src{i})" for i in range(num_srcs)])
reg_file = f"({uniform}) ? UGPR : GPR"
else:
reg_file = "GPR"
if not op.types:
continue
# Ignore the lane index when determining the type of a shuffle
infer_operands = operands[0:-1] if op.name == "shuffle" else operands
%>
static inline jay_inst *
_jay_${OPCODE}(${signature(op, with_types = True)})
{
% if infer_type(op):
enum jay_type t = jay_num_values(dst) == 2 ? JAY_TYPE_U64 :
${" && ".join([f"(jay_is_flag({x}) || jay_is_imm({x}))" for x in infer_operands])}
? JAY_TYPE_U1 : JAY_TYPE_U32;
% elif multi_type:
type_assert(${OPCODE}, 0
% for type in op.types:
|| t == JAY_TYPE_${type.upper()}
% endfor
);
% else:
enum jay_type t = JAY_TYPE_${op.types[0].upper()};
% endif
jay_inst *inst = jay_alloc_inst(b, JAY_OPCODE_${OPCODE}, ${num_srcs}, ${info_size});
% for _, prop in op.extra_struct:
% if not prop.startswith('pad'):
jay_set_${op.name}_${prop}(inst, ${prop});
% endif
% endfor
inst->type = t;
% if op.has_dest:
inst->dst = dst;
% endif
% for i in range(num_srcs):
inst->src[${i}] = src${i};
% endfor
jay_builder_insert(b, inst);
return inst;
}
#define jay_${OPCODE}(${signature(op, with_types = True, mode = 'call')}) _jay_${OPCODE}(${signature(op, with_types = True, src = 'JAY_BUILD_SRC({})', mode='call')})
% for type in op.types:
static inline ${'jay_def' if op.has_dest else 'void'}
_jay_${OPCODE}_${type}(${signature(op, with_dest = False)})
{
% if op.has_dest:
jay_def dst = jay_alloc_def(b, ${reg_file}, ${2 if '64' in type else 1});
%endif
jay_${OPCODE}(${signature(op, with_types = True, type_ = 'JAY_TYPE_'+type.upper(), mode = 'call')});
% if op.has_dest:
return dst;
% endif
}
#define jay_${OPCODE}_${type}(${signature(op, with_dest = False, mode =
'call')}) _jay_${OPCODE}_${type}(${signature(op, src='JAY_BUILD_SRC({})', mode = 'call', with_dest = False)})
% endfor
% endfor
#undef type_assert
"""
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument('output', action='store')
args = parser.parse_args()
ops = {op: v for (op, v) in OPCODES.items() if op not in {'cmp', 'send'}}
try:
with open(args.output, 'w', encoding='utf-8') as f:
f.write(Template(TEMPLATE).render(
opcodes=ops,
signature=signature,
infer_type=infer_type))
except Exception:
print(exceptions.text_error_template().render())
return 1
return 0
if __name__ == '__main__':
sys.exit(main())