1 /*
2 * Copyright 2023 Alyssa Rosenzweig
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include "agx_builder.h"
7 #include "agx_compile.h"
8 #include "agx_compiler.h"
9 #include "agx_test.h"
10
11 #include "util/macros.h"
12 #include <gtest/gtest.h>
13
14 #define CASE(instr, expected) \
15 do { \
16 agx_builder *A = agx_test_builder(mem_ctx); \
17 agx_builder *B = agx_test_builder(mem_ctx); \
18 { \
19 agx_builder *b = A; \
20 instr; \
21 } \
22 { \
23 agx_builder *b = B; \
24 expected; \
25 } \
26 agx_lower_spill(A->shader); \
27 ASSERT_SHADER_EQUAL(A->shader, B->shader); \
28 } while (0)
29
30 class LowerSpill : public testing::Test {
31 protected:
LowerSpill()32 LowerSpill()
33 {
34 mem_ctx = ralloc_context(NULL);
35
36 wx = agx_register(0, AGX_SIZE_32);
37 hy = agx_register(2, AGX_SIZE_16);
38
39 mw4 = agx_memory_register(0, AGX_SIZE_32);
40 mh4 = agx_memory_register(0, AGX_SIZE_16);
41 mw4.channels_m1 = 4 - 1;
42 mh4.channels_m1 = 4 - 1;
43
44 wx4 = wx;
45 wx4.channels_m1 = 4 - 1;
46
47 hy4 = hy;
48 hy4.channels_m1 = 4 - 1;
49 }
50
~LowerSpill()51 ~LowerSpill()
52 {
53 ralloc_free(mem_ctx);
54 }
55
56 void *mem_ctx;
57 agx_index wx, hy, wx4, hy4;
58 agx_index mw4, mh4;
59
60 unsigned scalar = BITFIELD_MASK(1);
61 unsigned vec4 = BITFIELD_MASK(4);
62
63 enum agx_format i16 = AGX_FORMAT_I16;
64 enum agx_format i32 = AGX_FORMAT_I32;
65 };
66
TEST_F(LowerSpill,ScalarSpills)67 TEST_F(LowerSpill, ScalarSpills)
68 {
69 CASE(agx_mov_to(b, agx_memory_register(11, AGX_SIZE_16), hy),
70 agx_stack_store(b, hy, agx_immediate(22), i16, scalar));
71
72 CASE(agx_mov_to(b, agx_memory_register(18, AGX_SIZE_32), wx),
73 agx_stack_store(b, wx, agx_immediate(36), i32, scalar));
74 }
75
TEST_F(LowerSpill,ScalarFills)76 TEST_F(LowerSpill, ScalarFills)
77 {
78 CASE(agx_mov_to(b, hy, agx_memory_register(11, AGX_SIZE_16)),
79 agx_stack_load_to(b, hy, agx_immediate(22), i16, scalar));
80
81 CASE(agx_mov_to(b, wx, agx_memory_register(18, AGX_SIZE_32)),
82 agx_stack_load_to(b, wx, agx_immediate(36), i32, scalar));
83 }
84
TEST_F(LowerSpill,VectorSpills)85 TEST_F(LowerSpill, VectorSpills)
86 {
87 CASE(agx_mov_to(b, mh4, hy4),
88 agx_stack_store(b, hy4, agx_immediate(0), i16, vec4));
89
90 CASE(agx_mov_to(b, mw4, wx4),
91 agx_stack_store(b, wx4, agx_immediate(0), i32, vec4));
92 }
93
TEST_F(LowerSpill,VectorFills)94 TEST_F(LowerSpill, VectorFills)
95 {
96 CASE(agx_mov_to(b, hy4, mh4),
97 agx_stack_load_to(b, hy4, agx_immediate(0), i16, vec4));
98
99 CASE(agx_mov_to(b, wx4, mw4),
100 agx_stack_load_to(b, wx4, agx_immediate(0), i32, vec4));
101 }
102
TEST_F(LowerSpill,ScalarSpill64)103 TEST_F(LowerSpill, ScalarSpill64)
104 {
105 CASE(agx_mov_to(b, agx_memory_register(16, AGX_SIZE_64),
106 agx_register(8, AGX_SIZE_64)),
107 agx_stack_store(b, agx_register(8, AGX_SIZE_64), agx_immediate(32), i32,
108 BITFIELD_MASK(2)));
109 }
110
TEST_F(LowerSpill,ScalarFill64)111 TEST_F(LowerSpill, ScalarFill64)
112 {
113 CASE(agx_mov_to(b, agx_register(16, AGX_SIZE_64),
114 agx_memory_register(8, AGX_SIZE_64)),
115 agx_stack_load_to(b, agx_register(16, AGX_SIZE_64), agx_immediate(16),
116 i32, BITFIELD_MASK(2)));
117 }
118
TEST_F(LowerSpill,Vec6Spill)119 TEST_F(LowerSpill, Vec6Spill)
120 {
121 CASE(
122 {
123 agx_index mvec6 = agx_memory_register(16, AGX_SIZE_32);
124 agx_index vec6 = agx_register(8, AGX_SIZE_32);
125 vec6.channels_m1 = 6 - 1;
126 mvec6.channels_m1 = 6 - 1;
127
128 agx_mov_to(b, mvec6, vec6);
129 },
130 {
131 agx_index vec4 = agx_register(8, AGX_SIZE_32);
132 agx_index vec2 = agx_register(8 + (4 * 2), AGX_SIZE_32);
133 vec4.channels_m1 = 4 - 1;
134 vec2.channels_m1 = 2 - 1;
135
136 agx_stack_store(b, vec4, agx_immediate(32), i32, BITFIELD_MASK(4));
137 agx_stack_store(b, vec2, agx_immediate(32 + 4 * 4), i32,
138 BITFIELD_MASK(2));
139 });
140 }
141
TEST_F(LowerSpill,Vec6Fill)142 TEST_F(LowerSpill, Vec6Fill)
143 {
144 CASE(
145 {
146 agx_index mvec6 = agx_memory_register(16, AGX_SIZE_32);
147 agx_index vec6 = agx_register(8, AGX_SIZE_32);
148 vec6.channels_m1 = 6 - 1;
149 mvec6.channels_m1 = 6 - 1;
150
151 agx_mov_to(b, vec6, mvec6);
152 },
153 {
154 agx_index vec4 = agx_register(8, AGX_SIZE_32);
155 agx_index vec2 = agx_register(8 + (4 * 2), AGX_SIZE_32);
156 vec4.channels_m1 = 4 - 1;
157 vec2.channels_m1 = 2 - 1;
158
159 agx_stack_load_to(b, vec4, agx_immediate(32), i32, BITFIELD_MASK(4));
160 agx_stack_load_to(b, vec2, agx_immediate(32 + 4 * 4), i32,
161 BITFIELD_MASK(2));
162 });
163 }
164