mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-23 23:48:18 +02:00
153 lines
4.3 KiB
Python
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())
|