1 /* -*- mesa-c++ -*-
2 *
3 * Copyright (c) 2021 Collabora LTD
4 *
5 * Author: Gert Wollny <[email protected]>
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * on the rights to use, copy, modify, merge, publish, distribute, sub
11 * license, and/or sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27 #include "../sfn_alu_defines.h"
28 #include "../sfn_debug.h"
29 #include "../sfn_virtualvalues.h"
30
31 #include "gtest/gtest.h"
32
33 using namespace r600;
34
35 class ValueTest : public ::testing::Test {
SetUp()36 void SetUp() override { init_pool(); }
37
TearDown()38 void TearDown() override { release_pool(); }
39 };
40
TEST_F(ValueTest,gpr_register_fully_pinned)41 TEST_F(ValueTest, gpr_register_fully_pinned)
42 {
43 Register reg(1, 2, pin_fully);
44
45 EXPECT_EQ(reg.sel(), 1);
46 EXPECT_EQ(reg.chan(), 2);
47 EXPECT_EQ(reg.pin(), pin_fully);
48 EXPECT_FALSE(reg.is_virtual());
49
50 Register reg2(3, 1, pin_fully);
51
52 EXPECT_EQ(reg2.sel(), 3);
53 EXPECT_EQ(reg2.chan(), 1);
54 EXPECT_EQ(reg2.pin(), pin_fully);
55 EXPECT_FALSE(reg2.is_virtual());
56 }
57
58 #ifdef __cpp_exceptions
TEST_F(ValueTest,virtual_register_must_not_be_pinned_to_sel)59 TEST_F(ValueTest, virtual_register_must_not_be_pinned_to_sel)
60 {
61 EXPECT_THROW(Register(1024, 1, pin_fully), std::invalid_argument);
62 }
63 #endif
64
TEST_F(ValueTest,virtual_register_not_pinned)65 TEST_F(ValueTest, virtual_register_not_pinned)
66 {
67 Register reg(1024, 1, pin_none);
68
69 EXPECT_EQ(reg.sel(), 1024);
70 EXPECT_EQ(reg.chan(), 1);
71 EXPECT_EQ(reg.pin(), pin_none);
72 EXPECT_TRUE(reg.is_virtual());
73
74 Register reg2(1025, 2, pin_none);
75
76 EXPECT_EQ(reg2.sel(), 1025);
77 EXPECT_EQ(reg2.chan(), 2);
78 EXPECT_EQ(reg2.pin(), pin_none);
79 EXPECT_TRUE(reg2.is_virtual());
80 }
81
TEST_F(ValueTest,uniform_value)82 TEST_F(ValueTest, uniform_value)
83 {
84 UniformValue reg0(512, 1);
85
86 EXPECT_EQ(reg0.sel(), 512);
87 EXPECT_EQ(reg0.chan(), 1);
88 EXPECT_EQ(reg0.kcache_bank(), 0);
89 EXPECT_FALSE(reg0.buf_addr());
90 EXPECT_FALSE(reg0.is_virtual());
91
92 UniformValue reg1(513, 2, 1);
93
94 EXPECT_EQ(reg1.sel(), 513);
95 EXPECT_EQ(reg1.chan(), 2);
96 EXPECT_EQ(reg1.kcache_bank(), 1);
97 EXPECT_FALSE(reg1.buf_addr());
98 EXPECT_FALSE(reg1.is_virtual());
99
100 auto addr = new Register(1024, 0, pin_none);
101 ASSERT_TRUE(addr);
102
103 UniformValue reg_with_buffer_addr(513, 0, addr, 0);
104
105 EXPECT_EQ(reg_with_buffer_addr.sel(), 513);
106 EXPECT_EQ(reg_with_buffer_addr.chan(), 0);
107 EXPECT_EQ(reg_with_buffer_addr.pin(), pin_none);
108 EXPECT_EQ(reg_with_buffer_addr.kcache_bank(), 0);
109 EXPECT_FALSE(reg_with_buffer_addr.is_virtual());
110 ASSERT_TRUE(reg_with_buffer_addr.buf_addr());
111
112 auto baddr = reg_with_buffer_addr.buf_addr();
113 EXPECT_EQ(baddr->sel(), 1024);
114 EXPECT_EQ(baddr->chan(), 0);
115 EXPECT_EQ(baddr->pin(), pin_none);
116 EXPECT_TRUE(baddr->is_virtual());
117 }
118
TEST_F(ValueTest,literal_value)119 TEST_F(ValueTest, literal_value)
120 {
121 LiteralConstant literal(12);
122 EXPECT_EQ(literal.sel(), ALU_SRC_LITERAL);
123 EXPECT_EQ(literal.chan(), -1);
124 EXPECT_EQ(literal.value(), 12);
125 EXPECT_FALSE(literal.is_virtual());
126
127 LiteralConstant literal2(2);
128 EXPECT_EQ(literal2.sel(), ALU_SRC_LITERAL);
129 EXPECT_EQ(literal2.chan(), -1);
130 EXPECT_EQ(literal2.value(), 2);
131 EXPECT_FALSE(literal2.is_virtual());
132 }
133
TEST_F(ValueTest,inline_constant)134 TEST_F(ValueTest, inline_constant)
135 {
136 InlineConstant c0(ALU_SRC_1);
137
138 EXPECT_EQ(c0.sel(), ALU_SRC_1);
139 EXPECT_EQ(c0.chan(), 0);
140 EXPECT_FALSE(c0.is_virtual());
141
142 InlineConstant c1(ALU_SRC_M_1_INT);
143 EXPECT_EQ(c1.sel(), ALU_SRC_M_1_INT);
144 EXPECT_EQ(c1.chan(), 0);
145 EXPECT_FALSE(c1.is_virtual());
146
147 InlineConstant c2(ALU_SRC_PV, 1);
148 EXPECT_EQ(c2.sel(), ALU_SRC_PV);
149 EXPECT_EQ(c2.chan(), 1);
150 EXPECT_FALSE(c2.is_virtual());
151 }
152
TEST_F(ValueTest,array)153 TEST_F(ValueTest, array)
154 {
155 LocalArray array(1024, 2, 12);
156
157 EXPECT_EQ(array.size(), 12);
158 EXPECT_EQ(array.nchannels(), 2);
159
160 auto elm0 = array.element(0, nullptr, 0);
161 ASSERT_TRUE(elm0);
162
163 EXPECT_EQ(elm0->sel(), 1024);
164 EXPECT_EQ(elm0->chan(), 0);
165 EXPECT_EQ(elm0->pin(), pin_array);
166
167 EXPECT_FALSE(elm0->get_addr());
168
169 auto elm1 = array.element(8, nullptr, 1);
170 ASSERT_TRUE(elm1);
171
172 EXPECT_EQ(elm1->sel(), 1024 + 8);
173 EXPECT_EQ(elm1->chan(), 1);
174 EXPECT_EQ(elm1->pin(), pin_array);
175 EXPECT_FALSE(elm1->get_addr());
176
177 auto addr = new Register(2000, 0, pin_none);
178 ASSERT_TRUE(addr);
179
180 auto elm_indirect = array.element(0, addr, 1);
181 ASSERT_TRUE(elm_indirect);
182
183 auto elm_addr = elm_indirect->get_addr();
184 ASSERT_TRUE(elm_addr);
185
186 EXPECT_EQ(elm_indirect->sel(), 1024);
187 EXPECT_EQ(elm_indirect->chan(), 1);
188 EXPECT_EQ(elm_indirect->pin(), pin_array);
189
190 EXPECT_EQ(elm_addr->sel(), 2000);
191 EXPECT_EQ(elm_addr->chan(), 0);
192 EXPECT_EQ(elm_addr->pin(), pin_none);
193
194 // A constant addr should resolve directly
195 auto addr2 = new LiteralConstant(3);
196 ASSERT_TRUE(addr2);
197
198 auto elm_direct = array.element(0, addr2, 0);
199 auto elm_direct_addr = elm_direct->get_addr();
200 EXPECT_FALSE(elm_direct_addr);
201
202 EXPECT_EQ(elm_direct->sel(), 1027);
203 EXPECT_EQ(elm_direct->chan(), 0);
204 EXPECT_EQ(elm_direct->pin(), pin_array);
205
206 #ifdef __cpp_exceptions
207 EXPECT_THROW(array.element(12, nullptr, 0), std::invalid_argument);
208 EXPECT_THROW(array.element(3, nullptr, 2), std::invalid_argument);
209
210 auto addr3 = new LiteralConstant(12);
211 ASSERT_TRUE(addr3);
212 EXPECT_THROW(array.element(0, addr3, 0), std::invalid_argument);
213 #endif
214 }
215
TEST_F(ValueTest,reg_from_string)216 TEST_F(ValueTest, reg_from_string)
217 {
218 Register reg(1000, 0, pin_none);
219 auto fs = Register::from_string("R1000.x");
220 EXPECT_EQ(*fs, reg);
221
222 EXPECT_EQ(*Register::from_string("R1001.y"), Register(1001, 1, pin_none));
223
224 auto reg2 = Register(1, 2, pin_fully);
225 reg2.set_flag(Register::pin_start);
226 EXPECT_EQ(*Register::from_string("R1.z@fully"), reg2);
227 EXPECT_EQ(*Register::from_string("R1000.y@chan"), Register(1000, 1, pin_chan));
228 EXPECT_EQ(*Register::from_string("R1000.y@free"), Register(1000, 1, pin_free));
229
230 EXPECT_EQ(*VirtualValue::from_string("L[0x1]"), LiteralConstant(1));
231 EXPECT_EQ(*VirtualValue::from_string("L[0x2]"), LiteralConstant(2));
232 EXPECT_EQ(*VirtualValue::from_string("L[0xA]"), LiteralConstant(10));
233
234 EXPECT_EQ(*VirtualValue::from_string("I[0]"), InlineConstant(ALU_SRC_0));
235 EXPECT_EQ(*VirtualValue::from_string("I[HW_WAVE_ID]"),
236 InlineConstant(ALU_SRC_HW_WAVE_ID));
237 }
238