5 * Copyright (c) 2013 Connor Abbott (connor@abbott.cx)
6 * Copyright (c) 2018 Alyssa Rosenzweig (alyssa@rosenzweig.io)
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 #include "midgard-parse.h"
34 #include "disassemble.h"
36 #include "util/half_float.h"
38 #define DEFINE_CASE(define, str) case define: { printf(str); break; }
40 static bool is_instruction_int
= false;
43 print_alu_opcode(midgard_alu_op op
)
47 if (alu_opcode_props
[op
].name
) {
48 printf("%s", alu_opcode_props
[op
].name
);
50 int_op
= midgard_is_integer_op(op
);
52 printf("alu_op_%02X", op
);
54 /* For constant analysis */
55 is_instruction_int
= int_op
;
59 print_ld_st_opcode(midgard_load_store_op op
)
61 if (load_store_opcode_names
[op
])
62 printf("%s", load_store_opcode_names
[op
]);
64 printf("ldst_op_%02X", op
);
67 static bool is_embedded_constant_half
= false;
68 static bool is_embedded_constant_int
= false;
71 prefix_for_bits(unsigned bits
)
86 print_reg(unsigned reg
, unsigned bits
)
88 /* Perform basic static analysis for expanding constants correctly */
90 if ((bits
== 16) && (reg
>> 1) == 26) {
91 is_embedded_constant_half
= true;
92 is_embedded_constant_int
= is_instruction_int
;
93 } else if ((bits
== 32) && reg
== 26) {
94 is_embedded_constant_int
= is_instruction_int
;
95 } else if (bits
== 8) {
97 } else if (bits
== 64) {
101 char prefix
= prefix_for_bits(bits
);
109 static char *outmod_names
[4] = {
117 print_outmod(midgard_outmod outmod
)
119 printf("%s", outmod_names
[outmod
]);
123 print_quad_word(uint32_t *words
, unsigned tabs
)
127 for (i
= 0; i
< 4; i
++)
128 printf("0x%08X%s ", words
[i
], i
== 3 ? "" : ",");
134 print_vector_src(unsigned src_binary
, bool out_high
,
135 midgard_reg_mode mode
, unsigned reg
,
138 midgard_vector_alu_src
*src
= (midgard_vector_alu_src
*)&src_binary
;
140 /* Modifiers change meaning depending on the op's context */
142 midgard_int_mod int_mod
= src
->mod
;
146 case midgard_int_sign_extend
:
149 case midgard_int_zero_extend
:
152 case midgard_int_reserved
:
155 case midgard_int_normal
:
160 if (src
->mod
& MIDGARD_FLOAT_MOD_NEG
)
163 if (src
->mod
& MIDGARD_FLOAT_MOD_ABS
)
169 if (mode
== midgard_reg_mode_8
) {
171 printf(" /* half */ ");
173 unsigned quarter_reg
= reg
* 2;
180 printf(" /* rep_high */ ");
186 printf(" /* rep_low */ ");
189 print_reg(quarter_reg
, 8);
190 } else if (mode
== midgard_reg_mode_16
) {
192 printf(" /* half */ ");
194 unsigned half_reg
= reg
* 2;
201 printf(" /* rep_high */ ");
207 printf(" /* rep_low */ ");
210 print_reg(half_reg
, 16);
211 } else if (mode
== midgard_reg_mode_32
) {
213 printf(" /* rep_high */ ");
216 print_reg(reg
* 2 + src
->rep_low
, 16);
219 printf(" /* rep_low */ ");
223 } else if (mode
== midgard_reg_mode_64
) {
225 printf(" /* rep_high */ ");
228 printf(" /* rep_low */ ");
231 printf(" /* half */ ");
234 printf(" /* out_high */ ");
241 if (src
->swizzle
!= 0xE4) { //default swizzle
243 static const char c
[4] = "xyzw";
247 for (i
= 0; i
< 4; i
++)
248 printf("%c", c
[(src
->swizzle
>> (i
* 2)) & 3]);
251 /* Since we wrapped with a function-looking thing */
253 if ((is_int
&& (int_mod
!= midgard_int_normal
))
254 || (!is_int
&& src
->mod
& MIDGARD_FLOAT_MOD_ABS
))
259 decode_vector_imm(unsigned src2_reg
, unsigned imm
)
262 ret
= src2_reg
<< 11;
263 ret
|= (imm
& 0x7) << 8;
264 ret
|= (imm
>> 3) & 0xFF;
269 print_immediate(uint16_t imm
)
271 if (is_instruction_int
)
274 printf("#%g", _mesa_half_to_float(imm
));
278 bits_for_mode(midgard_reg_mode mode
)
281 case midgard_reg_mode_8
:
283 case midgard_reg_mode_16
:
285 case midgard_reg_mode_32
:
287 case midgard_reg_mode_64
:
295 print_dest(unsigned reg
, midgard_reg_mode mode
, midgard_dest_override override
, bool out_high
)
297 bool overriden
= override
!= midgard_dest_override_none
;
298 bool overriden_up
= override
== midgard_dest_override_upper
;
300 /* Depending on the mode and override, we determine the type of
301 * destination addressed. Absent an override, we address just the
302 * type of the operation itself, directly at the out_reg register
303 * (scaled if necessary to disambiguate, raised if necessary) */
305 unsigned bits
= bits_for_mode(mode
);
310 /* Sanity check the override */
313 bool modeable
= (mode
== midgard_reg_mode_32
) || (mode
== midgard_reg_mode_16
);
314 bool known
= override
!= 0x3; /* Unused value */
315 bool uppable
= !overriden_up
|| (mode
== midgard_reg_mode_32
);
317 if (!(modeable
&& known
&& uppable
))
318 printf("/* do%d */ ", override
);
322 case midgard_reg_mode_8
:
323 case midgard_reg_mode_16
:
324 reg
= reg
* 2 + out_high
;
327 case midgard_reg_mode_32
:
329 reg
= (reg
* 2) + overriden_up
;
338 print_reg(reg
, bits
);
342 print_vector_field(const char *name
, uint16_t *words
, uint16_t reg_word
,
345 midgard_reg_info
*reg_info
= (midgard_reg_info
*)®_word
;
346 midgard_vector_alu
*alu_field
= (midgard_vector_alu
*) words
;
347 midgard_reg_mode mode
= alu_field
->reg_mode
;
349 /* For now, prefix instruction names with their unit, until we
350 * understand how this works on a deeper level */
353 print_alu_opcode(alu_field
->op
);
354 print_outmod(alu_field
->outmod
);
357 bool out_high
= false;
360 if (mode
== midgard_reg_mode_16
361 || mode
== midgard_reg_mode_8
) {
363 /* For partial views, the mask denotes which adjacent register
364 * is used as the window into the larger register */
366 if (alu_field
->mask
& 0xF) {
369 if ((alu_field
->mask
& 0xF0))
370 printf("/* %X */ ", alu_field
->mask
);
372 mask
= alu_field
->mask
;
375 mask
= alu_field
->mask
>> 4;
378 /* For full 32-bit, every other bit is duplicated, so we only
379 * pick every other to find the effective mask */
381 mask
= alu_field
->mask
& 1;
382 mask
|= (alu_field
->mask
& 4) >> 1;
383 mask
|= (alu_field
->mask
& 16) >> 2;
384 mask
|= (alu_field
->mask
& 64) >> 3;
386 /* ... but verify! */
388 unsigned checked
= alu_field
->mask
& 0x55;
389 unsigned opposite
= alu_field
->mask
& 0xAA;
391 if ((checked
<< 1) != opposite
)
392 printf("/* %X */ ", alu_field
->mask
);
395 /* First, print the destination */
396 print_dest(reg_info
->out_reg
, mode
, alu_field
->dest_override
, out_high
);
398 /* The semantics here are not totally grokked yet */
399 if (alu_field
->dest_override
== midgard_dest_override_upper
)
404 static const char c
[4] = "xyzw";
408 for (i
= 0; i
< 4; i
++)
415 bool is_int
= midgard_is_integer_op(alu_field
->op
);
416 print_vector_src(alu_field
->src1
, out_high
, mode
, reg_info
->src1_reg
, is_int
);
420 if (reg_info
->src2_imm
) {
421 uint16_t imm
= decode_vector_imm(reg_info
->src2_reg
, alu_field
->src2
>> 2);
422 print_immediate(imm
);
424 print_vector_src(alu_field
->src2
, out_high
, mode
,
425 reg_info
->src2_reg
, is_int
);
432 print_scalar_src(unsigned src_binary
, unsigned reg
)
434 midgard_scalar_alu_src
*src
= (midgard_scalar_alu_src
*)&src_binary
;
445 print_reg(reg
* 2 + (src
->component
>> 2), 16);
447 static const char c
[4] = "xyzw";
449 printf(".%c", c
[src
->full
? src
->component
>> 1 : src
->component
& 3]);
457 decode_scalar_imm(unsigned src2_reg
, unsigned imm
)
460 ret
= src2_reg
<< 11;
461 ret
|= (imm
& 3) << 9;
462 ret
|= (imm
& 4) << 6;
463 ret
|= (imm
& 0x38) << 2;
469 print_scalar_field(const char *name
, uint16_t *words
, uint16_t reg_word
,
472 midgard_reg_info
*reg_info
= (midgard_reg_info
*)®_word
;
473 midgard_scalar_alu
*alu_field
= (midgard_scalar_alu
*) words
;
475 if (alu_field
->unknown
)
476 printf("scalar ALU unknown bit set\n");
479 print_alu_opcode(alu_field
->op
);
480 print_outmod(alu_field
->outmod
);
483 if (alu_field
->output_full
)
484 print_reg(reg_info
->out_reg
, 32);
486 print_reg(reg_info
->out_reg
* 2 + (alu_field
->output_component
>> 2),
489 static const char c
[4] = "xyzw";
491 c
[alu_field
->output_full
? alu_field
->output_component
>> 1 :
492 alu_field
->output_component
& 3]);
494 print_scalar_src(alu_field
->src1
, reg_info
->src1_reg
);
498 if (reg_info
->src2_imm
) {
499 uint16_t imm
= decode_scalar_imm(reg_info
->src2_reg
,
501 print_immediate(imm
);
503 print_scalar_src(alu_field
->src2
, reg_info
->src2_reg
);
509 print_branch_op(int op
)
512 case midgard_jmp_writeout_op_branch_uncond
:
516 case midgard_jmp_writeout_op_branch_cond
:
520 case midgard_jmp_writeout_op_writeout
:
524 case midgard_jmp_writeout_op_tilebuffer_pending
:
525 printf("tilebuffer.");
528 case midgard_jmp_writeout_op_discard
:
533 printf("unk%d.", op
);
539 print_branch_cond(int cond
)
542 case midgard_condition_write0
:
546 case midgard_condition_false
:
550 case midgard_condition_true
:
554 case midgard_condition_always
:
559 printf("unk%X", cond
);
565 print_compact_branch_writeout_field(uint16_t word
)
567 midgard_jmp_writeout_op op
= word
& 0x7;
570 case midgard_jmp_writeout_op_branch_uncond
: {
571 midgard_branch_uncond br_uncond
;
572 memcpy((char *) &br_uncond
, (char *) &word
, sizeof(br_uncond
));
573 printf("br.uncond ");
575 if (br_uncond
.unknown
!= 1)
576 printf("unknown:%d, ", br_uncond
.unknown
);
578 if (br_uncond
.offset
>= 0)
581 printf("%d", br_uncond
.offset
);
583 printf(" -> %X\n", br_uncond
.dest_tag
);
587 case midgard_jmp_writeout_op_branch_cond
:
588 case midgard_jmp_writeout_op_writeout
:
589 case midgard_jmp_writeout_op_discard
:
591 midgard_branch_cond br_cond
;
592 memcpy((char *) &br_cond
, (char *) &word
, sizeof(br_cond
));
596 print_branch_op(br_cond
.op
);
597 print_branch_cond(br_cond
.cond
);
601 if (br_cond
.offset
>= 0)
604 printf("%d", br_cond
.offset
);
606 printf(" -> %X\n", br_cond
.dest_tag
);
613 print_extended_branch_writeout_field(uint8_t *words
)
615 midgard_branch_extended br
;
616 memcpy((char *) &br
, (char *) words
, sizeof(br
));
620 print_branch_op(br
.op
);
622 /* Condition repeated 8 times in all known cases. Check this. */
624 unsigned cond
= br
.cond
& 0x3;
626 for (unsigned i
= 0; i
< 16; i
+= 2) {
627 assert(((br
.cond
>> i
) & 0x3) == cond
);
630 print_branch_cond(cond
);
633 printf(".unknown%d", br
.unknown
);
640 printf("%d", br
.offset
);
642 printf(" -> %X\n", br
.dest_tag
);
646 num_alu_fields_enabled(uint32_t control_word
)
650 if ((control_word
>> 17) & 1)
653 if ((control_word
>> 19) & 1)
656 if ((control_word
>> 21) & 1)
659 if ((control_word
>> 23) & 1)
662 if ((control_word
>> 25) & 1)
669 float_bitcast(uint32_t integer
)
681 print_alu_word(uint32_t *words
, unsigned num_quad_words
,
684 uint32_t control_word
= words
[0];
685 uint16_t *beginning_ptr
= (uint16_t *)(words
+ 1);
686 unsigned num_fields
= num_alu_fields_enabled(control_word
);
687 uint16_t *word_ptr
= beginning_ptr
+ num_fields
;
688 unsigned num_words
= 2 + num_fields
;
690 if ((control_word
>> 16) & 1)
691 printf("unknown bit 16 enabled\n");
693 if ((control_word
>> 17) & 1) {
694 print_vector_field("vmul", word_ptr
, *beginning_ptr
, tabs
);
700 if ((control_word
>> 18) & 1)
701 printf("unknown bit 18 enabled\n");
703 if ((control_word
>> 19) & 1) {
704 print_scalar_field("sadd", word_ptr
, *beginning_ptr
, tabs
);
710 if ((control_word
>> 20) & 1)
711 printf("unknown bit 20 enabled\n");
713 if ((control_word
>> 21) & 1) {
714 print_vector_field("vadd", word_ptr
, *beginning_ptr
, tabs
);
720 if ((control_word
>> 22) & 1)
721 printf("unknown bit 22 enabled\n");
723 if ((control_word
>> 23) & 1) {
724 print_scalar_field("smul", word_ptr
, *beginning_ptr
, tabs
);
730 if ((control_word
>> 24) & 1)
731 printf("unknown bit 24 enabled\n");
733 if ((control_word
>> 25) & 1) {
734 print_vector_field("lut", word_ptr
, *beginning_ptr
, tabs
);
740 if ((control_word
>> 26) & 1) {
741 print_compact_branch_writeout_field(*word_ptr
);
746 if ((control_word
>> 27) & 1) {
747 print_extended_branch_writeout_field((uint8_t *) word_ptr
);
752 if (num_quad_words
> (num_words
+ 7) / 8) {
753 assert(num_quad_words
== (num_words
+ 15) / 8);
754 //Assume that the extra quadword is constants
755 void *consts
= words
+ (4 * num_quad_words
- 4);
757 if (is_embedded_constant_int
) {
758 if (is_embedded_constant_half
) {
759 int16_t *sconsts
= (int16_t *) consts
;
760 printf("sconstants %d, %d, %d, %d\n",
766 int32_t *iconsts
= (int32_t *) consts
;
767 printf("iconstants %d, %d, %d, %d\n",
774 if (is_embedded_constant_half
) {
775 uint16_t *hconsts
= (uint16_t *) consts
;
776 printf("hconstants %g, %g, %g, %g\n",
777 _mesa_half_to_float(hconsts
[0]),
778 _mesa_half_to_float(hconsts
[1]),
779 _mesa_half_to_float(hconsts
[2]),
780 _mesa_half_to_float(hconsts
[3]));
782 uint32_t *fconsts
= (uint32_t *) consts
;
783 printf("fconstants %g, %g, %g, %g\n",
784 float_bitcast(fconsts
[0]),
785 float_bitcast(fconsts
[1]),
786 float_bitcast(fconsts
[2]),
787 float_bitcast(fconsts
[3]));
794 /* Swizzle/mask formats are common between load/store ops and texture ops, it
798 print_swizzle(uint32_t swizzle
)
802 if (swizzle
!= 0xE4) {
805 for (i
= 0; i
< 4; i
++)
806 printf("%c", "xyzw"[(swizzle
>> (2 * i
)) & 3]);
811 print_mask(uint32_t mask
)
818 for (i
= 0; i
< 4; i
++)
820 printf("%c", "xyzw"[i
]);
822 /* Handle degenerate case */
829 print_varying_parameters(midgard_load_store_word
*word
)
831 midgard_varying_parameter param
;
832 unsigned v
= word
->varying_parameters
;
833 memcpy(¶m
, &v
, sizeof(param
));
835 if (param
.is_varying
) {
836 /* If a varying, there are qualifiers */
840 if (param
.interpolation
!= midgard_interp_default
) {
841 if (param
.interpolation
== midgard_interp_centroid
)
844 printf(".interp%d", param
.interpolation
);
846 } else if (param
.flat
|| param
.interpolation
) {
847 printf(" /* is_varying not set but varying metadata attached */");
850 if (param
.zero1
|| param
.zero2
)
851 printf(" /* zero tripped, %d %d */ ", param
.zero1
, param
.zero2
);
855 is_op_varying(unsigned op
)
858 case midgard_op_st_vary_16
:
859 case midgard_op_st_vary_32
:
860 case midgard_op_ld_vary_16
:
861 case midgard_op_ld_vary_32
:
869 print_load_store_instr(uint64_t data
,
872 midgard_load_store_word
*word
= (midgard_load_store_word
*) &data
;
874 print_ld_st_opcode(word
->op
);
876 if (is_op_varying(word
->op
))
877 print_varying_parameters(word
);
879 printf(" r%d", word
->reg
);
880 print_mask(word
->mask
);
882 int address
= word
->address
;
884 if (word
->op
== midgard_op_ld_uniform_32
) {
885 /* Uniforms use their own addressing scheme */
887 int lo
= word
->varying_parameters
>> 7;
888 int hi
= word
->address
;
890 /* TODO: Combine fields logically */
891 address
= (hi
<< 3) | lo
;
894 printf(", %d", address
);
896 print_swizzle(word
->swizzle
);
898 printf(", 0x%X /* %X */\n", word
->unknown
, word
->varying_parameters
);
902 print_load_store_word(uint32_t *word
, unsigned tabs
)
904 midgard_load_store
*load_store
= (midgard_load_store
*) word
;
906 if (load_store
->word1
!= 3) {
907 print_load_store_instr(load_store
->word1
, tabs
);
910 if (load_store
->word2
!= 3) {
911 print_load_store_instr(load_store
->word2
, tabs
);
916 print_texture_reg(bool full
, bool select
, bool upper
)
919 printf("r%d", REG_TEX_BASE
+ select
);
921 printf("hr%d", (REG_TEX_BASE
+ select
) * 2 + upper
);
924 printf("// error: out full / upper mutually exclusive\n");
929 print_texture_format(int format
)
931 /* Act like a modifier */
935 DEFINE_CASE(TEXTURE_2D
, "2d");
936 DEFINE_CASE(TEXTURE_3D
, "3d");
937 DEFINE_CASE(TEXTURE_CUBE
, "cube");
940 printf("fmt_%d", format
);
946 print_texture_op(int format
)
948 /* Act like a modifier */
952 DEFINE_CASE(TEXTURE_OP_NORMAL
, "normal");
953 DEFINE_CASE(TEXTURE_OP_TEXEL_FETCH
, "texelfetch");
956 printf("op_%d", format
);
964 print_texture_word(uint32_t *word
, unsigned tabs
)
966 midgard_texture_word
*texture
= (midgard_texture_word
*) word
;
968 /* Instruction family, like ALU words have theirs */
971 /* Broad category of texture operation in question */
972 print_texture_op(texture
->op
);
974 /* Specific format in question */
975 print_texture_format(texture
->format
);
977 /* Instruction "modifiers" parallel the ALU instructions. First group
978 * are modifiers that act alone */
980 if (!texture
->filter
)
992 /* Second set are modifiers which take an extra argument each */
994 if (texture
->has_offset
)
1002 print_texture_reg(texture
->out_full
, texture
->out_reg_select
, texture
->out_upper
);
1003 print_mask(texture
->mask
);
1006 printf("texture%d, ", texture
->texture_handle
);
1008 printf("sampler%d", texture
->sampler_handle
);
1009 print_swizzle(texture
->swizzle
);
1012 print_texture_reg(/*texture->in_reg_full*/true, texture
->in_reg_select
, texture
->in_reg_upper
);
1013 printf(".%c%c, ", "xyzw"[texture
->in_reg_swizzle_left
],
1014 "xyzw"[texture
->in_reg_swizzle_right
]);
1016 /* TODO: can offsets be full words? */
1017 if (texture
->has_offset
) {
1018 print_texture_reg(false, texture
->offset_reg_select
, texture
->offset_reg_upper
);
1023 printf("%f, ", texture
->bias
/ 256.0f
);
1027 /* While not zero in general, for these simple instructions the
1028 * following unknowns are zero, so we don't include them */
1030 if (texture
->unknown1
||
1031 texture
->unknown2
||
1032 texture
->unknown3
||
1033 texture
->unknown4
||
1034 texture
->unknownA
||
1035 texture
->unknownB
||
1036 texture
->unknown8
||
1037 texture
->unknown9
) {
1038 printf("// unknown1 = 0x%x\n", texture
->unknown1
);
1039 printf("// unknown2 = 0x%x\n", texture
->unknown2
);
1040 printf("// unknown3 = 0x%x\n", texture
->unknown3
);
1041 printf("// unknown4 = 0x%x\n", texture
->unknown4
);
1042 printf("// unknownA = 0x%x\n", texture
->unknownA
);
1043 printf("// unknownB = 0x%x\n", texture
->unknownB
);
1044 printf("// unknown8 = 0x%x\n", texture
->unknown8
);
1045 printf("// unknown9 = 0x%x\n", texture
->unknown9
);
1048 /* Similarly, if no offset is applied, these are zero. If an offset
1049 * -is- applied, or gradients are used, etc, these are nonzero but
1050 * largely unknown still. */
1052 if (texture
->offset_unknown1
||
1053 texture
->offset_reg_select
||
1054 texture
->offset_reg_upper
||
1055 texture
->offset_unknown4
||
1056 texture
->offset_unknown5
||
1057 texture
->offset_unknown6
||
1058 texture
->offset_unknown7
||
1059 texture
->offset_unknown8
||
1060 texture
->offset_unknown9
) {
1061 printf("// offset_unknown1 = 0x%x\n", texture
->offset_unknown1
);
1062 printf("// offset_reg_select = 0x%x\n", texture
->offset_reg_select
);
1063 printf("// offset_reg_upper = 0x%x\n", texture
->offset_reg_upper
);
1064 printf("// offset_unknown4 = 0x%x\n", texture
->offset_unknown4
);
1065 printf("// offset_unknown5 = 0x%x\n", texture
->offset_unknown5
);
1066 printf("// offset_unknown6 = 0x%x\n", texture
->offset_unknown6
);
1067 printf("// offset_unknown7 = 0x%x\n", texture
->offset_unknown7
);
1068 printf("// offset_unknown8 = 0x%x\n", texture
->offset_unknown8
);
1069 printf("// offset_unknown9 = 0x%x\n", texture
->offset_unknown9
);
1073 if (texture
->unknown7
!= 0x1)
1074 printf("// (!) unknown7 = %d\n", texture
->unknown7
);
1078 disassemble_midgard(uint8_t *code
, size_t size
)
1080 uint32_t *words
= (uint32_t *) code
;
1081 unsigned num_words
= size
/ 4;
1084 bool prefetch_flag
= false;
1088 while (i
< num_words
) {
1089 unsigned num_quad_words
= midgard_word_size
[words
[i
] & 0xF];
1091 switch (midgard_word_types
[words
[i
] & 0xF]) {
1092 case midgard_word_type_texture
:
1093 print_texture_word(&words
[i
], tabs
);
1096 case midgard_word_type_load_store
:
1097 print_load_store_word(&words
[i
], tabs
);
1100 case midgard_word_type_alu
:
1101 print_alu_word(&words
[i
], num_quad_words
, tabs
);
1106 /* Reset word static analysis state */
1107 is_embedded_constant_half
= false;
1108 is_embedded_constant_int
= false;
1113 printf("Unknown word type %u:\n", words
[i
] & 0xF);
1115 print_quad_word(&words
[i
], tabs
);
1122 unsigned next
= (words
[i
] & 0xF0) >> 4;
1124 i
+= 4 * num_quad_words
;
1126 /* Break based on instruction prefetch flag */
1128 if (i
< num_words
&& next
== 1) {
1129 prefetch_flag
= true;
1131 if (midgard_word_types
[words
[i
] & 0xF] != midgard_word_type_alu
)