2 * Copyright © 2012 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
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
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
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 #include "util/ralloc.h"
29 #include "brw_gen_enum.h"
32 test_compact_instruction(struct brw_codegen
*p
, brw_inst src
)
35 memset(&dst
, 0xd0, sizeof(dst
));
37 if (brw_try_compact_instruction(p
->devinfo
, &dst
, &src
)) {
40 brw_uncompact_instruction(p
->devinfo
, &uncompacted
, &dst
);
41 if (memcmp(&uncompacted
, &src
, sizeof(src
))) {
42 brw_debug_compact_uncompact(p
->devinfo
, &src
, &uncompacted
);
46 brw_compact_inst unchanged
;
47 memset(&unchanged
, 0xd0, sizeof(unchanged
));
48 /* It's not supposed to change dst unless it compacted. */
49 if (memcmp(&unchanged
, &dst
, sizeof(dst
))) {
50 fprintf(stderr
, "Failed to compact, but dst changed\n");
51 fprintf(stderr
, " Instruction: ");
52 brw_disassemble_inst(stderr
, p
->devinfo
, &src
, false, 0, NULL
);
61 * When doing fuzz testing, pad bits won't round-trip.
63 * This sort of a superset of skip_bit, which is testing for changing bits that
64 * aren't worth testing for fuzzing. We also just want to clear bits that
65 * become meaningless once fuzzing twiddles a related bit.
68 clear_pad_bits(const struct gen_device_info
*devinfo
, brw_inst
*inst
)
70 if (brw_inst_opcode(devinfo
, inst
) != BRW_OPCODE_SEND
&&
71 brw_inst_opcode(devinfo
, inst
) != BRW_OPCODE_SENDC
&&
72 brw_inst_src0_reg_file(devinfo
, inst
) != BRW_IMMEDIATE_VALUE
&&
73 brw_inst_src1_reg_file(devinfo
, inst
) != BRW_IMMEDIATE_VALUE
) {
74 brw_inst_set_bits(inst
, 127, 111, 0);
77 if (devinfo
->gen
== 8 && !devinfo
->is_cherryview
&&
78 is_3src(devinfo
, brw_inst_opcode(devinfo
, inst
))) {
79 brw_inst_set_bits(inst
, 105, 105, 0);
80 brw_inst_set_bits(inst
, 84, 84, 0);
81 brw_inst_set_bits(inst
, 36, 35, 0);
86 skip_bit(const struct gen_device_info
*devinfo
, brw_inst
*src
, int bit
)
92 /* The compact bit -- uncompacted can't have it set. */
96 if (is_3src(devinfo
, brw_inst_opcode(devinfo
, src
))) {
97 if (devinfo
->gen
>= 9 || devinfo
->is_cherryview
) {
101 if (bit
>= 126 && bit
<= 127)
110 if (bit
>= 35 && bit
<= 36)
117 if (devinfo
->gen
>= 8) {
124 if (devinfo
->gen
< 7 && bit
== 90)
127 if (bit
>= 91 && bit
<= 95)
132 /* sometimes these are pad bits. */
133 if (brw_inst_opcode(devinfo
, src
) != BRW_OPCODE_SEND
&&
134 brw_inst_opcode(devinfo
, src
) != BRW_OPCODE_SENDC
&&
135 brw_inst_src0_reg_file(devinfo
, src
) != BRW_IMMEDIATE_VALUE
&&
136 brw_inst_src1_reg_file(devinfo
, src
) != BRW_IMMEDIATE_VALUE
&&
145 test_fuzz_compact_instruction(struct brw_codegen
*p
, brw_inst src
)
147 for (int bit0
= 0; bit0
< 128; bit0
++) {
148 if (skip_bit(p
->devinfo
, &src
, bit0
))
151 for (int bit1
= 0; bit1
< 128; bit1
++) {
152 brw_inst instr
= src
;
153 uint64_t *bits
= instr
.data
;
155 if (skip_bit(p
->devinfo
, &src
, bit1
))
158 bits
[bit0
/ 64] ^= (1ull << (bit0
& 63));
159 bits
[bit1
/ 64] ^= (1ull << (bit1
& 63));
161 clear_pad_bits(p
->devinfo
, &instr
);
163 if (!brw_validate_instruction(p
->devinfo
, &instr
, 0, NULL
))
166 if (!test_compact_instruction(p
, instr
)) {
167 printf(" twiddled bits for fuzzing %d, %d\n", bit0
, bit1
);
177 gen_ADD_GRF_GRF_GRF(struct brw_codegen
*p
)
179 struct brw_reg g0
= brw_vec8_grf(0, 0);
180 struct brw_reg g2
= brw_vec8_grf(2, 0);
181 struct brw_reg g4
= brw_vec8_grf(4, 0);
183 brw_ADD(p
, g0
, g2
, g4
);
187 gen_ADD_GRF_GRF_IMM(struct brw_codegen
*p
)
189 struct brw_reg g0
= brw_vec8_grf(0, 0);
190 struct brw_reg g2
= brw_vec8_grf(2, 0);
192 brw_ADD(p
, g0
, g2
, brw_imm_f(1.0));
196 gen_ADD_GRF_GRF_IMM_d(struct brw_codegen
*p
)
198 struct brw_reg g0
= retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_D
);
199 struct brw_reg g2
= retype(brw_vec8_grf(2, 0), BRW_REGISTER_TYPE_D
);
201 brw_ADD(p
, g0
, g2
, brw_imm_d(1));
205 gen_MOV_GRF_GRF(struct brw_codegen
*p
)
207 struct brw_reg g0
= brw_vec8_grf(0, 0);
208 struct brw_reg g2
= brw_vec8_grf(2, 0);
214 gen_ADD_MRF_GRF_GRF(struct brw_codegen
*p
)
216 struct brw_reg m6
= brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, 6, 0);
217 struct brw_reg g2
= brw_vec8_grf(2, 0);
218 struct brw_reg g4
= brw_vec8_grf(4, 0);
220 brw_ADD(p
, m6
, g2
, g4
);
224 gen_ADD_vec1_GRF_GRF_GRF(struct brw_codegen
*p
)
226 struct brw_reg g0
= brw_vec1_grf(0, 0);
227 struct brw_reg g2
= brw_vec1_grf(2, 0);
228 struct brw_reg g4
= brw_vec1_grf(4, 0);
230 brw_ADD(p
, g0
, g2
, g4
);
234 gen_PLN_MRF_GRF_GRF(struct brw_codegen
*p
)
236 struct brw_reg m6
= brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE
, 6, 0);
237 struct brw_reg interp
= brw_vec1_grf(2, 0);
238 struct brw_reg g4
= brw_vec8_grf(4, 0);
240 brw_PLN(p
, m6
, interp
, g4
);
244 gen_f0_0_MOV_GRF_GRF(struct brw_codegen
*p
)
246 struct brw_reg g0
= brw_vec8_grf(0, 0);
247 struct brw_reg g2
= brw_vec8_grf(2, 0);
249 brw_push_insn_state(p
);
250 brw_set_default_predicate_control(p
, BRW_PREDICATE_NORMAL
);
252 brw_pop_insn_state(p
);
255 /* The handling of f0.1 vs f0.0 changes between gen6 and gen7. Explicitly test
256 * it, so that we run the fuzzing can run over all the other bits that might
260 gen_f0_1_MOV_GRF_GRF(struct brw_codegen
*p
)
262 struct brw_reg g0
= brw_vec8_grf(0, 0);
263 struct brw_reg g2
= brw_vec8_grf(2, 0);
265 brw_push_insn_state(p
);
266 brw_set_default_predicate_control(p
, BRW_PREDICATE_NORMAL
);
267 brw_inst
*mov
= brw_MOV(p
, g0
, g2
);
268 brw_inst_set_flag_subreg_nr(p
->devinfo
, mov
, 1);
269 brw_pop_insn_state(p
);
273 void (*func
)(struct brw_codegen
*p
);
276 { gen_MOV_GRF_GRF
, GEN_ALL
},
277 { gen_ADD_GRF_GRF_GRF
, GEN_ALL
},
278 { gen_ADD_GRF_GRF_IMM
, GEN_ALL
},
279 { gen_ADD_GRF_GRF_IMM_d
, GEN_ALL
},
280 { gen_ADD_MRF_GRF_GRF
, GEN_LE(GEN6
) },
281 { gen_ADD_vec1_GRF_GRF_GRF
, GEN_ALL
},
282 { gen_PLN_MRF_GRF_GRF
, GEN_LE(GEN6
) },
283 { gen_f0_0_MOV_GRF_GRF
, GEN_ALL
},
284 { gen_f0_1_MOV_GRF_GRF
, GEN_ALL
},
288 run_tests(const struct gen_device_info
*devinfo
)
292 for (unsigned i
= 0; i
< ARRAY_SIZE(tests
); i
++) {
293 if ((tests
[i
].gens
& gen_from_devinfo(devinfo
)) == 0)
296 for (int align_16
= 0; align_16
<= 1; align_16
++) {
297 /* Align16 support is not present on Gen11+ */
298 if (devinfo
->gen
>= 11 && align_16
)
301 struct brw_codegen
*p
= rzalloc(NULL
, struct brw_codegen
);
302 brw_init_codegen(devinfo
, p
, p
);
304 brw_set_default_predicate_control(p
, BRW_PREDICATE_NONE
);
306 brw_set_default_access_mode(p
, BRW_ALIGN_16
);
308 brw_set_default_access_mode(p
, BRW_ALIGN_1
);
311 assert(p
->nr_insn
== 1);
313 if (!test_compact_instruction(p
, p
->store
[0])) {
318 if (!test_fuzz_compact_instruction(p
, p
->store
[0])) {
331 main(int argc
, char **argv
)
333 struct gen_device_info
*devinfo
= (struct gen_device_info
*)calloc(1, sizeof(*devinfo
));
336 for (devinfo
->gen
= 5; devinfo
->gen
<= 12; devinfo
->gen
++) {
337 fail
|= run_tests(devinfo
);