1 /*
2 * Copyright © 2022 Imagination Technologies Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24 #ifndef ROGUE_BUILDER_H
25 #define ROGUE_BUILDER_H
26
27 /**
28 * \file rogue_builder.h
29 *
30 * \brief Contains helper functions for building Rogue shaders.
31 */
32
33 #include "rogue.h"
34
35 /** Rogue builder context. */
36 typedef struct rogue_builder {
37 rogue_shader *shader; /** The shader being built. */
38 rogue_cursor cursor; /** The current position in the shader. */
39 } rogue_builder;
40
41 /**
42 * \brief Initialises a Rogue builder context.
43 *
44 * \param[in] b The builder context.
45 * \param[in] shader The shader.
46 */
rogue_builder_init(rogue_builder * b,rogue_shader * shader)47 static inline void rogue_builder_init(rogue_builder *b, rogue_shader *shader)
48 {
49 b->shader = shader;
50 b->cursor = rogue_cursor_before_shader(shader);
51 }
52
53 /**
54 * \brief Inserts a basic block at the current builder context position.
55 *
56 * \param[in] b The builder context.
57 * \param[in] block The basic block to insert.
58 */
rogue_builder_insert_block(rogue_builder * b,rogue_block * block)59 static inline void rogue_builder_insert_block(rogue_builder *b,
60 rogue_block *block)
61 {
62 rogue_block_insert(block, b->cursor);
63 b->cursor = rogue_cursor_after_block(block);
64 }
65
66 /**
67 * \brief Inserts a new basic block at the current builder context position.
68 *
69 * \param[in] b The builder context.
70 * \param[in] label The (optional) basic block label.
71 * \return The new block.
72 */
rogue_push_block_labelled(rogue_builder * b,const char * label)73 static inline rogue_block *rogue_push_block_labelled(rogue_builder *b,
74 const char *label)
75 {
76 rogue_block *block = rogue_block_create(b->shader, label);
77 rogue_builder_insert_block(b, block);
78
79 return block;
80 }
81
82 /**
83 * \brief Inserts a new basic block at the current builder context position.
84 *
85 * \param[in] b The builder context.
86 * \return The new block.
87 */
rogue_push_block(rogue_builder * b)88 static inline rogue_block *rogue_push_block(rogue_builder *b)
89 {
90 return rogue_push_block_labelled(b, NULL);
91 }
92
93 /* ALU instructions. */
94 #define ROGUE_BUILDER_DEFINE_ALU11(op) \
95 rogue_alu_instr *rogue_##op(rogue_builder *b, \
96 rogue_ref dst0, \
97 rogue_ref src0);
98
99 #define ROGUE_BUILDER_DEFINE_ALU12(op) \
100 rogue_alu_instr *rogue_##op(rogue_builder *b, \
101 rogue_ref dst0, \
102 rogue_ref src0, \
103 rogue_ref src1);
104
105 #define ROGUE_BUILDER_DEFINE_ALU13(op) \
106 rogue_alu_instr *rogue_##op(rogue_builder *b, \
107 rogue_ref dst0, \
108 rogue_ref src0, \
109 rogue_ref src1, \
110 rogue_ref src2);
111
112 #define ROGUE_BUILDER_DEFINE_ALU22(op) \
113 rogue_alu_instr *rogue_##op(rogue_builder *b, \
114 rogue_ref dst0, \
115 rogue_ref dst1, \
116 rogue_ref src0, \
117 rogue_ref src1);
118
119 #define ROGUE_BUILDER_DEFINE_ALU23(op) \
120 rogue_alu_instr *rogue_##op(rogue_builder *b, \
121 rogue_ref dst0, \
122 rogue_ref dst1, \
123 rogue_ref src0, \
124 rogue_ref src1, \
125 rogue_ref src2);
126
127 #define ROGUE_BUILDER_DEFINE_ALU35(op) \
128 rogue_alu_instr *rogue_##op(rogue_builder *b, \
129 rogue_ref dst0, \
130 rogue_ref dst1, \
131 rogue_ref dst2, \
132 rogue_ref src0, \
133 rogue_ref src1, \
134 rogue_ref src2, \
135 rogue_ref src3, \
136 rogue_ref src4);
137
138 #include "rogue_alu_instrs.def"
139
140 /* Backend instructions. */
141 #define ROGUE_BUILDER_DEFINE_BACKEND00(op) \
142 rogue_backend_instr *rogue_##op(rogue_builder *b);
143
144 #define ROGUE_BUILDER_DEFINE_BACKEND02(op) \
145 rogue_backend_instr *rogue_##op(rogue_builder *b, \
146 rogue_ref src0, \
147 rogue_ref src1);
148
149 #define ROGUE_BUILDER_DEFINE_BACKEND11(op) \
150 rogue_backend_instr *rogue_##op(rogue_builder *b, \
151 rogue_ref dst0, \
152 rogue_ref src0);
153
154 #define ROGUE_BUILDER_DEFINE_BACKEND13(op) \
155 rogue_backend_instr *rogue_##op(rogue_builder *b, \
156 rogue_ref dst0, \
157 rogue_ref src0, \
158 rogue_ref src1, \
159 rogue_ref src2);
160
161 #define ROGUE_BUILDER_DEFINE_BACKEND14(op) \
162 rogue_backend_instr *rogue_##op(rogue_builder *b, \
163 rogue_ref dst0, \
164 rogue_ref src0, \
165 rogue_ref src1, \
166 rogue_ref src2, \
167 rogue_ref src3);
168
169 #define ROGUE_BUILDER_DEFINE_BACKEND06(op) \
170 rogue_backend_instr *rogue_##op(rogue_builder *b, \
171 rogue_ref src0, \
172 rogue_ref src1, \
173 rogue_ref src2, \
174 rogue_ref src3, \
175 rogue_ref src4, \
176 rogue_ref src5);
177
178 #define ROGUE_BUILDER_DEFINE_BACKEND16(op) \
179 rogue_backend_instr *rogue_##op(rogue_builder *b, \
180 rogue_ref dst0, \
181 rogue_ref src0, \
182 rogue_ref src1, \
183 rogue_ref src2, \
184 rogue_ref src3, \
185 rogue_ref src4, \
186 rogue_ref src5);
187
188 #include "rogue_backend_instrs.def"
189
190 /* Ctrl instructions. */
191 #define ROGUE_BUILDER_DEFINE_CTRLB(op) \
192 rogue_ctrl_instr *rogue_##op(rogue_builder *b, rogue_block *block);
193
194 #define ROGUE_BUILDER_DEFINE_CTRL00(op) \
195 rogue_ctrl_instr *rogue_##op(rogue_builder *b);
196
197 #define ROGUE_BUILDER_DEFINE_CTRL01(op) \
198 rogue_ctrl_instr *rogue_##op(rogue_builder *b, rogue_ref src0);
199
200 #include "rogue_ctrl_instrs.def"
201
202 /* Bitwise instructions. */
203 #define ROGUE_BUILDER_DEFINE_BITWISE22(op) \
204 rogue_bitwise_instr *rogue_##op(rogue_builder *b, \
205 rogue_ref dst0, \
206 rogue_ref dst1, \
207 rogue_ref src0, \
208 rogue_ref src1);
209
210 #include "rogue_bitwise_instrs.def"
211
212 #endif /* ROGUE_BUILDER_H */
213