• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <random>
17 #include <gtest/gtest.h>
18 
19 const uint64_t SEED = 0x1234;
20 #ifndef PANDA_NIGHTLY_TEST_ON
21 const uint64_t ITERATION = 20;
22 #else
23 const uint64_t ITERATION = 4000;
24 #endif
25 static inline auto random_gen = std::mt19937_64(SEED);
26 
27 // Encoder header
28 #include "optimizer/code_generator/operands.h"
29 
30 namespace panda::compiler {
TEST(Operands,TypeInfo)31 TEST(Operands, TypeInfo)
32 {
33     uint8_t u8;
34     int8_t i8;
35     uint16_t u16;
36     int16_t i16;
37     uint32_t u32;
38     int32_t i32;
39     uint64_t u64;
40     int64_t i64;
41 
42     float f32;
43     double f64;
44 
45     TypeInfo arr[] = {
46         TypeInfo(u8),  // 0
47         TypeInfo(u16),
48         TypeInfo(u32),
49         TypeInfo(u64),
50         TypeInfo(i8),  // 4
51         TypeInfo(i16),
52         TypeInfo(i32),
53         TypeInfo(i64),
54         TypeInfo(INT8_TYPE),  // 8
55         TypeInfo(INT16_TYPE),
56         TypeInfo(INT32_TYPE),
57         TypeInfo(INT64_TYPE),
58         TypeInfo(f32),  // 12
59         TypeInfo(f64),
60         TypeInfo(FLOAT32_TYPE),  // 14
61         TypeInfo(FLOAT64_TYPE),
62         TypeInfo(),  // 16
63         INVALID_TYPE,
64     };
65 
66     for (uint8_t i = 0; i < sizeof(arr) / sizeof(TypeInfo); ++i) {
67         if (i >= 16) {
68             ASSERT_FALSE(arr[i].IsValid());
69         } else {
70             ASSERT_TRUE(arr[i].IsValid());
71         }
72     }
73 
74     for (int i = 0; i < 4; ++i) {
75         ASSERT_EQ(arr[i], arr[4 + i]);
76         ASSERT_EQ(arr[i], arr[8 + i]);
77         ASSERT_EQ(arr[4 + i], arr[8 + i]);
78 
79         ASSERT_EQ(arr[i].GetSize(), arr[4 + i].GetSize());
80         ASSERT_EQ(arr[i].GetSize(), arr[8 + i].GetSize());
81         ASSERT_EQ(arr[4 + i].GetSize(), arr[8 + i].GetSize());
82 
83         ASSERT_TRUE(arr[i].IsScalar());
84         ASSERT_TRUE(arr[4 + i].IsScalar());
85         ASSERT_TRUE(arr[8 + i].IsScalar());
86 
87         ASSERT_FALSE(arr[i].IsFloat());
88         ASSERT_FALSE(arr[4 + i].IsFloat());
89         ASSERT_FALSE(arr[8 + i].IsFloat());
90 
91         ASSERT_NE(arr[i], arr[12]);
92         ASSERT_NE(arr[i], arr[13]);
93         ASSERT_NE(arr[4 + i], arr[12]);
94         ASSERT_NE(arr[4 + i], arr[13]);
95         ASSERT_NE(arr[8 + i], arr[12]);
96         ASSERT_NE(arr[8 + i], arr[13]);
97 
98         ASSERT_NE(arr[i], arr[14]);
99         ASSERT_NE(arr[i], arr[15]);
100         ASSERT_NE(arr[4 + i], arr[14]);
101         ASSERT_NE(arr[4 + i], arr[15]);
102         ASSERT_NE(arr[8 + i], arr[14]);
103         ASSERT_NE(arr[8 + i], arr[15]);
104         ASSERT_NE(arr[i], arr[16]);
105         ASSERT_NE(arr[i], arr[17]);
106         ASSERT_NE(arr[4 + i], arr[16]);
107         ASSERT_NE(arr[4 + i], arr[17]);
108         ASSERT_NE(arr[8 + i], arr[16]);
109         ASSERT_NE(arr[8 + i], arr[17]);
110     }
111     // Float
112     ASSERT_EQ(arr[2].GetSize(), arr[12].GetSize());
113     ASSERT_EQ(arr[2].GetSize(), arr[14].GetSize());
114 
115     ASSERT_TRUE(arr[12].IsValid());
116     ASSERT_TRUE(arr[14].IsValid());
117     ASSERT_TRUE(arr[12].IsFloat());
118     ASSERT_TRUE(arr[14].IsFloat());
119     // Double
120     ASSERT_EQ(arr[3].GetSize(), arr[13].GetSize());
121     ASSERT_EQ(arr[3].GetSize(), arr[15].GetSize());
122 
123     // Check sizes:
124     ASSERT_EQ(BYTE_SIZE, HALF_SIZE / 2);
125     ASSERT_EQ(HALF_SIZE, WORD_SIZE / 2);
126     ASSERT_EQ(WORD_SIZE, DOUBLE_WORD_SIZE / 2);
127 
128     ASSERT_EQ(arr[0].GetSize(), BYTE_SIZE);
129     ASSERT_EQ(arr[1].GetSize(), HALF_SIZE);
130     ASSERT_EQ(arr[2].GetSize(), WORD_SIZE);
131     ASSERT_EQ(arr[3].GetSize(), DOUBLE_WORD_SIZE);
132 
133     ASSERT_EQ(sizeof(TypeInfo), sizeof(uint8_t));
134 
135     ASSERT_EQ(TypeInfo(u8), INT8_TYPE);
136     ASSERT_EQ(TypeInfo(u16), INT16_TYPE);
137     ASSERT_EQ(TypeInfo(u32), INT32_TYPE);
138     ASSERT_EQ(TypeInfo(u64), INT64_TYPE);
139 
140     ASSERT_EQ(TypeInfo(f32), FLOAT32_TYPE);
141     ASSERT_EQ(TypeInfo(f64), FLOAT64_TYPE);
142 }
143 
TEST(Operands,Reg)144 TEST(Operands, Reg)
145 {
146     //  Size of structure
147     ASSERT_LE(sizeof(Reg), sizeof(size_t));
148 
149     ASSERT_EQ(INVALID_REGISTER.GetId(), INVALID_REG_ID);
150 
151     // Check, what it is possible to create all 32 registers
152     // for each type
153 
154     // Check what special registers are possible to compare with others
155 
156     // Check equality between registers
157 
158     // Check invalid registers
159 }
160 
TEST(Operands,Imm)161 TEST(Operands, Imm)
162 {
163     // Check all possible types:
164     //  Imm holds same data (static cast for un-signed)
165     // GetType
166     // Getsize
167     // Is scalar
168     //  Is Valid
169     //  Bounary checks
170     //  Check IsZero
171     // Inc/dec checks
172     // INVALID_IMM check
173 
174     for (uint64_t i = 0; i < ITERATION; ++i) {
175         uint8_t u8 = random_gen(), u8_z = 0, u8_min = std::numeric_limits<uint8_t>::min(),
176                 u8_max = std::numeric_limits<uint8_t>::max();
177         uint16_t u16 = random_gen(), u16_z = 0, u16_min = std::numeric_limits<uint16_t>::min(),
178                  u16_max = std::numeric_limits<uint16_t>::max();
179         uint32_t u32 = random_gen(), u32_z = 0, u32_min = std::numeric_limits<uint32_t>::min(),
180                  u32_max = std::numeric_limits<uint32_t>::max();
181         uint64_t u64 = random_gen(), u64_z = 0, u64_min = std::numeric_limits<uint64_t>::min(),
182                  u64_max = std::numeric_limits<uint64_t>::max();
183 
184         int8_t i8 = random_gen(), i8_z = 0, i8_min = std::numeric_limits<int8_t>::min(),
185                i8_max = std::numeric_limits<int8_t>::max();
186         int16_t i16 = random_gen(), i16_z = 0, i16_min = std::numeric_limits<int16_t>::min(),
187                 i16_max = std::numeric_limits<int16_t>::max();
188         int32_t i32 = random_gen(), i32_z = 0, i32_min = std::numeric_limits<int32_t>::min(),
189                 i32_max = std::numeric_limits<int32_t>::max();
190         int64_t i64 = random_gen(), i64_z = 0, i64_min = std::numeric_limits<int64_t>::min(),
191                 i64_max = std::numeric_limits<int64_t>::max();
192 
193         float f32 = random_gen(), f32_z = 0, f32_min = std::numeric_limits<float>::min(),
194               f32_max = std::numeric_limits<float>::max();
195         double f64 = random_gen(), f64_z = 0, f64_min = std::numeric_limits<double>::min(),
196                f64_max = std::numeric_limits<double>::max();
197 
198         // Unsigned part - check across static_cast
199 
200         Imm imm_u8(u8), imm_u8_z(u8_z), imm_u8_min(u8_min), imm_u8_max(u8_max);
201         ASSERT_EQ(imm_u8.GetValue<int8_t>(), static_cast<int8_t>(u8));
202         ASSERT_EQ(imm_u8_min.GetValue<int8_t>(), static_cast<int8_t>(u8_min));
203         ASSERT_EQ(imm_u8_max.GetValue<int8_t>(), static_cast<int8_t>(u8_max));
204         ASSERT_EQ(imm_u8_z.GetValue<int8_t>(), static_cast<int8_t>(u8_z));
205 
206         ASSERT_TRUE(imm_u8_min.IsZero());
207         ASSERT_TRUE(imm_u8_z.IsZero());
208         ASSERT_FALSE(imm_u8_max.IsZero());
209 
210         ASSERT_TRUE(imm_u8.IsValid());
211         ASSERT_TRUE(imm_u8_z.IsValid());
212         ASSERT_TRUE(imm_u8_min.IsValid());
213         ASSERT_TRUE(imm_u8_max.IsValid());
214 
215         Imm imm_u16(u16), imm_u16_z(u16_z), imm_u16_min(u16_min), imm_u16_max(u16_max);
216         ASSERT_EQ(imm_u16.GetValue<int16_t>(), static_cast<int16_t>(u16));
217         ASSERT_EQ(imm_u16_min.GetValue<int16_t>(), static_cast<int16_t>(u16_min));
218         ASSERT_EQ(imm_u16_max.GetValue<int16_t>(), static_cast<int16_t>(u16_max));
219         ASSERT_EQ(imm_u16_z.GetValue<int16_t>(), static_cast<int16_t>(u16_z));
220 
221         ASSERT_TRUE(imm_u16_min.IsZero());
222         ASSERT_TRUE(imm_u16_z.IsZero());
223         ASSERT_FALSE(imm_u16_max.IsZero());
224 
225         ASSERT_TRUE(imm_u16.IsValid());
226         ASSERT_TRUE(imm_u16_z.IsValid());
227         ASSERT_TRUE(imm_u16_min.IsValid());
228         ASSERT_TRUE(imm_u16_max.IsValid());
229 
230         Imm imm_u32(u32), imm_u32_z(u32_z), imm_u32_min(u32_min), imm_u32_max(u32_max);
231         ASSERT_EQ(imm_u32.GetValue<int32_t>(), static_cast<int32_t>(u32));
232         ASSERT_EQ(imm_u32_min.GetValue<int32_t>(), static_cast<int32_t>(u32_min));
233         ASSERT_EQ(imm_u32_max.GetValue<int32_t>(), static_cast<int32_t>(u32_max));
234         ASSERT_EQ(imm_u32_z.GetValue<int32_t>(), static_cast<int32_t>(u32_z));
235 
236         ASSERT_TRUE(imm_u32_min.IsZero());
237         ASSERT_TRUE(imm_u32_z.IsZero());
238         ASSERT_FALSE(imm_u32_max.IsZero());
239 
240         ASSERT_TRUE(imm_u32.IsValid());
241         ASSERT_TRUE(imm_u32_z.IsValid());
242         ASSERT_TRUE(imm_u32_min.IsValid());
243         ASSERT_TRUE(imm_u32_max.IsValid());
244 
245         Imm imm_u64(u64), imm_u64_z(u64_z), imm_u64_min(u64_min), imm_u64_max(u64_max);
246         ASSERT_EQ(imm_u64.GetValue<int64_t>(), static_cast<int64_t>(u64));
247         ASSERT_EQ(imm_u64_min.GetValue<int64_t>(), static_cast<int64_t>(u64_min));
248         ASSERT_EQ(imm_u64_max.GetValue<int64_t>(), static_cast<int64_t>(u64_max));
249         ASSERT_EQ(imm_u64_z.GetValue<int64_t>(), static_cast<int64_t>(u64_z));
250 
251         ASSERT_TRUE(imm_u64_min.IsZero());
252         ASSERT_TRUE(imm_u64_z.IsZero());
253         ASSERT_FALSE(imm_u64_max.IsZero());
254 
255         ASSERT_TRUE(imm_u64.IsValid());
256         ASSERT_TRUE(imm_u64_z.IsValid());
257         ASSERT_TRUE(imm_u64_min.IsValid());
258         ASSERT_TRUE(imm_u64_max.IsValid());
259 
260         // Signed part
261 
262         Imm imm_i8(i8), imm_i8_z(i8_z), imm_i8_min(i8_min), imm_i8_max(i8_max);
263         ASSERT_EQ(imm_i8.GetValue<int8_t>(), i8);
264         ASSERT_EQ(imm_i8_min.GetValue<int8_t>(), i8_min);
265         ASSERT_EQ(imm_i8_max.GetValue<int8_t>(), i8_max);
266         ASSERT_EQ(imm_i8_z.GetValue<int8_t>(), i8_z);
267 
268         ASSERT_FALSE(imm_i8_min.IsZero());
269         ASSERT_TRUE(imm_i8_z.IsZero());
270         ASSERT_FALSE(imm_i8_max.IsZero());
271 
272         ASSERT_TRUE(imm_i8.IsValid());
273         ASSERT_TRUE(imm_i8_z.IsValid());
274         ASSERT_TRUE(imm_i8_min.IsValid());
275         ASSERT_TRUE(imm_i8_max.IsValid());
276 
277         Imm imm_i16(i16), imm_i16_z(i16_z), imm_i16_min(i16_min), imm_i16_max(i16_max);
278         ASSERT_EQ(imm_i16.GetValue<int16_t>(), i16);
279         ASSERT_EQ(imm_i16_min.GetValue<int16_t>(), i16_min);
280         ASSERT_EQ(imm_i16_max.GetValue<int16_t>(), i16_max);
281         ASSERT_EQ(imm_i16_z.GetValue<int16_t>(), i16_z);
282 
283         ASSERT_FALSE(imm_i16_min.IsZero());
284         ASSERT_TRUE(imm_i16_z.IsZero());
285         ASSERT_FALSE(imm_i16_max.IsZero());
286 
287         ASSERT_TRUE(imm_i16.IsValid());
288         ASSERT_TRUE(imm_i16_z.IsValid());
289         ASSERT_TRUE(imm_i16_min.IsValid());
290         ASSERT_TRUE(imm_i16_max.IsValid());
291 
292         Imm imm_i32(i32), imm_i32_z(i32_z), imm_i32_min(i32_min), imm_i32_max(i32_max);
293         ASSERT_EQ(imm_i32.GetValue<int32_t>(), i32);
294         ASSERT_EQ(imm_i32_min.GetValue<int32_t>(), i32_min);
295         ASSERT_EQ(imm_i32_max.GetValue<int32_t>(), i32_max);
296         ASSERT_EQ(imm_i32_z.GetValue<int32_t>(), i32_z);
297 
298         ASSERT_FALSE(imm_i32_min.IsZero());
299         ASSERT_TRUE(imm_i32_z.IsZero());
300         ASSERT_FALSE(imm_i32_max.IsZero());
301 
302         ASSERT_TRUE(imm_i32.IsValid());
303         ASSERT_TRUE(imm_i32_z.IsValid());
304         ASSERT_TRUE(imm_i32_min.IsValid());
305         ASSERT_TRUE(imm_i32_max.IsValid());
306 
307         Imm imm_i64(i64), imm_i64_z(i64_z), imm_i64_min(i64_min), imm_i64_max(i64_max);
308         ASSERT_EQ(imm_i64.GetValue<int64_t>(), i64);
309         ASSERT_EQ(imm_i64_min.GetValue<int64_t>(), i64_min);
310         ASSERT_EQ(imm_i64_max.GetValue<int64_t>(), i64_max);
311         ASSERT_EQ(imm_i64_z.GetValue<int64_t>(), i64_z);
312 
313         ASSERT_FALSE(imm_i64_min.IsZero());
314         ASSERT_TRUE(imm_i64_z.IsZero());
315         ASSERT_FALSE(imm_i64_max.IsZero());
316 
317         ASSERT_TRUE(imm_i64.IsValid());
318         ASSERT_TRUE(imm_i64_z.IsValid());
319         ASSERT_TRUE(imm_i64_min.IsValid());
320         ASSERT_TRUE(imm_i64_max.IsValid());
321     }
322     // Sizeof imm:
323     // Imm holds 2 uint64_t values (std::variant)
324     ASSERT_LE(sizeof(Imm), sizeof(uint64_t) * 2);
325 }
326 
TEST(Operands,MemRef)327 TEST(Operands, MemRef)
328 {
329     Reg r1(1, INT64_TYPE), r2(2, INT64_TYPE), r_i(INVALID_REG_ID, INVALID_TYPE);
330     ssize_t i1(0x0), i2(0x2);
331 
332     MemRef arr[] {MemRef(r1), MemRef(r1, i1), MemRef(r1)};
333     // 1. Check constructors
334     //  for getters
335     //  for validness
336     //  for operator ==
337     // 2. Create mem with invalid_reg / invalid imm
338 }
339 }  // namespace panda::compiler
340