summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <alyssa.rosenzweig@collabora.com>2020-11-27 19:01:00 -0500
committerMarge Bot <eric+marge@anholt.net>2020-12-31 14:39:01 +0000
commit8ef0d411708a82ec35b723615bf4d47fdcd40c5a (patch)
tree12ced62f5e396ffcb9cfe53afe04d6c56fcf1954
parent1893a3805e4189ebdcd957d71941c855cf12f8b6 (diff)
pan/bi: Generate builder routines
To simplify construction of Bifrost IR. Ideas from NIR's builder, as well as IBC. Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8135>
-rw-r--r--src/panfrost/bifrost/bi_builder.h.py140
-rw-r--r--src/panfrost/bifrost/meson.build16
2 files changed, 155 insertions, 1 deletions
diff --git a/src/panfrost/bifrost/bi_builder.h.py b/src/panfrost/bifrost/bi_builder.h.py
new file mode 100644
index 00000000000..5fbb48f180a
--- /dev/null
+++ b/src/panfrost/bifrost/bi_builder.h.py
@@ -0,0 +1,140 @@
+# Copyright (C) 2020 Collabora, Ltd.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice (including the next
+# paragraph) shall be included in all copies or substantial portions of the
+# Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+SKIP = set(["lane", "lanes", "lanes", "replicate", "swz", "widen", "swap", "neg", "abs", "not", "sign", "extend", "divzero", "clamp", "sem", "not_result", "skip"])
+
+TEMPLATE = """
+#ifndef _BI_BUILDER_H_
+#define _BI_BUILDER_H_
+
+#include "compiler.h"
+
+<%
+def typesize(opcode):
+ if opcode[-3:] == '128':
+ return 128
+ if opcode[-2:] == '48':
+ return 48
+ elif opcode[-1] == '8':
+ return 8
+ else:
+ try:
+ return int(opcode[-2:])
+ except:
+ return None
+%>
+
+% for opcode in ops:
+static inline
+bi_instr * bi_${opcode.replace('.', '_').lower()}_to(${signature(ops[opcode], 1, modifiers)})
+{
+ bi_instr *I = rzalloc(b->shader, bi_instr);
+ I->op = BI_OPCODE_${opcode.replace('.', '_').upper()};
+ I->dest[0] = dest0;
+% for src in range(src_count(ops[opcode])):
+ I->src[${src}] = src${src};
+% endfor
+% for mod in ops[opcode]["modifiers"]:
+% if mod[0:-1] not in SKIP and mod not in SKIP:
+ I->${mod} = ${mod};
+% endif
+% endfor
+% for imm in ops[opcode]["immediates"]:
+ I->${imm} = ${imm};
+% endfor
+ bi_builder_insert(&b->cursor, I);
+ return I;
+}
+
+% if opcode.split(".")[0] not in ["JUMP", "BRANCHZ", "BRANCH"]:
+static inline
+bi_index bi_${opcode.replace('.', '_').lower()}(${signature(ops[opcode], 0, modifiers)})
+{
+ return (bi_${opcode.replace('.', '_').lower()}_to(${arguments(ops[opcode], 1)}))->dest[0];
+}
+
+%endif
+<%
+ common_op = opcode.split('.')[0]
+ variants = [a for a in ops.keys() if a.split('.')[0] == common_op]
+ signatures = [signature(ops[op], 0, modifiers, sized=True) for op in variants]
+ homogenous = all([sig == signatures[0] for sig in signatures])
+ sizes = [typesize(x) for x in variants]
+ last = opcode == variants[-1]
+%>
+% if homogenous and len(variants) > 1 and last:
+% for (suffix, temp, dests, ret) in (('_to', False, 1, 'instr *'), ('', True, 0, 'index')):
+% if not temp or common_op not in ["JUMP", "BRANCHZ", "BRANCH"]:
+static inline
+bi_${ret} bi_${common_op.replace('.', '_').lower()}${suffix}(${signature(ops[opcode], dests, modifiers, sized=True)})
+{
+% for i, (variant, size) in enumerate(zip(variants, sizes)):
+ ${"else " if i > 0 else ""} if (bitsize == ${size})
+ return (bi_${variant.replace('.', '_').lower()}_to(${arguments(ops[opcode], 1, temp_dest = temp)}))${"->dest[0]" if temp else ""};
+% endfor
+ else
+ unreachable("Invalid bitsize for ${common_op}");
+}
+
+%endif
+%endfor
+%endif
+%endfor
+#endif"""
+
+import sys
+from bifrost_isa import *
+from mako.template import Template
+
+instructions = parse_instructions(sys.argv[1], include_pseudo = True)
+ir_instructions = partition_mnemonics(instructions)
+modifier_lists = order_modifiers(ir_instructions)
+
+# Generate type signature for a builder routine
+
+def should_skip(mod):
+ return mod in SKIP or mod[0:-1] in SKIP
+
+def modifier_signature(op):
+ return sorted([m for m in op["modifiers"].keys() if not should_skip(m)])
+
+def signature(op, dest_count, modifiers, sized = False):
+ return ", ".join(
+ ["bi_builder *b"] +
+ (["unsigned bitsize"] if sized else []) +
+ ["bi_index dest{}".format(i) for i in range(dest_count)] +
+ ["bi_index src{}".format(i) for i in range(src_count(op))] +
+ ["{} {}".format(
+ "bool" if len(modifiers[T[0:-1]] if T[-1] in "0123" else modifiers[T]) == 2 else
+ "enum bi_" + T[0:-1] if T[-1] in "0123" else
+ "enum bi_" + T,
+ T) for T in modifier_signature(op)] +
+ ["uint32_t {}".format(imm) for imm in op["immediates"]])
+
+def arguments(op, dest_count, temp_dest = True):
+ return ", ".join(
+ ["b"] +
+ ["bi_temp(b->shader)" if temp_dest else 'dest{}'.format(i) for i in range(dest_count)] +
+ ["src{}".format(i) for i in range(src_count(op))] +
+ modifier_signature(op) +
+ op["immediates"])
+
+print(Template(COPYRIGHT + TEMPLATE).render(ops = ir_instructions, modifiers = modifier_lists, signature = signature, arguments = arguments, src_count = src_count, SKIP = SKIP))
diff --git a/src/panfrost/bifrost/meson.build b/src/panfrost/bifrost/meson.build
index 392c65f4350..c76c5b5c209 100644
--- a/src/panfrost/bifrost/meson.build
+++ b/src/panfrost/bifrost/meson.build
@@ -101,6 +101,20 @@ idep_bi_opcodes_h = declare_dependency(
include_directories : include_directories('.'),
)
+bi_builder_h = custom_target(
+ 'bi_builder.h',
+ input : ['bi_builder.h.py', 'ISA.xml'],
+ output : 'bi_builder.h',
+ command : [prog_python, '@INPUT@'],
+ capture : true,
+ depend_files : files('bifrost_isa.py'),
+)
+
+idep_bi_builder_h = declare_dependency(
+ sources : [bi_builder_h],
+ include_directories : include_directories('.'),
+)
+
libpanfrost_bifrost_disasm = static_library(
'panfrost_bifrost_disasm',
['disassemble.c', 'bi_print_common.c', bifrost_gen_disasm_c],
@@ -116,7 +130,7 @@ libpanfrost_bifrost = static_library(
'panfrost_bifrost',
[libpanfrost_bifrost_files, bifrost_nir_algebraic_c, bi_opcodes_c, bi_printer_c],
include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux, inc_panfrost_hw],
- dependencies: [idep_nir, idep_bi_generated_pack_h, idep_bi_opcodes_h],
+ dependencies: [idep_nir, idep_bi_generated_pack_h, idep_bi_opcodes_h, idep_bi_builder_h],
link_with: [libpanfrost_util, libpanfrost_bifrost_disasm],
c_args : [no_override_init_args],
gnu_symbol_visibility : 'hidden',