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 19const uint64_t SEED = 0x1234; 20#ifndef PANDA_NIGHTLY_TEST_ON 21const uint64_t ITERATION = 20; 22#else 23const uint64_t ITERATION = 4000; 24#endif 25static inline auto random_gen = std::mt19937_64(SEED); 26 27// Encoder header 28#include "optimizer/code_generator/operands.h" 29 30namespace panda::compiler { 31TEST(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 144TEST(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 161TEST(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} // namespace panda::compiler 327