• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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