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 #include "toy_compiler.h"
34 tc_dump_operand(struct toy_compiler
*tc
,
35 enum toy_file file
, enum toy_type type
, enum toy_rect rect
,
36 bool indirect
, unsigned indirect_subreg
, uint32_t val32
,
39 static const char *toy_file_names
[TOY_FILE_COUNT
] = {
41 [TOY_FILE_ARF
] = "NOT USED",
44 [TOY_FILE_IMM
] = "NOT USED",
46 const char *name
= toy_file_names
[file
];
49 if (file
!= TOY_FILE_IMM
) {
50 reg
= val32
/ TOY_REG_WIDTH
;
51 subreg
= (val32
% TOY_REG_WIDTH
) / toy_type_size(type
);
57 const int addr_subreg
= indirect_subreg
/ toy_type_size(TOY_TYPE_UW
);
59 ilo_printf("%s[a0.%d", name
, addr_subreg
);
61 ilo_printf("%+d", (int) val32
);
68 ilo_printf("%s%d", name
, reg
);
70 ilo_printf(".%d", subreg
);
78 ilo_printf("a0.%d", subreg
);
80 case BRW_ARF_ACCUMULATOR
:
81 case BRW_ARF_ACCUMULATOR
+ 1:
82 ilo_printf("acc%d.%d", (reg
& 1), subreg
);
85 ilo_printf("f0.%d", subreg
);
88 ilo_printf("sr0.%d", subreg
);
91 ilo_printf("cr0.%d", subreg
);
93 case BRW_ARF_NOTIFICATION_COUNT
:
94 case BRW_ARF_NOTIFICATION_COUNT
+ 1:
95 ilo_printf("n%d.%d", (reg
& 1), subreg
);
106 union fi fi
= { .ui
= val32
};
107 ilo_printf("%f", fi
.f
);
111 ilo_printf("%d", (int32_t) val32
);
114 ilo_printf("%u", val32
);
117 ilo_printf("%d", (int16_t) (val32
& 0xffff));
120 ilo_printf("%u", val32
& 0xffff);
123 ilo_printf("0x%08x", val32
);
126 assert(!"unknown imm type");
131 assert(!"unexpected file");
135 /* dump the region parameter */
136 if (file
!= TOY_FILE_IMM
) {
137 int vert_stride
, width
, horz_stride
;
140 case TOY_RECT_LINEAR
:
141 vert_stride
= tc
->rect_linear_width
;
142 width
= tc
->rect_linear_width
;
171 assert(!"unknown rect parameter");
179 ilo_printf("<%d>", horz_stride
);
181 ilo_printf("<%d;%d,%d>", vert_stride
, width
, horz_stride
);
204 assert(!"unexpected type");
210 * Dump a source operand.
213 tc_dump_src(struct toy_compiler
*tc
, struct toy_src src
)
220 tc_dump_operand(tc
, src
.file
, src
.type
, src
.rect
,
221 src
.indirect
, src
.indirect_subreg
, src
.val32
, false);
223 if (tsrc_is_swizzled(src
)) {
224 const char xyzw
[] = "xyzw";
225 ilo_printf(".%c%c%c%c",
229 xyzw
[src
.swizzle_w
]);
237 * Dump a destination operand.
240 tc_dump_dst(struct toy_compiler
*tc
, struct toy_dst dst
)
242 tc_dump_operand(tc
, dst
.file
, dst
.type
, dst
.rect
,
243 dst
.indirect
, dst
.indirect_subreg
, dst
.val32
, true);
245 if (dst
.writemask
!= TOY_WRITEMASK_XYZW
) {
247 if (dst
.writemask
& TOY_WRITEMASK_X
)
249 if (dst
.writemask
& TOY_WRITEMASK_Y
)
251 if (dst
.writemask
& TOY_WRITEMASK_Z
)
253 if (dst
.writemask
& TOY_WRITEMASK_W
)
259 get_opcode_name(unsigned opcode
)
262 case BRW_OPCODE_MOV
: return "mov";
263 case BRW_OPCODE_SEL
: return "sel";
264 case BRW_OPCODE_NOT
: return "not";
265 case BRW_OPCODE_AND
: return "and";
266 case BRW_OPCODE_OR
: return "or";
267 case BRW_OPCODE_XOR
: return "xor";
268 case BRW_OPCODE_SHR
: return "shr";
269 case BRW_OPCODE_SHL
: return "shl";
270 case BRW_OPCODE_RSR
: return "rsr";
271 case BRW_OPCODE_RSL
: return "rsl";
272 case BRW_OPCODE_ASR
: return "asr";
273 case BRW_OPCODE_CMP
: return "cmp";
274 case BRW_OPCODE_CMPN
: return "cmpn";
275 case BRW_OPCODE_JMPI
: return "jmpi";
276 case BRW_OPCODE_IF
: return "if";
277 case BRW_OPCODE_IFF
: return "iff";
278 case BRW_OPCODE_ELSE
: return "else";
279 case BRW_OPCODE_ENDIF
: return "endif";
280 case BRW_OPCODE_DO
: return "do";
281 case BRW_OPCODE_WHILE
: return "while";
282 case BRW_OPCODE_BREAK
: return "break";
283 case BRW_OPCODE_CONTINUE
: return "continue";
284 case BRW_OPCODE_HALT
: return "halt";
285 case BRW_OPCODE_MSAVE
: return "msave";
286 case BRW_OPCODE_MRESTORE
: return "mrestore";
287 case BRW_OPCODE_PUSH
: return "push";
288 case BRW_OPCODE_POP
: return "pop";
289 case BRW_OPCODE_WAIT
: return "wait";
290 case BRW_OPCODE_SEND
: return "send";
291 case BRW_OPCODE_SENDC
: return "sendc";
292 case BRW_OPCODE_MATH
: return "math";
293 case BRW_OPCODE_ADD
: return "add";
294 case BRW_OPCODE_MUL
: return "mul";
295 case BRW_OPCODE_AVG
: return "avg";
296 case BRW_OPCODE_FRC
: return "frc";
297 case BRW_OPCODE_RNDU
: return "rndu";
298 case BRW_OPCODE_RNDD
: return "rndd";
299 case BRW_OPCODE_RNDE
: return "rnde";
300 case BRW_OPCODE_RNDZ
: return "rndz";
301 case BRW_OPCODE_MAC
: return "mac";
302 case BRW_OPCODE_MACH
: return "mach";
303 case BRW_OPCODE_LZD
: return "lzd";
304 case BRW_OPCODE_SAD2
: return "sad2";
305 case BRW_OPCODE_SADA2
: return "sada2";
306 case BRW_OPCODE_DP4
: return "dp4";
307 case BRW_OPCODE_DPH
: return "dph";
308 case BRW_OPCODE_DP3
: return "dp3";
309 case BRW_OPCODE_DP2
: return "dp2";
310 case BRW_OPCODE_DPA2
: return "dpa2";
311 case BRW_OPCODE_LINE
: return "line";
312 case BRW_OPCODE_PLN
: return "pln";
313 case BRW_OPCODE_MAD
: return "mad";
314 case BRW_OPCODE_NOP
: return "nop";
316 case TOY_OPCODE_TGSI_IN
: return "tgsi.in";
317 case TOY_OPCODE_TGSI_CONST
: return "tgsi.const";
318 case TOY_OPCODE_TGSI_SV
: return "tgsi.sv";
319 case TOY_OPCODE_TGSI_IMM
: return "tgsi.imm";
320 case TOY_OPCODE_TGSI_INDIRECT_FETCH
: return "tgsi.indirect_fetch";
321 case TOY_OPCODE_TGSI_INDIRECT_STORE
: return "tgsi.indirect_store";
322 case TOY_OPCODE_TGSI_TEX
: return "tgsi.tex";
323 case TOY_OPCODE_TGSI_TXB
: return "tgsi.txb";
324 case TOY_OPCODE_TGSI_TXD
: return "tgsi.txd";
325 case TOY_OPCODE_TGSI_TXL
: return "tgsi.txl";
326 case TOY_OPCODE_TGSI_TXP
: return "tgsi.txp";
327 case TOY_OPCODE_TGSI_TXF
: return "tgsi.txf";
328 case TOY_OPCODE_TGSI_TXQ
: return "tgsi.txq";
329 case TOY_OPCODE_TGSI_TXQ_LZ
: return "tgsi.txq_lz";
330 case TOY_OPCODE_TGSI_TEX2
: return "tgsi.tex2";
331 case TOY_OPCODE_TGSI_TXB2
: return "tgsi.txb2";
332 case TOY_OPCODE_TGSI_TXL2
: return "tgsi.txl2";
333 case TOY_OPCODE_TGSI_SAMPLE
: return "tgsi.sample";
334 case TOY_OPCODE_TGSI_SAMPLE_I
: return "tgsi.sample_i";
335 case TOY_OPCODE_TGSI_SAMPLE_I_MS
: return "tgsi.sample_i_ms";
336 case TOY_OPCODE_TGSI_SAMPLE_B
: return "tgsi.sample_b";
337 case TOY_OPCODE_TGSI_SAMPLE_C
: return "tgsi.sample_c";
338 case TOY_OPCODE_TGSI_SAMPLE_C_LZ
: return "tgsi.sample_c_lz";
339 case TOY_OPCODE_TGSI_SAMPLE_D
: return "tgsi.sample_d";
340 case TOY_OPCODE_TGSI_SAMPLE_L
: return "tgsi.sample_l";
341 case TOY_OPCODE_TGSI_GATHER4
: return "tgsi.gather4";
342 case TOY_OPCODE_TGSI_SVIEWINFO
: return "tgsi.sviewinfo";
343 case TOY_OPCODE_TGSI_SAMPLE_POS
: return "tgsi.sample_pos";
344 case TOY_OPCODE_TGSI_SAMPLE_INFO
: return "tgsi.sample_info";
346 case TOY_OPCODE_INV
: return "math.inv";
347 case TOY_OPCODE_LOG
: return "math.log";
348 case TOY_OPCODE_EXP
: return "math.exp";
349 case TOY_OPCODE_SQRT
: return "math.sqrt";
350 case TOY_OPCODE_RSQ
: return "math.rsq";
351 case TOY_OPCODE_SIN
: return "math.sin";
352 case TOY_OPCODE_COS
: return "math.cos";
353 case TOY_OPCODE_FDIV
: return "math.fdiv";
354 case TOY_OPCODE_POW
: return "math.pow";
355 case TOY_OPCODE_INT_DIV_QUOTIENT
: return "math.int_div_quotient";
356 case TOY_OPCODE_INT_DIV_REMAINDER
: return "math.int_div_remainer";
358 case TOY_OPCODE_URB_WRITE
: return "urb.urb_write";
360 case TOY_OPCODE_EMIT
: return "gs.emit";
361 case TOY_OPCODE_ENDPRIM
: return "gs.endprim";
363 case TOY_OPCODE_DDX
: return "fs.ddx";
364 case TOY_OPCODE_DDY
: return "fs.ddy";
365 case TOY_OPCODE_FB_WRITE
: return "fs.fb_write";
366 case TOY_OPCODE_KIL
: return "fs.kil";
367 default: return "unk";
372 get_cond_modifier_name(unsigned opcode
, unsigned cond_modifier
)
375 case BRW_OPCODE_SEND
:
376 case BRW_OPCODE_SENDC
:
378 switch (cond_modifier
) {
379 case BRW_SFID_NULL
: return "Null";
380 case BRW_SFID_SAMPLER
: return "Sampling Engine";
381 case BRW_SFID_MESSAGE_GATEWAY
: return "Message Gateway";
382 case GEN6_SFID_DATAPORT_SAMPLER_CACHE
: return "Data Port Sampler Cache";
383 case GEN6_SFID_DATAPORT_RENDER_CACHE
: return "Data Port Render Cache";
384 case BRW_SFID_URB
: return "URB";
385 case BRW_SFID_THREAD_SPAWNER
: return "Thread Spawner";
386 case GEN6_SFID_DATAPORT_CONSTANT_CACHE
: return "Constant Cache";
387 default: return "Unknown";
390 case BRW_OPCODE_MATH
:
392 switch (cond_modifier
) {
393 case BRW_MATH_FUNCTION_INV
: return "INV";
394 case BRW_MATH_FUNCTION_LOG
: return "LOG";
395 case BRW_MATH_FUNCTION_EXP
: return "EXP";
396 case BRW_MATH_FUNCTION_SQRT
: return "SQRT";
397 case BRW_MATH_FUNCTION_RSQ
: return "RSQ";
398 case BRW_MATH_FUNCTION_SIN
: return "SIN";
399 case BRW_MATH_FUNCTION_COS
: return "COS";
400 case BRW_MATH_FUNCTION_FDIV
: return "FDIV";
401 case BRW_MATH_FUNCTION_POW
: return "POW";
402 case BRW_MATH_FUNCTION_INT_DIV_QUOTIENT
: return "INT DIV (quotient)";
403 case BRW_MATH_FUNCTION_INT_DIV_REMAINDER
: return "INT DIV (remainder)";
404 default: return "UNK";
408 switch (cond_modifier
) {
409 case BRW_CONDITIONAL_NONE
: return NULL
;
410 case BRW_CONDITIONAL_Z
: return "z";
411 case BRW_CONDITIONAL_NZ
: return "nz";
412 case BRW_CONDITIONAL_G
: return "g";
413 case BRW_CONDITIONAL_GE
: return "ge";
414 case BRW_CONDITIONAL_L
: return "l";
415 case BRW_CONDITIONAL_LE
: return "le";
416 default: return "unk";
423 * Dump an instruction.
426 tc_dump_inst(struct toy_compiler
*tc
, const struct toy_inst
*inst
)
431 name
= get_opcode_name(inst
->opcode
);
433 ilo_printf(" %s", name
);
435 if (inst
->opcode
== BRW_OPCODE_NOP
) {
443 name
= get_cond_modifier_name(inst
->opcode
, inst
->cond_modifier
);
445 ilo_printf(".%s", name
);
449 tc_dump_dst(tc
, inst
->dst
);
451 for (i
= 0; i
< Elements(inst
->src
); i
++) {
452 if (tsrc_is_null(inst
->src
[i
]))
456 tc_dump_src(tc
, inst
->src
[i
]);
463 * Dump the instructions added to the compiler.
466 toy_compiler_dump(struct toy_compiler
*tc
)
468 struct toy_inst
*inst
;
473 while ((inst
= tc_next_no_skip(tc
)) != NULL
) {
474 /* we do not generate code for markers */
476 ilo_printf("marker:");
478 ilo_printf("%6d:", pc
++);
480 tc_dump_inst(tc
, inst
);
485 * Clean up the toy compiler.
488 toy_compiler_cleanup(struct toy_compiler
*tc
)
490 struct toy_inst
*inst
, *next
;
492 LIST_FOR_EACH_ENTRY_SAFE(inst
, next
, &tc
->instructions
, list
)
493 util_slab_free(&tc
->mempool
, inst
);
495 util_slab_destroy(&tc
->mempool
);
499 * Initialize the instruction template, from which tc_add() initializes the
500 * newly added instructions.
503 tc_init_inst_templ(struct toy_compiler
*tc
)
505 struct toy_inst
*templ
= &tc
->templ
;
508 templ
->opcode
= BRW_OPCODE_NOP
;
509 templ
->access_mode
= BRW_ALIGN_1
;
510 templ
->mask_ctrl
= BRW_MASK_ENABLE
;
511 templ
->dep_ctrl
= BRW_DEPENDENCY_NORMAL
;
512 templ
->qtr_ctrl
= GEN6_COMPRESSION_1Q
;
513 templ
->thread_ctrl
= BRW_THREAD_NORMAL
;
514 templ
->pred_ctrl
= BRW_PREDICATE_NONE
;
515 templ
->pred_inv
= false;
516 templ
->exec_size
= BRW_EXECUTE_1
;
517 templ
->cond_modifier
= BRW_CONDITIONAL_NONE
;
518 templ
->acc_wr_ctrl
= false;
519 templ
->saturate
= false;
521 templ
->marker
= false;
523 templ
->dst
= tdst_null();
524 for (i
= 0; i
< Elements(templ
->src
); i
++)
525 templ
->src
[i
] = tsrc_null();
527 for (i
= 0; i
< Elements(templ
->tex
.offsets
); i
++)
528 templ
->tex
.offsets
[i
] = tsrc_null();
530 list_inithead(&templ
->list
);
534 * Initialize the toy compiler.
537 toy_compiler_init(struct toy_compiler
*tc
, const struct ilo_dev_info
*dev
)
539 memset(tc
, 0, sizeof(*tc
));
543 tc_init_inst_templ(tc
);
545 util_slab_create(&tc
->mempool
, sizeof(struct toy_inst
),
546 64, UTIL_SLAB_SINGLETHREADED
);
548 list_inithead(&tc
->instructions
);
549 /* instructions are added to the tail */
552 tc
->rect_linear_width
= 1;
554 /* skip 0 so that util_hash_table_get() never returns NULL */