1
2 #include "../sfn_instr_alu.h"
3 #include "../sfn_instr_export.h"
4 #include "../sfn_instr_fetch.h"
5 #include "../sfn_instr_lds.h"
6 #include "../sfn_instr_mem.h"
7 #include "../sfn_instr_tex.h"
8 #include "../sfn_instrfactory.h"
9
10 #include "gtest/gtest.h"
11 #include <sstream>
12
13 namespace r600 {
14
15 using std::istringstream;
16 using std::ostringstream;
17 using std::string;
18
19 class TestInstrFromString : public ::testing::Test {
20 public:
21 TestInstrFromString();
22
23 PInst from_string(const std::string& s);
24
25 protected:
26 void add_dest_from_string(const char *init);
27 void add_dest_vec4_from_string(const char *init);
28
29 void check(const Instr& eval, const Instr& expect);
30 void check(const string& init, const Instr& expect);
31
32 void SetUp() override;
33 void TearDown() override;
34
35 InstrFactory *m_instr_factory{nullptr};
36 };
37
TEST_F(TestInstrFromString,test_alu_mov)38 TEST_F(TestInstrFromString, test_alu_mov)
39 {
40 add_dest_from_string("R1999.x");
41
42 AluInstr expect(op1_mov,
43 new Register(2000, 1, pin_none),
44 new Register(1999, 0, pin_none),
45 {alu_write, alu_last_instr});
46
47 check("ALU MOV R2000.y : R1999.x {WL}", expect);
48 }
49
TEST_F(TestInstrFromString,test_alu_lds_read_ret)50 TEST_F(TestInstrFromString, test_alu_lds_read_ret)
51 {
52 add_dest_from_string("R1999.x");
53
54 AluInstr expect(DS_OP_READ_RET, {new Register(1999, 0, pin_none)}, {});
55
56 check("ALU LDS READ_RET __.x : R1999.x {}", expect);
57 }
58
TEST_F(TestInstrFromString,test_alu_mov_literal)59 TEST_F(TestInstrFromString, test_alu_mov_literal)
60 {
61 AluInstr expect(op1_mov,
62 new Register(2000, 1, pin_none),
63 new LiteralConstant(0x10),
64 {alu_write, alu_last_instr});
65
66 check("ALU MOV R2000.y : L[0x10] {WL}", expect);
67 }
68
TEST_F(TestInstrFromString,test_alu_mov_neg)69 TEST_F(TestInstrFromString, test_alu_mov_neg)
70 {
71 add_dest_from_string("R1999.x");
72 AluInstr expect(op1_mov,
73 new Register(2000, 1, pin_none),
74 new Register(1999, 0, pin_none),
75 {alu_write, alu_last_instr});
76 expect.set_source_mod(0, AluInstr::mod_neg);
77
78 check("ALU MOV R2000.y : -R1999.x {WL}", expect);
79 }
80
TEST_F(TestInstrFromString,test_alu_mov_abs)81 TEST_F(TestInstrFromString, test_alu_mov_abs)
82 {
83 add_dest_from_string("R1999.x");
84 AluInstr expect(op1_mov,
85 new Register(2000, 1, pin_none),
86 new Register(1999, 0, pin_none),
87 {alu_write, alu_last_instr});
88 expect.set_source_mod(0, AluInstr::mod_abs);
89
90 check("ALU MOV R2000.y : |R1999.x| {WL}", expect);
91 }
92
TEST_F(TestInstrFromString,test_alu_mov_neg_abs)93 TEST_F(TestInstrFromString, test_alu_mov_neg_abs)
94 {
95 add_dest_from_string("R1999.x");
96 AluInstr expect(op1_mov,
97 new Register(2000, 1, pin_none),
98 new Register(1999, 0, pin_none),
99 {alu_write});
100 expect.set_source_mod(0, AluInstr::mod_abs);
101 expect.set_source_mod(0, AluInstr::mod_neg);
102
103 check("ALU MOV R2000.y : -|R1999.x| {W}", expect);
104 }
105
TEST_F(TestInstrFromString,test_alu_add)106 TEST_F(TestInstrFromString, test_alu_add)
107 {
108 add_dest_from_string("R1998.z");
109 add_dest_from_string("R1999.w");
110
111 AluInstr expect(op2_add,
112 new Register(2000, 1, pin_none),
113 new Register(1999, 3, pin_none),
114 new Register(1998, 2, pin_none),
115 {alu_last_instr});
116 check("ALU ADD __.y : R1999.w R1998.z {L}", expect);
117 }
118
TEST_F(TestInstrFromString,test_alu_add_clmap)119 TEST_F(TestInstrFromString, test_alu_add_clmap)
120 {
121 add_dest_from_string("R1998.z");
122 add_dest_from_string("R1999.w");
123 AluInstr expect(op2_add,
124 new Register(2000, 1, pin_none),
125 new Register(1999, 3, pin_none),
126 new Register(1998, 2, pin_none),
127 {alu_last_instr, alu_dst_clamp});
128 check("ALU ADD CLAMP __.y : R1999.w R1998.z {L}", expect);
129 }
130
TEST_F(TestInstrFromString,test_alu_add_neg2)131 TEST_F(TestInstrFromString, test_alu_add_neg2)
132 {
133 add_dest_from_string("R1998.z");
134 add_dest_from_string("R1999.w");
135 AluInstr expect(op2_add,
136 new Register(2000, 1, pin_none),
137 new Register(1999, 3, pin_none),
138 new Register(1998, 2, pin_none),
139 {alu_last_instr});
140 expect.set_source_mod(1, AluInstr::mod_neg);
141
142 check("ALU ADD __.y : R1999.w -R1998.z {L}", expect);
143 }
144
TEST_F(TestInstrFromString,test_alu_sete_update_pref)145 TEST_F(TestInstrFromString, test_alu_sete_update_pref)
146 {
147 add_dest_from_string("R1998.z");
148 add_dest_from_string("R1999.w");
149 AluInstr expect(op2_sete,
150 new Register(2000, 1, pin_none),
151 new Register(1999, 3, pin_none),
152 new Register(1998, 2, pin_none),
153 {alu_last_instr, alu_update_pred});
154 expect.set_source_mod(1, AluInstr::mod_neg);
155 check("ALU SETE __.y : R1999.w -R1998.z {LP}", expect);
156 }
157
TEST_F(TestInstrFromString,test_alu_sete_update_pref_empty_dest)158 TEST_F(TestInstrFromString, test_alu_sete_update_pref_empty_dest)
159 {
160 add_dest_from_string("R1998.z");
161 add_dest_from_string("R1999.w");
162 AluInstr expect(op2_sete,
163 new Register(2000, 0, pin_none),
164 new Register(1999, 3, pin_none),
165 new Register(1998, 2, pin_none),
166 {alu_last_instr, alu_update_pred});
167 check("ALU SETE __.x : R1999.w R1998.z {LP}", expect);
168 }
169
TEST_F(TestInstrFromString,test_alu_setne_update_exec)170 TEST_F(TestInstrFromString, test_alu_setne_update_exec)
171 {
172 add_dest_from_string("R1998.z");
173 add_dest_from_string("R1999.w");
174 AluInstr expect(op2_setne,
175 new Register(2000, 1, pin_none),
176 new Register(1999, 3, pin_none),
177 new Register(1998, 2, pin_none),
178 {alu_last_instr, alu_update_exec});
179 expect.set_source_mod(1, AluInstr::mod_neg);
180 check("ALU SETNE __.y : R1999.w -R1998.z {LE}", expect);
181 }
182
TEST_F(TestInstrFromString,test_alu_add_abs2)183 TEST_F(TestInstrFromString, test_alu_add_abs2)
184 {
185 add_dest_from_string("R1998.z");
186 add_dest_from_string("R1999.w");
187 AluInstr expect(op2_add,
188 new Register(2000, 1, pin_none),
189 new Register(1999, 3, pin_none),
190 new Register(1998, 2, pin_none),
191 {alu_write, alu_last_instr});
192 expect.set_source_mod(1, AluInstr::mod_abs);
193 check("ALU ADD R2000.y : R1999.w |R1998.z| {WL}", expect);
194 }
195
TEST_F(TestInstrFromString,test_alu_add_abs2_neg2)196 TEST_F(TestInstrFromString, test_alu_add_abs2_neg2)
197 {
198 add_dest_from_string("R1998.z");
199 add_dest_from_string("R1999.w");
200 AluInstr expect(op2_add,
201 new Register(2000, 1, pin_none),
202 new Register(1999, 3, pin_none),
203 new Register(1998, 2, pin_none),
204 {alu_write, alu_last_instr});
205 expect.set_source_mod(1, AluInstr::mod_neg);
206 expect.set_source_mod(1, AluInstr::mod_abs);
207
208 check("ALU ADD R2000.y : R1999.w -|R1998.z| {WL}", expect);
209 }
210
TEST_F(TestInstrFromString,test_alu_muladd)211 TEST_F(TestInstrFromString, test_alu_muladd)
212 {
213 add_dest_from_string("R1998.z");
214 add_dest_from_string("R1999.w");
215 add_dest_from_string("R2000.y");
216 AluInstr expect(op3_muladd_ieee,
217 new Register(2000, 1, pin_none),
218 new Register(1999, 3, pin_none),
219 new Register(1998, 2, pin_none),
220 new Register(2000, 1, pin_none),
221 {alu_write, alu_last_instr});
222 check("ALU MULADD_IEEE R2000.y : R1999.w R1998.z R2000.y {WL}", expect);
223 }
224
TEST_F(TestInstrFromString,test_alu_muladd_neg3)225 TEST_F(TestInstrFromString, test_alu_muladd_neg3)
226 {
227 add_dest_from_string("R1998.z");
228 add_dest_from_string("R1999.w");
229 add_dest_from_string("R2000.y");
230 AluInstr expect(op3_muladd_ieee,
231 new Register(2000, 1, pin_none),
232 new Register(1999, 3, pin_none),
233 new Register(1998, 2, pin_none),
234 new Register(2000, 1, pin_none),
235 {alu_last_instr});
236 check("ALU MULADD_IEEE __.y : R1999.w R1998.z -R2000.y {L}", expect);
237 }
238
TEST_F(TestInstrFromString,test_alu_mov_bs)239 TEST_F(TestInstrFromString, test_alu_mov_bs)
240 {
241 add_dest_from_string("R1999.x");
242 for (auto& [expect_bs, str] : AluInstr::bank_swizzle_map) {
243 auto init = std::string("ALU MOV R2000.y : R1999.x {WL} ") + str;
244
245 AluInstr expect(op1_mov,
246 new Register(2000, 1, pin_none),
247 new Register(1999, 0, pin_none),
248 {alu_write, alu_last_instr});
249 expect.set_bank_swizzle(expect_bs);
250
251 check(init, expect);
252 }
253 }
254
TEST_F(TestInstrFromString,test_alu_dot4_ieee)255 TEST_F(TestInstrFromString, test_alu_dot4_ieee)
256 {
257 add_dest_from_string("R199.x");
258 add_dest_from_string("R199.y");
259 add_dest_from_string("R199.z");
260 add_dest_from_string("R199.w");
261 add_dest_from_string("R198.x");
262 add_dest_from_string("R198.y");
263 add_dest_from_string("R198.z");
264 add_dest_from_string("R198.w");
265 auto init = std::string("ALU DOT4_IEEE R2000.y : R199.x R198.w + R199.y R198.z + "
266 "R199.z R198.y + R199.w R198.x {WL}");
267
268 AluInstr expect(op2_dot4_ieee,
269 new Register(2000, 1, pin_none),
270 {new Register(199, 0, pin_none),
271 new Register(198, 3, pin_none),
272 new Register(199, 1, pin_none),
273 new Register(198, 2, pin_none),
274 new Register(199, 2, pin_none),
275 new Register(198, 1, pin_none),
276 new Register(199, 3, pin_none),
277 new Register(198, 0, pin_none)},
278 {alu_write, alu_last_instr},
279 4);
280
281 check(init, expect);
282 }
283
TEST_F(TestInstrFromString,test_alu_dot4_with_mods)284 TEST_F(TestInstrFromString, test_alu_dot4_with_mods)
285 {
286 add_dest_from_string("R199.x");
287 add_dest_from_string("R199.y");
288 add_dest_from_string("R199.z");
289 add_dest_from_string("R199.w");
290 add_dest_from_string("R198.x");
291 add_dest_from_string("R198.y");
292 add_dest_from_string("R198.z");
293 add_dest_from_string("R198.w");
294 auto init = std::string("ALU DOT4_IEEE R2000.y : -R199.x R198.w + R199.y |R198.z| + "
295 "-|R199.z| R198.y + -R199.w R198.x {WL}");
296
297 AluInstr expect(op2_dot4_ieee,
298 new Register(2000, 1, pin_none),
299 {new Register(199, 0, pin_none),
300 new Register(198, 3, pin_none),
301 new Register(199, 1, pin_none),
302 new Register(198, 2, pin_none),
303 new Register(199, 2, pin_none),
304 new Register(198, 1, pin_none),
305 new Register(199, 3, pin_none),
306 new Register(198, 0, pin_none)},
307 {alu_write, alu_last_instr},
308 4);
309
310 expect.set_source_mod(0, AluInstr::mod_neg);
311 expect.set_source_mod(3, AluInstr::mod_abs);
312 expect.set_source_mod(4, AluInstr::mod_neg);
313 expect.set_source_mod(4, AluInstr::mod_abs);
314 expect.set_source_mod(7, AluInstr::mod_neg);
315
316 check(init, expect);
317 auto instr = from_string(init);
318
319 std::ostringstream print_str;
320 print_str << *instr;
321 EXPECT_EQ(print_str.str(), init);
322
323 }
324
325
TEST_F(TestInstrFromString,test_alu_mov_cf)326 TEST_F(TestInstrFromString, test_alu_mov_cf)
327 {
328 add_dest_from_string("R1999.x");
329 for (auto& [expect_cf, str] : AluInstr::cf_map) {
330 auto init = std::string("ALU MOV R2000.y : R1999.x {WL} ") + str;
331
332 AluInstr expect(op1_mov,
333 new Register(2000, 1, pin_none),
334 new Register(1999, 0, pin_none),
335 {alu_write, alu_last_instr});
336 expect.set_cf_type(expect_cf);
337
338 check(init, expect);
339 }
340 }
341
TEST_F(TestInstrFromString,test_alu_interp_xy)342 TEST_F(TestInstrFromString, test_alu_interp_xy)
343 {
344 add_dest_from_string("R0.y@fully");
345 auto init =
346 std::string("ALU INTERP_ZW R1024.z@chan : R0.y@fully Param0.z {W} VEC_210");
347
348 auto r0y = new Register(0, 1, pin_fully);
349 r0y->set_flag(Register::pin_start);
350 AluInstr expect(op2_interp_zw,
351 new Register(1024, 2, pin_chan),
352 r0y,
353 new InlineConstant(ALU_SRC_PARAM_BASE, 2),
354 {alu_write});
355 expect.set_bank_swizzle(alu_vec_210);
356
357 check(init, expect);
358 }
359
TEST_F(TestInstrFromString,test_alu_interp_xy_no_write)360 TEST_F(TestInstrFromString, test_alu_interp_xy_no_write)
361 {
362 add_dest_from_string("R0.x@fully");
363 auto init = std::string("ALU INTERP_XY __.x@chan : R0.x@fully Param0.z {} VEC_210");
364
365 auto r0x = new Register(0, 0, pin_fully);
366 r0x->set_flag(Register::pin_start);
367
368 AluInstr expect(op2_interp_xy,
369 new Register(1024, 0, pin_chan),
370 r0x,
371 new InlineConstant(ALU_SRC_PARAM_BASE, 2),
372 {});
373 expect.set_bank_swizzle(alu_vec_210);
374
375 check(init, expect);
376 }
377
TEST_F(TestInstrFromString,test_alu_mov_cf_bs)378 TEST_F(TestInstrFromString, test_alu_mov_cf_bs)
379 {
380 add_dest_from_string("R1999.x");
381 auto init = std::string("ALU MOV R2000.y : R1999.x {WL} VEC_210 POP_AFTER");
382 AluInstr expect(op1_mov,
383 new Register(2000, 1, pin_none),
384 new Register(1999, 0, pin_none),
385 {alu_write, alu_last_instr});
386 expect.set_cf_type(cf_alu_pop_after);
387 expect.set_bank_swizzle(alu_vec_210);
388 check(init, expect);
389 }
390
TEST_F(TestInstrFromString,test_tex_sample_basic)391 TEST_F(TestInstrFromString, test_tex_sample_basic)
392 {
393 add_dest_vec4_from_string("R2000.xyzw");
394 auto init = std::string("TEX SAMPLE R1000.xyzw : R2000.xyzw RID:10 SID:1 NNNN");
395 TexInstr expect(
396 TexInstr::sample, RegisterVec4(1000), {0, 1, 2, 3}, RegisterVec4(2000), 10, nullptr, 1);
397 check(init, expect);
398 }
399
TEST_F(TestInstrFromString,test_tex_ld_basic)400 TEST_F(TestInstrFromString, test_tex_ld_basic)
401 {
402 add_dest_vec4_from_string("R2002.xyzw");
403 auto init = std::string("TEX LD R1001.xyzw : R2002.xyzw RID:27 SID:7 NNNN");
404 TexInstr expect(
405 TexInstr::ld, RegisterVec4(1001), {0, 1, 2, 3}, RegisterVec4(2002), 27, nullptr, 7);
406 check(init, expect);
407 }
408
TEST_F(TestInstrFromString,test_tex_sample_with_offset)409 TEST_F(TestInstrFromString, test_tex_sample_with_offset)
410 {
411 add_dest_vec4_from_string("R2002.xyzw");
412 auto init =
413 std::string("TEX SAMPLE R1001.xyzw : R2002.xyzw RID:27 SID:2 OX:1 OY:-2 OZ:5 NNNN");
414
415 TexInstr expect(
416 TexInstr::sample, RegisterVec4(1001), {0, 1, 2, 3}, RegisterVec4(2002), 27, nullptr, 2);
417 expect.set_offset(0, 1);
418 expect.set_offset(1, -2);
419 expect.set_offset(2, 5);
420
421 check(init, expect);
422 }
423
TEST_F(TestInstrFromString,test_tex_gather4_x)424 TEST_F(TestInstrFromString, test_tex_gather4_x)
425 {
426 add_dest_vec4_from_string("R2002.xyzw");
427 auto init =
428 std::string("TEX GATHER4 R1001.xyzw : R2002.xyzw RID:7 SID:27 MODE:0 NNNN");
429 TexInstr expect(
430 TexInstr::gather4, RegisterVec4(1001), {0, 1, 2, 3}, RegisterVec4(2002), 7, nullptr, 27);
431 check(init, expect);
432 }
433
TEST_F(TestInstrFromString,test_tex_gather4_y)434 TEST_F(TestInstrFromString, test_tex_gather4_y)
435 {
436 add_dest_vec4_from_string("R2002.xyzw");
437 auto init =
438 std::string("TEX GATHER4 R1001.xyzw : R2002.xyzw RID:7 SID:27 MODE:1 NNNN");
439 TexInstr expect(
440 TexInstr::gather4, RegisterVec4(1001), {0, 1, 2, 3}, RegisterVec4(2002), 7, nullptr, 27);
441 expect.set_gather_comp(1);
442 check(init, expect);
443 }
444
TEST_F(TestInstrFromString,test_tex_sampler_with_offset)445 TEST_F(TestInstrFromString, test_tex_sampler_with_offset)
446 {
447 add_dest_vec4_from_string("R2002.xyzw");
448 auto init =
449 std::string("TEX SAMPLE R1001.xyzw : R2002.xyzw RID:7 SID:27 SO:R200.z NNNN");
450 TexInstr expect(TexInstr::sample,
451 RegisterVec4(1001),
452 {0, 1, 2, 3},
453 RegisterVec4(2002),
454 7,
455 nullptr,
456 27,
457 new Register(200, 2, pin_none));
458 check(init, expect);
459 }
460
TEST_F(TestInstrFromString,test_export_param_60)461 TEST_F(TestInstrFromString, test_export_param_60)
462 {
463 add_dest_vec4_from_string("R1001.xyzw");
464
465 ExportInstr expect(ExportInstr::param, 60, RegisterVec4(1001));
466 check("EXPORT PARAM 60 R1001.xyzw", expect);
467 }
468
TEST_F(TestInstrFromString,test_export_pos_61)469 TEST_F(TestInstrFromString, test_export_pos_61)
470 {
471 add_dest_from_string("R1002.y@group");
472
473 ExportInstr expect(ExportInstr::pos, 61, RegisterVec4(1002, false, {1, 4, 5, 7}));
474 check("EXPORT POS 61 R1002.y01_", expect);
475 }
476
TEST_F(TestInstrFromString,test_export_last_pixel_0)477 TEST_F(TestInstrFromString, test_export_last_pixel_0)
478 {
479 add_dest_vec4_from_string("R1002.xyzw");
480
481 ExportInstr expect(ExportInstr::pixel, 0, RegisterVec4(1002, false, {2, 3, 0, 1}));
482 expect.set_is_last_export(true);
483 check("EXPORT_DONE PIXEL 0 R1002.zwxy", expect);
484 }
485
TEST_F(TestInstrFromString,test_fetch_basic)486 TEST_F(TestInstrFromString, test_fetch_basic)
487 {
488 add_dest_from_string("R201.z");
489
490 FetchInstr expect(vc_fetch,
491 RegisterVec4(1002),
492 {0, 4, 5, 1},
493 new Register(201, 2, pin_none),
494 0,
495 vertex_data,
496 fmt_8,
497 vtx_nf_norm,
498 vtx_es_none,
499 1,
500 nullptr);
501 expect.set_mfc(31);
502 expect.set_element_size(3);
503 check("VFETCH R1002.x01y : R201.z RID:1 VERTEX FMT(8,UNORM) MFC:31 ES:3", expect);
504 }
505
TEST_F(TestInstrFromString,test_query_buffer_size)506 TEST_F(TestInstrFromString, test_query_buffer_size)
507 {
508 QueryBufferSizeInstr expect(RegisterVec4(1002),
509 RegisterVec4::Swizzle({0, 1, 2, 3}),
510 1);
511 check("GET_BUF_RESINFO R1002.xyzw : RID:1", expect);
512
513 FetchInstr expect_fetch(vc_get_buf_resinfo,
514 RegisterVec4(1002),
515 RegisterVec4::Swizzle({0, 1, 2, 3}),
516 new Register(0, 7, pin_fully),
517 0,
518 no_index_offset,
519 fmt_32_32_32_32,
520 vtx_nf_norm,
521 vtx_es_none,
522 1,
523 nullptr);
524 expect_fetch.set_fetch_flag(FetchInstr::format_comp_signed);
525 check("GET_BUF_RESINFO R1002.xyzw : RID:1", expect_fetch);
526 }
527
TEST_F(TestInstrFromString,test_load_from_buffer)528 TEST_F(TestInstrFromString, test_load_from_buffer)
529 {
530 add_dest_from_string("R201.x");
531 add_dest_from_string("R202.x");
532 string init = "LOAD_BUF R200.xzwy : R201.x + 16b RID:10 + R202.x";
533 LoadFromBuffer expect(RegisterVec4(200),
534 RegisterVec4::Swizzle({0, 2, 3, 1}),
535 new Register(201, 0, pin_none),
536 16,
537 10,
538 new Register(202, 0, pin_none),
539 fmt_32_32_32_32_float);
540 check(init, expect);
541
542 auto instr = from_string(init);
543 FetchInstr expect_fetch(vc_fetch,
544 RegisterVec4(200),
545 RegisterVec4::Swizzle({0, 2, 3, 1}),
546 new Register(201, 0, pin_none),
547 16,
548 no_index_offset,
549 fmt_32_32_32_32_float,
550 vtx_nf_scaled,
551 vtx_es_none,
552 10,
553 new Register(202, 0, pin_none));
554 expect_fetch.set_fetch_flag(FetchInstr::format_comp_signed);
555 expect_fetch.set_mfc(16);
556 check(*instr, expect_fetch);
557 }
558
TEST_F(TestInstrFromString,test_load_from_scratch)559 TEST_F(TestInstrFromString, test_load_from_scratch)
560 {
561
562 add_dest_from_string("R201.x");
563 string init = "READ_SCRATCH R200.xzwy : R201.x SIZE:20 ES:3";
564
565 LoadFromScratch expect(RegisterVec4(200),
566 RegisterVec4::Swizzle({0, 2, 3, 1}),
567 new Register(201, 0, pin_none),
568 20);
569 check(init, expect);
570
571 FetchInstr expect_fetch(vc_read_scratch,
572 RegisterVec4(200),
573 RegisterVec4::Swizzle({0, 2, 3, 1}),
574 new Register(201, 0, pin_none),
575 0,
576 no_index_offset,
577 fmt_32_32_32_32,
578 vtx_nf_int,
579 vtx_es_none,
580 0,
581 nullptr);
582 expect_fetch.set_element_size(3);
583 expect_fetch.set_print_skip(FetchInstr::EPrintSkip::mfc);
584 expect_fetch.set_print_skip(FetchInstr::EPrintSkip::fmt);
585 expect_fetch.set_print_skip(FetchInstr::EPrintSkip::ftype);
586 expect_fetch.set_fetch_flag(FetchInstr::EFlags::uncached);
587 expect_fetch.set_fetch_flag(FetchInstr::EFlags::indexed);
588 expect_fetch.set_fetch_flag(FetchInstr::EFlags::wait_ack);
589 expect_fetch.set_array_size(19);
590
591 check(init, expect_fetch);
592 }
593
TEST_F(TestInstrFromString,test_write_scratch_to_offset)594 TEST_F(TestInstrFromString, test_write_scratch_to_offset)
595 {
596 add_dest_vec4_from_string("R1.xyzw");
597 string init = "WRITE_SCRATCH 20 R1.xyzw AL:4 ALO:16";
598 ScratchIOInstr expect(RegisterVec4(1), 20, 4, 16, 0xf);
599 check(init, expect);
600
601 add_dest_vec4_from_string("R2.xyzw");
602 string init2 = "WRITE_SCRATCH 10 R2.xy_w AL:8 ALO:8";
603 ScratchIOInstr expect2(RegisterVec4(2), 10, 8, 8, 0xb);
604 check(init2, expect2);
605 }
606
TEST_F(TestInstrFromString,test_write_scratch_to_index)607 TEST_F(TestInstrFromString, test_write_scratch_to_index)
608 {
609 add_dest_vec4_from_string("R1.xyzw");
610 add_dest_from_string("R3.x");
611 string init = "WRITE_SCRATCH @R3.x[10] R1.xyzw AL:4 ALO:16";
612 ScratchIOInstr expect(RegisterVec4(1), new Register(3, 0, pin_none), 4, 16, 0xf, 10);
613 check(init, expect);
614
615 add_dest_vec4_from_string("R2.xyzw");
616 add_dest_from_string("R4.x");
617 string init2 = "WRITE_SCRATCH @R4.x[20] R2.xy__ AL:4 ALO:16";
618 ScratchIOInstr expect2(RegisterVec4(2), new Register(4, 0, pin_none), 4, 16, 0x3, 20);
619 check(init2, expect2);
620 }
621
TEST_F(TestInstrFromString,test_load_from_scratch_fixed_offset)622 TEST_F(TestInstrFromString, test_load_from_scratch_fixed_offset)
623 {
624 string init = "READ_SCRATCH R200.xzwy : L[0xA] SIZE:40 ES:3";
625
626 LoadFromScratch expect(RegisterVec4(200),
627 RegisterVec4::Swizzle({0, 2, 3, 1}),
628 new LiteralConstant(10),
629 40);
630 check(init, expect);
631
632 FetchInstr expect_fetch(vc_read_scratch,
633 RegisterVec4(200),
634 RegisterVec4::Swizzle({0, 2, 3, 1}),
635 new Register(0, 7, pin_none),
636 0,
637 no_index_offset,
638 fmt_32_32_32_32,
639 vtx_nf_int,
640 vtx_es_none,
641 0,
642 nullptr);
643 expect_fetch.set_element_size(3);
644 expect_fetch.set_print_skip(FetchInstr::EPrintSkip::mfc);
645 expect_fetch.set_print_skip(FetchInstr::EPrintSkip::fmt);
646 expect_fetch.set_print_skip(FetchInstr::EPrintSkip::ftype);
647 expect_fetch.set_fetch_flag(FetchInstr::EFlags::uncached);
648 expect_fetch.set_fetch_flag(FetchInstr::EFlags::wait_ack);
649 expect_fetch.set_array_base(10);
650 expect_fetch.set_array_size(39);
651
652 check(init, expect_fetch);
653 }
654
TEST_F(TestInstrFromString,test_lds_read_3_values)655 TEST_F(TestInstrFromString, test_lds_read_3_values)
656 {
657 add_dest_from_string("R5.x@free");
658 add_dest_from_string("R5.y@free");
659 add_dest_from_string("R5.z@free");
660
661 auto init =
662 "LDS_READ [ R10.x@free R11.x@free R12.x@free ] : [ R5.x@free R5.y@free R5.z@free ]";
663
664 std::vector<PRegister, Allocator<PRegister>> dests(3);
665 std::vector<PVirtualValue, Allocator<PVirtualValue>> srcs(3);
666
667 for (int i = 0; i < 3; ++i) {
668 dests[i] = new Register(10 + i, 0, pin_free);
669 srcs[i] = new Register(5, i, pin_free);
670 }
671
672 LDSReadInstr expect(dests, srcs);
673 check(init, expect);
674 }
675
TEST_F(TestInstrFromString,test_lds_read_2_values)676 TEST_F(TestInstrFromString, test_lds_read_2_values)
677 {
678 add_dest_from_string("R5.x@free");
679 add_dest_from_string("R5.y@free");
680
681 auto init = "LDS_READ [ R11.x@free R12.x@free ] : [ R5.x@free R5.y@free ]";
682
683 std::vector<PRegister, Allocator<PRegister>> dests(2);
684 std::vector<PVirtualValue, Allocator<PVirtualValue>> srcs(2);
685
686 for (int i = 0; i < 2; ++i) {
687 dests[i] = new Register(11 + i, 0, pin_free);
688 srcs[i] = new Register(5, i, pin_free);
689 }
690
691 LDSReadInstr expect(dests, srcs);
692 check(init, expect);
693 }
694
TEST_F(TestInstrFromString,test_lds_write_1_value)695 TEST_F(TestInstrFromString, test_lds_write_1_value)
696 {
697 auto init = "LDS WRITE __.x [ R1.x ] : R2.y";
698 add_dest_from_string("R1.x");
699 add_dest_from_string("R2.y");
700
701 LDSAtomicInstr expect(DS_OP_WRITE,
702 nullptr,
703 new Register(1, 0, pin_none),
704 {new Register(2, 1, pin_none)});
705
706 check(init, expect);
707 }
708
TEST_F(TestInstrFromString,test_lds_write_2_value)709 TEST_F(TestInstrFromString, test_lds_write_2_value)
710 {
711 auto init = "LDS WRITE2 __.x [ R1.x ] : R2.y KC0[1].z";
712
713 add_dest_from_string("R1.x");
714 add_dest_from_string("R2.y");
715
716 LDSAtomicInstr expect(DS_OP_WRITE2,
717 nullptr,
718 new Register(1, 0, pin_none),
719 {new Register(2, 1, pin_none), new UniformValue(513, 2, 0)});
720
721 check(init, expect);
722 }
723
TEST_F(TestInstrFromString,test_lds_write_atomic_add_ret)724 TEST_F(TestInstrFromString, test_lds_write_atomic_add_ret)
725 {
726 auto init = "LDS ADD_RET R7.y [ R1.x ] : R2.y";
727
728 add_dest_from_string("R1.x");
729 add_dest_from_string("R2.y");
730
731 LDSAtomicInstr expect(DS_OP_ADD_RET,
732 new Register(7, 1, pin_none),
733 new Register(1, 0, pin_none),
734 {new Register(2, 1, pin_none)});
735
736 check(init, expect);
737 }
738
TEST_F(TestInstrFromString,test_lds_write_atomic_add)739 TEST_F(TestInstrFromString, test_lds_write_atomic_add)
740 {
741 auto init = "LDS ADD __.x [ R1.x ] : R2.y";
742
743 add_dest_from_string("R1.x");
744 add_dest_from_string("R2.y");
745
746 LDSAtomicInstr expect(DS_OP_ADD,
747 nullptr,
748 new Register(1, 0, pin_none),
749 {new Register(2, 1, pin_none)});
750
751 check(init, expect);
752 }
753
TEST_F(TestInstrFromString,test_writeTF)754 TEST_F(TestInstrFromString, test_writeTF)
755 {
756 auto init = "WRITE_TF R1.xyzw";
757
758 add_dest_vec4_from_string("R1.xyzw");
759
760 WriteTFInstr expect(RegisterVec4(1, false, {0, 1, 2, 3}, pin_group));
761
762 check(init, expect);
763 }
764
TestInstrFromString()765 TestInstrFromString::TestInstrFromString() {}
766
767 PInst
from_string(const std::string & s)768 TestInstrFromString::from_string(const std::string& s)
769 {
770 return m_instr_factory->from_string(s, 0, false);
771 }
772
773 void
check(const Instr & eval,const Instr & expect)774 TestInstrFromString::check(const Instr& eval, const Instr& expect)
775 {
776 EXPECT_EQ(eval, expect);
777 }
778
779 void
check(const string & init,const Instr & expect)780 TestInstrFromString::check(const string& init, const Instr& expect)
781 {
782 auto instr = from_string(init);
783 ASSERT_TRUE(instr);
784 EXPECT_EQ(*instr, expect);
785 }
786
787 void
add_dest_from_string(const char * init)788 TestInstrFromString::add_dest_from_string(const char *init)
789 {
790 m_instr_factory->value_factory().dest_from_string(init);
791 }
792
793 void
add_dest_vec4_from_string(const char * init)794 TestInstrFromString::add_dest_vec4_from_string(const char *init)
795 {
796 RegisterVec4::Swizzle dummy;
797 m_instr_factory->value_factory().dest_vec4_from_string(init, dummy);
798 }
799
800 void
SetUp()801 TestInstrFromString::SetUp()
802 {
803 MemoryPool::instance().initialize();
804 m_instr_factory = new InstrFactory;
805 }
806
807 void
TearDown()808 TestInstrFromString::TearDown()
809 {
810 MemoryPool::instance().free();
811 }
812
813 } // namespace r600
814