i965: split EU defines to brw_eu_defines.h
[mesa.git] / src / mesa / drivers / dri / i965 / test_eu_compact.c
1 /*
2 * Copyright © 2012 Intel Corporation
3 *
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:
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
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
21 * IN THE SOFTWARE.
22 */
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdbool.h>
27 #include "util/ralloc.h"
28 #include "brw_eu.h"
29
30 static bool
31 test_compact_instruction(struct brw_codegen *p, brw_inst src)
32 {
33 brw_compact_inst dst;
34 memset(&dst, 0xd0, sizeof(dst));
35
36 if (brw_try_compact_instruction(p->devinfo, &dst, &src)) {
37 brw_inst uncompacted;
38
39 brw_uncompact_instruction(p->devinfo, &uncompacted, &dst);
40 if (memcmp(&uncompacted, &src, sizeof(src))) {
41 brw_debug_compact_uncompact(p->devinfo, &src, &uncompacted);
42 return false;
43 }
44 } else {
45 brw_compact_inst unchanged;
46 memset(&unchanged, 0xd0, sizeof(unchanged));
47 /* It's not supposed to change dst unless it compacted. */
48 if (memcmp(&unchanged, &dst, sizeof(dst))) {
49 fprintf(stderr, "Failed to compact, but dst changed\n");
50 fprintf(stderr, " Instruction: ");
51 brw_disassemble_inst(stderr, p->devinfo, &src, false);
52 return false;
53 }
54 }
55
56 return true;
57 }
58
59 /**
60 * When doing fuzz testing, pad bits won't round-trip.
61 *
62 * This sort of a superset of skip_bit, which is testing for changing bits that
63 * aren't worth testing for fuzzing. We also just want to clear bits that
64 * become meaningless once fuzzing twiddles a related bit.
65 */
66 static void
67 clear_pad_bits(const struct gen_device_info *devinfo, brw_inst *inst)
68 {
69 if (brw_inst_opcode(devinfo, inst) != BRW_OPCODE_SEND &&
70 brw_inst_opcode(devinfo, inst) != BRW_OPCODE_SENDC &&
71 brw_inst_opcode(devinfo, inst) != BRW_OPCODE_BREAK &&
72 brw_inst_opcode(devinfo, inst) != BRW_OPCODE_CONTINUE &&
73 brw_inst_src0_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE &&
74 brw_inst_src1_reg_file(devinfo, inst) != BRW_IMMEDIATE_VALUE) {
75 brw_inst_set_bits(inst, 127, 111, 0);
76 }
77 }
78
79 static bool
80 skip_bit(const struct gen_device_info *devinfo, brw_inst *src, int bit)
81 {
82 /* pad bit */
83 if (bit == 7)
84 return true;
85
86 /* The compact bit -- uncompacted can't have it set. */
87 if (bit == 29)
88 return true;
89
90 /* pad bit */
91 if (bit == 47)
92 return true;
93
94 /* pad bits */
95 if (bit >= 90 && bit <= 95)
96 return true;
97
98 /* sometimes these are pad bits. */
99 if (brw_inst_opcode(devinfo, src) != BRW_OPCODE_SEND &&
100 brw_inst_opcode(devinfo, src) != BRW_OPCODE_SENDC &&
101 brw_inst_opcode(devinfo, src) != BRW_OPCODE_BREAK &&
102 brw_inst_opcode(devinfo, src) != BRW_OPCODE_CONTINUE &&
103 brw_inst_src0_reg_file(devinfo, src) != BRW_IMMEDIATE_VALUE &&
104 brw_inst_src1_reg_file(devinfo, src) != BRW_IMMEDIATE_VALUE &&
105 bit >= 121) {
106 return true;
107 }
108
109 return false;
110 }
111
112 static bool
113 test_fuzz_compact_instruction(struct brw_codegen *p, brw_inst src)
114 {
115 for (int bit0 = 0; bit0 < 128; bit0++) {
116 if (skip_bit(p->devinfo, &src, bit0))
117 continue;
118
119 for (int bit1 = 0; bit1 < 128; bit1++) {
120 brw_inst instr = src;
121 uint32_t *bits = (uint32_t *)&instr;
122
123 if (skip_bit(p->devinfo, &src, bit1))
124 continue;
125
126 bits[bit0 / 32] ^= (1 << (bit0 & 31));
127 bits[bit1 / 32] ^= (1 << (bit1 & 31));
128
129 clear_pad_bits(p->devinfo, &instr);
130
131 if (!test_compact_instruction(p, instr)) {
132 printf(" twiddled bits for fuzzing %d, %d\n", bit0, bit1);
133 return false;
134 }
135 }
136 }
137
138 return true;
139 }
140
141 static void
142 gen_ADD_GRF_GRF_GRF(struct brw_codegen *p)
143 {
144 struct brw_reg g0 = brw_vec8_grf(0, 0);
145 struct brw_reg g2 = brw_vec8_grf(2, 0);
146 struct brw_reg g4 = brw_vec8_grf(4, 0);
147
148 brw_ADD(p, g0, g2, g4);
149 }
150
151 static void
152 gen_ADD_GRF_GRF_IMM(struct brw_codegen *p)
153 {
154 struct brw_reg g0 = brw_vec8_grf(0, 0);
155 struct brw_reg g2 = brw_vec8_grf(2, 0);
156
157 brw_ADD(p, g0, g2, brw_imm_f(1.0));
158 }
159
160 static void
161 gen_ADD_GRF_GRF_IMM_d(struct brw_codegen *p)
162 {
163 struct brw_reg g0 = retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_D);
164 struct brw_reg g2 = retype(brw_vec8_grf(2, 0), BRW_REGISTER_TYPE_D);
165
166 brw_ADD(p, g0, g2, brw_imm_d(1));
167 }
168
169 static void
170 gen_MOV_GRF_GRF(struct brw_codegen *p)
171 {
172 struct brw_reg g0 = brw_vec8_grf(0, 0);
173 struct brw_reg g2 = brw_vec8_grf(2, 0);
174
175 brw_MOV(p, g0, g2);
176 }
177
178 static void
179 gen_ADD_MRF_GRF_GRF(struct brw_codegen *p)
180 {
181 struct brw_reg m6 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 6, 0);
182 struct brw_reg g2 = brw_vec8_grf(2, 0);
183 struct brw_reg g4 = brw_vec8_grf(4, 0);
184
185 brw_ADD(p, m6, g2, g4);
186 }
187
188 static void
189 gen_ADD_vec1_GRF_GRF_GRF(struct brw_codegen *p)
190 {
191 struct brw_reg g0 = brw_vec1_grf(0, 0);
192 struct brw_reg g2 = brw_vec1_grf(2, 0);
193 struct brw_reg g4 = brw_vec1_grf(4, 0);
194
195 brw_ADD(p, g0, g2, g4);
196 }
197
198 static void
199 gen_PLN_MRF_GRF_GRF(struct brw_codegen *p)
200 {
201 struct brw_reg m6 = brw_vec8_reg(BRW_MESSAGE_REGISTER_FILE, 6, 0);
202 struct brw_reg interp = brw_vec1_grf(2, 0);
203 struct brw_reg g4 = brw_vec8_grf(4, 0);
204
205 brw_PLN(p, m6, interp, g4);
206 }
207
208 static void
209 gen_f0_0_MOV_GRF_GRF(struct brw_codegen *p)
210 {
211 struct brw_reg g0 = brw_vec8_grf(0, 0);
212 struct brw_reg g2 = brw_vec8_grf(2, 0);
213
214 brw_push_insn_state(p);
215 brw_set_default_predicate_control(p, true);
216 brw_MOV(p, g0, g2);
217 brw_pop_insn_state(p);
218 }
219
220 /* The handling of f0.1 vs f0.0 changes between gen6 and gen7. Explicitly test
221 * it, so that we run the fuzzing can run over all the other bits that might
222 * interact with it.
223 */
224 static void
225 gen_f0_1_MOV_GRF_GRF(struct brw_codegen *p)
226 {
227 struct brw_reg g0 = brw_vec8_grf(0, 0);
228 struct brw_reg g2 = brw_vec8_grf(2, 0);
229
230 brw_push_insn_state(p);
231 brw_set_default_predicate_control(p, true);
232 brw_inst *mov = brw_MOV(p, g0, g2);
233 brw_inst_set_flag_subreg_nr(p->devinfo, mov, 1);
234 brw_pop_insn_state(p);
235 }
236
237 struct {
238 void (*func)(struct brw_codegen *p);
239 } tests[] = {
240 { gen_MOV_GRF_GRF },
241 { gen_ADD_GRF_GRF_GRF },
242 { gen_ADD_GRF_GRF_IMM },
243 { gen_ADD_GRF_GRF_IMM_d },
244 { gen_ADD_MRF_GRF_GRF },
245 { gen_ADD_vec1_GRF_GRF_GRF },
246 { gen_PLN_MRF_GRF_GRF },
247 { gen_f0_0_MOV_GRF_GRF },
248 { gen_f0_1_MOV_GRF_GRF },
249 };
250
251 static bool
252 run_tests(const struct gen_device_info *devinfo)
253 {
254 brw_init_compaction_tables(devinfo);
255 bool fail = false;
256
257 for (int i = 0; i < ARRAY_SIZE(tests); i++) {
258 for (int align_16 = 0; align_16 <= 1; align_16++) {
259 struct brw_codegen *p = rzalloc(NULL, struct brw_codegen);
260 brw_init_codegen(devinfo, p, p);
261
262 brw_set_default_predicate_control(p, BRW_PREDICATE_NONE);
263 if (align_16)
264 brw_set_default_access_mode(p, BRW_ALIGN_16);
265 else
266 brw_set_default_access_mode(p, BRW_ALIGN_1);
267
268 tests[i].func(p);
269 assert(p->nr_insn == 1);
270
271 if (!test_compact_instruction(p, p->store[0])) {
272 fail = true;
273 continue;
274 }
275
276 if (!test_fuzz_compact_instruction(p, p->store[0])) {
277 fail = true;
278 continue;
279 }
280
281 ralloc_free(p);
282 }
283 }
284
285 return fail;
286 }
287
288 int
289 main(int argc, char **argv)
290 {
291 struct gen_device_info *devinfo = calloc(1, sizeof(*devinfo));
292 devinfo->gen = 6;
293 bool fail = false;
294
295 for (devinfo->gen = 6; devinfo->gen <= 7; devinfo->gen++) {
296 fail |= run_tests(devinfo);
297 }
298
299 return fail;
300 }