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