2 * Mesa 3-D graphics library
4 * Copyright (C) 2012-2013 LunarG, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included
14 * in all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
25 * Chia-I Wu <olv@lunarg.com>
28 #ifndef TOY_COMPILER_H
29 #define TOY_COMPILER_H
31 #include "brw_defines.h"
33 #include "util/u_slab.h"
34 #include "ilo_common.h"
35 #include "toy_compiler_reg.h"
41 /* 0..127 are reserved for BRW_OPCODE_x */
42 TOY_OPCODE_LAST_HW
= 127,
44 /* TGSI register functions */
46 TOY_OPCODE_TGSI_CONST
,
49 TOY_OPCODE_TGSI_INDIRECT_FETCH
,
50 TOY_OPCODE_TGSI_INDIRECT_STORE
,
52 /* TGSI sampling functions */
60 TOY_OPCODE_TGSI_TXQ_LZ
,
64 TOY_OPCODE_TGSI_SAMPLE
,
65 TOY_OPCODE_TGSI_SAMPLE_I
,
66 TOY_OPCODE_TGSI_SAMPLE_I_MS
,
67 TOY_OPCODE_TGSI_SAMPLE_B
,
68 TOY_OPCODE_TGSI_SAMPLE_C
,
69 TOY_OPCODE_TGSI_SAMPLE_C_LZ
,
70 TOY_OPCODE_TGSI_SAMPLE_D
,
71 TOY_OPCODE_TGSI_SAMPLE_L
,
72 TOY_OPCODE_TGSI_GATHER4
,
73 TOY_OPCODE_TGSI_SVIEWINFO
,
74 TOY_OPCODE_TGSI_SAMPLE_POS
,
75 TOY_OPCODE_TGSI_SAMPLE_INFO
,
87 TOY_OPCODE_INT_DIV_QUOTIENT
,
88 TOY_OPCODE_INT_DIV_REMAINDER
,
93 /* GS-specific functions */
97 /* FS-specific functions */
108 unsigned opcode
:8; /* enum toy_opcode */
109 unsigned access_mode
:1; /* BRW_ALIGN_x */
110 unsigned mask_ctrl
:1; /* BRW_MASK_x */
111 unsigned dep_ctrl
:2; /* BRW_DEPENDENCY_x */
112 unsigned qtr_ctrl
:2; /* GEN6_COMPRESSION_x */
113 unsigned thread_ctrl
:2; /* BRW_THREAD_x */
114 unsigned pred_ctrl
:4; /* BRW_PREDICATE_x */
115 unsigned pred_inv
:1; /* true or false */
116 unsigned exec_size
:3; /* BRW_EXECUTE_x */
117 unsigned cond_modifier
:4; /* BRW_CONDITIONAL_x */
118 unsigned acc_wr_ctrl
:1; /* true or false */
119 unsigned saturate
:1; /* true or false */
121 /* true if the instruction should be ignored for instruction iteration */
127 struct toy_src src
[5]; /* match TGSI_FULL_MAX_SRC_REGISTERS */
130 int target
; /* TGSI_TEXTURE_x */
131 struct toy_src offsets
[1]; /* need to be 4 when GATHER4 is supported */
134 struct list_head list
;
140 struct toy_compiler
{
143 struct toy_inst templ
;
144 struct util_slab_mempool mempool
;
145 struct list_head instructions
;
146 struct list_head
*iter
, *iter_next
;
148 /* this is not set until toy_compiler_legalize_for_asm() */
149 int num_instructions
;
151 int rect_linear_width
;
159 * Allocate the given number of VRF registers.
162 tc_alloc_vrf(struct toy_compiler
*tc
, int count
)
164 const int vrf
= tc
->next_vrf
;
166 tc
->next_vrf
+= count
;
172 * Allocate a temporary register.
174 static inline struct toy_dst
175 tc_alloc_tmp(struct toy_compiler
*tc
)
177 return tdst(TOY_FILE_VRF
, tc_alloc_vrf(tc
, 1), 0);
181 * Allocate four temporary registers.
184 tc_alloc_tmp4(struct toy_compiler
*tc
, struct toy_dst
*tmp
)
186 tmp
[0] = tc_alloc_tmp(tc
);
187 tmp
[1] = tc_alloc_tmp(tc
);
188 tmp
[2] = tc_alloc_tmp(tc
);
189 tmp
[3] = tc_alloc_tmp(tc
);
193 * Duplicate an instruction at the current location.
195 static inline struct toy_inst
*
196 tc_duplicate_inst(struct toy_compiler
*tc
, const struct toy_inst
*inst
)
198 struct toy_inst
*new_inst
;
200 new_inst
= util_slab_alloc(&tc
->mempool
);
205 list_addtail(&new_inst
->list
, tc
->iter_next
);
211 * Move an instruction to the current location.
214 tc_move_inst(struct toy_compiler
*tc
, struct toy_inst
*inst
)
216 list_del(&inst
->list
);
217 list_addtail(&inst
->list
, tc
->iter_next
);
221 * Discard an instruction.
224 tc_discard_inst(struct toy_compiler
*tc
, struct toy_inst
*inst
)
226 list_del(&inst
->list
);
227 util_slab_free(&tc
->mempool
, inst
);
231 * Add a new instruction at the current location, using tc->templ as the
234 static inline struct toy_inst
*
235 tc_add(struct toy_compiler
*tc
)
237 return tc_duplicate_inst(tc
, &tc
->templ
);
241 * A convenient version of tc_add() for instructions with 3 source operands.
243 static inline struct toy_inst
*
244 tc_add3(struct toy_compiler
*tc
, unsigned opcode
,
250 struct toy_inst
*inst
;
256 inst
->opcode
= opcode
;
266 * A convenient version of tc_add() for instructions with 2 source operands.
268 static inline struct toy_inst
*
269 tc_add2(struct toy_compiler
*tc
, int opcode
,
274 return tc_add3(tc
, opcode
, dst
, src0
, src1
, tsrc_null());
278 * A convenient version of tc_add() for instructions with 1 source operand.
280 static inline struct toy_inst
*
281 tc_add1(struct toy_compiler
*tc
, unsigned opcode
,
285 return tc_add2(tc
, opcode
, dst
, src0
, tsrc_null());
289 * A convenient version of tc_add() for instructions without source or
290 * destination operands.
292 static inline struct toy_inst
*
293 tc_add0(struct toy_compiler
*tc
, unsigned opcode
)
295 return tc_add1(tc
, opcode
, tdst_null(), tsrc_null());
298 #define TC_ALU0(func, opcode) \
299 static inline struct toy_inst * \
300 func(struct toy_compiler *tc) \
302 return tc_add0(tc, opcode); \
305 #define TC_ALU1(func, opcode) \
306 static inline struct toy_inst * \
307 func(struct toy_compiler *tc, \
308 struct toy_dst dst, \
309 struct toy_src src) \
311 return tc_add1(tc, opcode, dst, src); \
314 #define TC_ALU2(func, opcode) \
315 static inline struct toy_inst * \
316 func(struct toy_compiler *tc, \
317 struct toy_dst dst, \
318 struct toy_src src0, \
319 struct toy_src src1) \
321 return tc_add2(tc, opcode, \
325 #define TC_ALU3(func, opcode) \
326 static inline struct toy_inst * \
327 func(struct toy_compiler *tc, \
328 struct toy_dst dst, \
329 struct toy_src src0, \
330 struct toy_src src1, \
331 struct toy_src src2) \
333 return tc_add3(tc, opcode, \
334 dst, src0, src1, src2); \
337 #define TC_CND2(func, opcode) \
338 static inline struct toy_inst * \
339 func(struct toy_compiler *tc, \
340 struct toy_dst dst, \
341 struct toy_src src0, \
342 struct toy_src src1, \
343 unsigned cond_modifier) \
345 struct toy_inst *inst; \
346 inst = tc_add2(tc, opcode, \
348 inst->cond_modifier = cond_modifier; \
352 TC_ALU0(tc_NOP
, BRW_OPCODE_NOP
)
353 TC_ALU0(tc_ELSE
, BRW_OPCODE_ELSE
)
354 TC_ALU0(tc_ENDIF
, BRW_OPCODE_ENDIF
)
355 TC_ALU1(tc_MOV
, BRW_OPCODE_MOV
)
356 TC_ALU1(tc_RNDD
, BRW_OPCODE_RNDD
)
357 TC_ALU1(tc_INV
, TOY_OPCODE_INV
)
358 TC_ALU1(tc_FRC
, BRW_OPCODE_FRC
)
359 TC_ALU1(tc_EXP
, TOY_OPCODE_EXP
)
360 TC_ALU1(tc_LOG
, TOY_OPCODE_LOG
)
361 TC_ALU2(tc_ADD
, BRW_OPCODE_ADD
)
362 TC_ALU2(tc_MUL
, BRW_OPCODE_MUL
)
363 TC_ALU2(tc_AND
, BRW_OPCODE_AND
)
364 TC_ALU2(tc_OR
, BRW_OPCODE_OR
)
365 TC_ALU2(tc_DP2
, BRW_OPCODE_DP2
)
366 TC_ALU2(tc_DP3
, BRW_OPCODE_DP3
)
367 TC_ALU2(tc_DP4
, BRW_OPCODE_DP4
)
368 TC_ALU2(tc_SHL
, BRW_OPCODE_SHL
)
369 TC_ALU2(tc_SHR
, BRW_OPCODE_SHR
)
370 TC_ALU2(tc_POW
, TOY_OPCODE_POW
)
371 TC_ALU3(tc_MAC
, BRW_OPCODE_MAC
)
372 TC_CND2(tc_SEL
, BRW_OPCODE_SEL
)
373 TC_CND2(tc_CMP
, BRW_OPCODE_CMP
)
374 TC_CND2(tc_IF
, BRW_OPCODE_IF
)
375 TC_CND2(tc_SEND
, BRW_OPCODE_SEND
)
378 * Upcast a list_head to an instruction.
380 static inline struct toy_inst
*
381 tc_list_to_inst(struct toy_compiler
*tc
, struct list_head
*item
)
383 return container_of(item
, (struct toy_inst
*) NULL
, list
);
387 * Return the instruction at the current location.
389 static inline struct toy_inst
*
390 tc_current(struct toy_compiler
*tc
)
392 return (tc
->iter
!= &tc
->instructions
) ?
393 tc_list_to_inst(tc
, tc
->iter
) : NULL
;
397 * Set the current location to the head.
400 tc_head(struct toy_compiler
*tc
)
402 tc
->iter
= &tc
->instructions
;
403 tc
->iter_next
= tc
->iter
->next
;
407 * Set the current location to the tail.
410 tc_tail(struct toy_compiler
*tc
)
412 tc
->iter
= &tc
->instructions
;
413 tc
->iter_next
= tc
->iter
;
417 * Advance the current location.
419 static inline struct toy_inst
*
420 tc_next_no_skip(struct toy_compiler
*tc
)
422 /* stay at the tail so that new instructions are added there */
423 if (tc
->iter_next
== &tc
->instructions
) {
428 tc
->iter
= tc
->iter_next
;
429 tc
->iter_next
= tc
->iter_next
->next
;
431 return tc_list_to_inst(tc
, tc
->iter
);
435 * Advance the current location, skipping markers.
437 static inline struct toy_inst
*
438 tc_next(struct toy_compiler
*tc
)
440 struct toy_inst
*inst
;
443 inst
= tc_next_no_skip(tc
);
444 } while (inst
&& inst
->marker
);
450 tc_fail(struct toy_compiler
*tc
, const char *reason
)
459 toy_compiler_init(struct toy_compiler
*tc
, int gen
);
462 toy_compiler_cleanup(struct toy_compiler
*tc
);
465 toy_compiler_dump(struct toy_compiler
*tc
);
468 toy_compiler_assemble(struct toy_compiler
*tc
, int *size
);
471 toy_compiler_disassemble(struct toy_compiler
*tc
, const void *kernel
, int size
);
473 #endif /* TOY_COMPILER_H */