pvr: Add new Rogue compiler framework
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20430>
This commit is contained in:

committed by
Marge Bot

parent
5038a049f1
commit
d187418f63
364
src/imagination/rogue/rogue_builder.c
Normal file
364
src/imagination/rogue/rogue_builder.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/*
|
||||
* Copyright © 2022 Imagination Technologies 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.
|
||||
*/
|
||||
|
||||
#include "rogue.h"
|
||||
#include "rogue_builder.h"
|
||||
#include "util/macros.h"
|
||||
|
||||
/**
|
||||
* \file rogue_builder.c
|
||||
*
|
||||
* \brief Contains helper functions for building Rogue shaders.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Inserts an instruction at the current builder context position.
|
||||
*
|
||||
* \param[in] b The builder context.
|
||||
* \param[in] instr The instruction to insert.
|
||||
*/
|
||||
static inline void rogue_builder_insert_instr(rogue_builder *b,
|
||||
rogue_instr *instr)
|
||||
{
|
||||
rogue_instr_insert(instr, b->cursor);
|
||||
b->cursor = rogue_cursor_after_instr(instr);
|
||||
}
|
||||
|
||||
/* ALU instructions */
|
||||
|
||||
static inline rogue_alu_instr *rogue_build_alu(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst,
|
||||
unsigned num_srcs,
|
||||
rogue_ref srcs[num_srcs])
|
||||
{
|
||||
rogue_alu_instr *alu =
|
||||
rogue_alu_instr_create(rogue_cursor_block(b->cursor), op);
|
||||
|
||||
alu->dst.ref = dst;
|
||||
for (unsigned i = 0; i < num_srcs; ++i) {
|
||||
alu->src[i].ref = srcs[i];
|
||||
alu->src[i].index = i;
|
||||
}
|
||||
|
||||
rogue_builder_insert_instr(b, &alu->instr);
|
||||
return alu;
|
||||
}
|
||||
|
||||
static inline rogue_alu_instr *rogue_build_alu1(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst,
|
||||
rogue_ref src0)
|
||||
{
|
||||
rogue_ref srcs[] = { src0 };
|
||||
return rogue_build_alu(b, op, dst, 1, srcs);
|
||||
}
|
||||
|
||||
static inline rogue_alu_instr *rogue_build_alu2(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst,
|
||||
rogue_ref src0,
|
||||
rogue_ref src1)
|
||||
{
|
||||
rogue_ref srcs[] = { src0, src1 };
|
||||
return rogue_build_alu(b, op, dst, 2, srcs);
|
||||
}
|
||||
|
||||
static inline rogue_alu_instr *rogue_build_alu3(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst,
|
||||
rogue_ref src0,
|
||||
rogue_ref src1,
|
||||
rogue_ref src2)
|
||||
{
|
||||
rogue_ref srcs[] = { src0, src1, src2 };
|
||||
return rogue_build_alu(b, op, dst, 3, srcs);
|
||||
}
|
||||
|
||||
/* TODO: Static inline in rogue.h? */
|
||||
#define ROGUE_BUILDER_DEFINE_ALU1(op) \
|
||||
PUBLIC \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst, \
|
||||
rogue_ref src0) \
|
||||
{ \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_srcs == 1); \
|
||||
return rogue_build_alu1(b, ROGUE_ALU_OP_##op, dst, src0); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU2(op) \
|
||||
PUBLIC \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1) \
|
||||
{ \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_srcs == 2); \
|
||||
return rogue_build_alu2(b, ROGUE_ALU_OP_##op, dst, src0, src1); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU3(op) \
|
||||
PUBLIC \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1, \
|
||||
rogue_ref src2) \
|
||||
{ \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_srcs == 3); \
|
||||
return rogue_build_alu3(b, ROGUE_ALU_OP_##op, dst, src0, src1, src2); \
|
||||
}
|
||||
|
||||
#include "rogue_alu_instrs.def"
|
||||
|
||||
static inline rogue_backend_instr *rogue_build_backend(rogue_builder *b,
|
||||
enum rogue_backend_op op,
|
||||
unsigned num_dsts,
|
||||
rogue_ref dsts[num_dsts],
|
||||
unsigned num_srcs,
|
||||
rogue_ref srcs[num_srcs])
|
||||
{
|
||||
rogue_backend_instr *backend =
|
||||
rogue_backend_instr_create(rogue_cursor_block(b->cursor), op);
|
||||
|
||||
for (unsigned i = 0; i < num_dsts; ++i) {
|
||||
backend->dst[i].ref = dsts[i];
|
||||
backend->dst[i].index = i;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_srcs; ++i) {
|
||||
backend->src[i].ref = srcs[i];
|
||||
backend->src[i].index = i;
|
||||
}
|
||||
|
||||
rogue_builder_insert_instr(b, &backend->instr);
|
||||
return backend;
|
||||
}
|
||||
|
||||
static inline rogue_backend_instr *
|
||||
rogue_build_backend00(rogue_builder *b, enum rogue_backend_op op)
|
||||
{
|
||||
return rogue_build_backend(b, op, 0, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static inline rogue_backend_instr *
|
||||
rogue_build_backend11(rogue_builder *b,
|
||||
enum rogue_backend_op op,
|
||||
rogue_ref dst0,
|
||||
rogue_ref src0)
|
||||
{
|
||||
rogue_ref dsts[] = { dst0 };
|
||||
rogue_ref srcs[] = { src0 };
|
||||
return rogue_build_backend(b, op, 1, dsts, 1, srcs);
|
||||
}
|
||||
|
||||
static inline rogue_backend_instr *
|
||||
rogue_build_backend14(rogue_builder *b,
|
||||
enum rogue_backend_op op,
|
||||
rogue_ref dst0,
|
||||
rogue_ref src0,
|
||||
rogue_ref src1,
|
||||
rogue_ref src2,
|
||||
rogue_ref src3)
|
||||
{
|
||||
rogue_ref dsts[] = { dst0 };
|
||||
rogue_ref srcs[] = { src0, src1, src2, src3 };
|
||||
return rogue_build_backend(b, op, 1, dsts, 4, srcs);
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_BACKEND00(op) \
|
||||
PUBLIC \
|
||||
rogue_backend_instr *rogue_##op(rogue_builder *b) \
|
||||
{ \
|
||||
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_dsts == 0); \
|
||||
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_srcs == 0); \
|
||||
return rogue_build_backend00(b, ROGUE_BACKEND_OP_##op); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_BACKEND11(op) \
|
||||
PUBLIC \
|
||||
rogue_backend_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref src0) \
|
||||
{ \
|
||||
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_dsts == 1); \
|
||||
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_srcs == 1); \
|
||||
return rogue_build_backend11(b, ROGUE_BACKEND_OP_##op, dst0, src0); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_BACKEND14(op) \
|
||||
PUBLIC \
|
||||
rogue_backend_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1, \
|
||||
rogue_ref src2, \
|
||||
rogue_ref src3) \
|
||||
{ \
|
||||
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_dsts == 1); \
|
||||
assert(rogue_backend_op_infos[ROGUE_BACKEND_OP_##op].num_srcs == 4); \
|
||||
return rogue_build_backend14(b, \
|
||||
ROGUE_BACKEND_OP_##op, \
|
||||
dst0, \
|
||||
src0, \
|
||||
src1, \
|
||||
src2, \
|
||||
src3); \
|
||||
}
|
||||
|
||||
#include "rogue_backend_instrs.def"
|
||||
|
||||
static inline rogue_ctrl_instr *rogue_build_ctrl(rogue_builder *b,
|
||||
enum rogue_ctrl_op op,
|
||||
rogue_block *target_block,
|
||||
unsigned num_dsts,
|
||||
rogue_ref dsts[num_dsts],
|
||||
unsigned num_srcs,
|
||||
rogue_ref srcs[num_srcs])
|
||||
{
|
||||
rogue_ctrl_instr *ctrl =
|
||||
rogue_ctrl_instr_create(rogue_cursor_block(b->cursor), op);
|
||||
|
||||
ctrl->target_block = target_block;
|
||||
|
||||
for (unsigned i = 0; i < num_dsts; ++i) {
|
||||
ctrl->dst[i].ref = dsts[i];
|
||||
ctrl->dst[i].index = i;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_srcs; ++i) {
|
||||
ctrl->src[i].ref = srcs[i];
|
||||
ctrl->src[i].index = i;
|
||||
}
|
||||
|
||||
rogue_builder_insert_instr(b, &ctrl->instr);
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
static inline rogue_ctrl_instr *
|
||||
rogue_build_ctrlb(rogue_builder *b, enum rogue_ctrl_op op, rogue_block *block)
|
||||
{
|
||||
return rogue_build_ctrl(b, op, block, 0, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static inline rogue_ctrl_instr *rogue_build_ctrl00(rogue_builder *b,
|
||||
enum rogue_ctrl_op op)
|
||||
{
|
||||
return rogue_build_ctrl(b, op, NULL, 0, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static inline rogue_ctrl_instr *
|
||||
rogue_build_ctrl01(rogue_builder *b, enum rogue_ctrl_op op, rogue_ref src0)
|
||||
{
|
||||
rogue_ref srcs[] = { src0 };
|
||||
return rogue_build_ctrl(b, op, NULL, 0, NULL, 1, srcs);
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_CTRLB(op) \
|
||||
PUBLIC \
|
||||
rogue_ctrl_instr *rogue_##op(rogue_builder *b, rogue_block *block) \
|
||||
{ \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].has_target); \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].num_dsts == 0); \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].num_srcs == 0); \
|
||||
return rogue_build_ctrlb(b, ROGUE_CTRL_OP_##op, block); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_CTRL00(op) \
|
||||
PUBLIC \
|
||||
rogue_ctrl_instr *rogue_##op(rogue_builder *b) \
|
||||
{ \
|
||||
assert(!rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].has_target); \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].num_dsts == 0); \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].num_srcs == 0); \
|
||||
return rogue_build_ctrl00(b, ROGUE_CTRL_OP_##op); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_CTRL01(op) \
|
||||
PUBLIC \
|
||||
rogue_ctrl_instr *rogue_##op(rogue_builder *b, rogue_ref src0) \
|
||||
{ \
|
||||
assert(!rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].has_target); \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].num_dsts == 0); \
|
||||
assert(rogue_ctrl_op_infos[ROGUE_CTRL_OP_##op].num_srcs == 1); \
|
||||
return rogue_build_ctrl01(b, ROGUE_CTRL_OP_##op, src0); \
|
||||
}
|
||||
|
||||
#include "rogue_ctrl_instrs.def"
|
||||
|
||||
static inline rogue_bitwise_instr *rogue_build_bitwise(rogue_builder *b,
|
||||
enum rogue_bitwise_op op,
|
||||
unsigned num_dsts,
|
||||
rogue_ref dsts[num_dsts],
|
||||
unsigned num_srcs,
|
||||
rogue_ref srcs[num_srcs])
|
||||
{
|
||||
rogue_bitwise_instr *bitwise =
|
||||
rogue_bitwise_instr_create(rogue_cursor_block(b->cursor), op);
|
||||
|
||||
for (unsigned i = 0; i < num_dsts; ++i) {
|
||||
bitwise->dst[i].ref = dsts[i];
|
||||
bitwise->dst[i].index = i;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_srcs; ++i) {
|
||||
bitwise->src[i].ref = srcs[i];
|
||||
bitwise->src[i].index = i;
|
||||
}
|
||||
|
||||
rogue_builder_insert_instr(b, &bitwise->instr);
|
||||
return bitwise;
|
||||
}
|
||||
|
||||
static inline rogue_bitwise_instr *
|
||||
rogue_build_bitwise22(rogue_builder *b,
|
||||
enum rogue_bitwise_op op,
|
||||
rogue_ref dst0,
|
||||
rogue_ref dst1,
|
||||
rogue_ref src0,
|
||||
rogue_ref src1)
|
||||
{
|
||||
rogue_ref dsts[] = { dst0, dst1 };
|
||||
rogue_ref srcs[] = { src0, src1 };
|
||||
return rogue_build_bitwise(b, op, 2, dsts, 2, srcs);
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_BITWISE22(op) \
|
||||
PUBLIC \
|
||||
rogue_bitwise_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref dst1, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1) \
|
||||
{ \
|
||||
assert(rogue_bitwise_op_infos[ROGUE_BITWISE_OP_##op].num_dsts == 2); \
|
||||
assert(rogue_bitwise_op_infos[ROGUE_BITWISE_OP_##op].num_srcs == 2); \
|
||||
return rogue_build_bitwise22(b, \
|
||||
ROGUE_BITWISE_OP_##op, \
|
||||
dst0, \
|
||||
dst1, \
|
||||
src0, \
|
||||
src1); \
|
||||
}
|
||||
|
||||
#include "rogue_bitwise_instrs.def"
|
Reference in New Issue
Block a user