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