1#!/usr/bin/python 2# 3# Copyright (C) 2015 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18import sys 19import unittest 20 21import gen_intrinsics 22 23 24class GenIntrinsicsTests(unittest.TestCase): 25 26 def test_get_semantics_player_hook_proto_smoke(self): 27 out = gen_intrinsics._get_semantics_player_hook_proto("Foo", { 28 "in": ["uint32_t"], 29 "out": [] 30 }) 31 self.assertEqual(out, "void Foo(Register arg0)") 32 33 def test_get_semantics_player_hook_proto_template_types(self): 34 intr = { 35 "Foo": { 36 "in": ["uint32_t", "uint8_t", "Type0", "Type1", "vec", "uimm8"], 37 "out": ["uint32_t"], 38 "class": "template", 39 "variants": ["Float32, int32", "Float64, int64"] 40 }} 41 gen_intrinsics._gen_semantic_player_types(intr.items()) 42 out = gen_intrinsics._get_semantics_player_hook_proto("Foo", intr["Foo"]) 43 self.assertEqual(out, 44 "template<typename Type0, typename Type1>\n" 45 "Register Foo(Register arg0, " 46 "Register arg1, " 47 "FpRegister arg2, " 48 "Register arg3, " 49 "SimdRegister arg4, " 50 "uint8_t arg5)" ) # pyformat: disable 51 52 def test_get_semantics_player_hook_proto_operand_types(self): 53 out = gen_intrinsics._get_semantics_player_hook_proto( 54 "Foo", { 55 "in": ["uint32_t", "uint8_t", "Float32", "Float64", "vec", "uimm8"], 56 "out": ["uint32_t"] 57 }) 58 self.assertEqual(out, 59 "Register Foo(Register arg0, " 60 "Register arg1, " 61 "SimdRegister arg2, " 62 "SimdRegister arg3, " 63 "SimdRegister arg4, " 64 "uint8_t arg5)" ) # pyformat: disable 65 66 def test_get_semantics_player_hook_proto_multiple_results(self): 67 out = gen_intrinsics._get_semantics_player_hook_proto("Foo", { 68 "in": ["uint32_t"], 69 "out": ["vec", "uint32_t"] 70 }) 71 self.assertEqual(out, 72 "std::tuple<SimdRegister, Register> Foo(Register arg0)") 73 74 def test_get_interpreter_hook_call_expr_smoke(self): 75 out = gen_intrinsics._get_interpreter_hook_call_expr( 76 "Foo", { 77 "in": ["uint32_t"], 78 "out": [] 79 }) 80 self.assertEqual(out, "intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0))") 81 82 def test_get_interpreter_hook_call_expr_template_types(self): 83 intr = { 84 "Foo": { 85 "in": ["uint32_t", "uint8_t", "Type0", "Type1", "vec", "uimm8"], 86 "out": ["uint32_t"], 87 "class": "template", 88 "variants": ["Float32, int32", "Float64, int64"] 89 }} 90 gen_intrinsics._gen_semantic_player_types(intr.items()) 91 out = gen_intrinsics._get_interpreter_hook_call_expr("Foo", intr["Foo"]) 92 self.assertEqual( 93 out, 94 "IntegerToGPRReg(std::get<0>(intrinsics::Foo<Type0, Type1>(" 95 "GPRRegToInteger<uint32_t>(arg0), " 96 "GPRRegToInteger<uint8_t>(arg1), " 97 "FPRegToFloat<Type0>(arg2), " 98 "GPRRegToInteger<Type1>(arg3), " 99 "arg4, " 100 "GPRRegToInteger<uint8_t>(arg5))))" ) # pyforman: disable 101 102 def test_get_interpreter_hook_call_expr_operand_types(self): 103 out = gen_intrinsics._get_interpreter_hook_call_expr( 104 "Foo", { 105 "in": ["uint32_t", "uint8_t", "Float32", "Float64", "vec", "uimm8"], 106 "out": [] 107 }) 108 self.assertEqual(out, 109 "intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0), " 110 "GPRRegToInteger<uint8_t>(arg1), " 111 "FPRegToFloat<intrinsics::Float32>(arg2), " 112 "FPRegToFloat<intrinsics::Float64>(arg3), " 113 "arg4, " 114 "GPRRegToInteger<uint8_t>(arg5))" ) # pyforman: disable 115 116 def test_get_interpreter_hook_call_expr_single_result(self): 117 out = gen_intrinsics._get_interpreter_hook_call_expr( 118 "Foo", { 119 "in": ["uint32_t"], 120 "out": ["uint32_t"] 121 }) 122 self.assertEqual(out, "std::get<0>(intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0)))") 123 124 def test_get_interpreter_hook_call_expr_multiple_result(self): 125 out = gen_intrinsics._get_interpreter_hook_call_expr( 126 "Foo", { 127 "in": ["uint32_t"], 128 "out": ["vec", "uint32_t"] 129 }) 130 self.assertEqual(out, "intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0))") 131 132 def test_get_interpreter_hook_call_expr_float32_result(self): 133 out = gen_intrinsics._get_interpreter_hook_call_expr( 134 "Foo", { 135 "in": ["uint32_t"], 136 "out": ["Float32"] 137 }) 138 self.assertEqual(out, "FloatToFPReg(std::get<0>(intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0))))") 139 140 def test_get_interpreter_hook_call_expr_float64_result(self): 141 out = gen_intrinsics._get_interpreter_hook_call_expr( 142 "Foo", { 143 "in": ["uint32_t"], 144 "out": ["Float64"] 145 }) 146 self.assertEqual(out, "FloatToFPReg(std::get<0>(intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0))))") 147 148 def test_get_interpreter_hook_call_expr_precise_nan(self): 149 out = gen_intrinsics._get_interpreter_hook_call_expr( 150 "Foo", { 151 "in": ["uint32_t"], 152 "out": [], 153 "precise_nans": True, 154 }) 155 self.assertEqual( 156 out, "intrinsics::Foo<config::kPreciseNaNOperationsHandling>(" 157 "GPRRegToInteger<uint32_t>(arg0))") 158 159 def test_gen_interpreter_hook_return_stmt(self): 160 out = gen_intrinsics._get_interpreter_hook_return_stmt( 161 "Foo", { 162 "in": ["uint32_t"], 163 "out": ["uint32_t"] 164 }) 165 self.assertEqual(out, "return std::get<0>(intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0)));") 166 167 def test_gen_interpreter_hook_return_stmt_void(self): 168 out = gen_intrinsics._get_interpreter_hook_return_stmt( 169 "Foo", { 170 "in": ["uint32_t"], 171 "out": [] 172 }) 173 self.assertEqual(out, "return intrinsics::Foo(GPRRegToInteger<uint32_t>(arg0));") 174 175 176 def test_get_semantics_player_hook_proto_raw_variant(self): 177 out = gen_intrinsics._get_semantics_player_hook_proto( 178 "Foo", { 179 "class": "vector_8/16", 180 "in": ["vec", "vec"], 181 "out": ["vec"], 182 "variants": ["raw"], 183 }) 184 self.assertEqual(out, "SimdRegister Foo(uint8_t size, " 185 "SimdRegister arg0, " 186 "SimdRegister arg1)") # pyformat: disable 187 188 189 def test_get_interpreter_hook_raw_vector_body(self): 190 out = gen_intrinsics._get_semantics_player_hook_raw_vector_body( 191 "Foo", { 192 "class": "vector_8/16", 193 "in": ["vec", "vec"], 194 "out": ["vec"], 195 }, gen_intrinsics._get_interpreter_hook_return_stmt) 196 self.assertSequenceEqual(list(out), 197 ("switch (size) {", 198 " case 64:" , 199 " return std::get<0>(intrinsics::Foo<64>(arg0, arg1));", 200 " case 128:", 201 " return std::get<0>(intrinsics::Foo<128>(arg0, arg1));", 202 " default:", 203 " LOG_ALWAYS_FATAL(\"Unsupported size\");", 204 "}")) # pyformat: disable 205 206 def test_get_interpreter_hook_vector_body_fp(self): 207 out = gen_intrinsics._get_interpreter_hook_vector_body( 208 "Foo", { 209 "class": "vector_16", 210 "in": ["vec", "vec"], 211 "out": ["vec"], 212 "variants": ["Float32"], 213 }) 214 self.assertSequenceEqual(list(out), 215 ("auto format = intrinsics::GetVectorFormatFP(elem_size, elem_num);", 216 "switch (format) {", 217 " case intrinsics::kVectorF32x4:" , 218 " return std::get<0>(intrinsics::Foo<intrinsics::Float32, 4>(arg0, arg1));", 219 " default:", 220 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 221 "}")) # pyformat: disable 222 223 224 def test_get_interpreter_hook_vector_body_unsigned_int(self): 225 out = gen_intrinsics._get_interpreter_hook_vector_body( 226 "Foo", { 227 "class": "vector_16", 228 "in": ["vec", "vec"], 229 "out": ["vec"], 230 "variants": ["unsigned_16/32/64"], 231 }) 232 self.assertSequenceEqual(list(out), 233 ("auto format = intrinsics::GetVectorFormatInt(elem_size, elem_num, false);", 234 "switch (format) {", 235 " case intrinsics::kVectorU16x8:" , 236 " return std::get<0>(intrinsics::Foo<uint16_t, 8>(arg0, arg1));", 237 " case intrinsics::kVectorU32x4:" , 238 " return std::get<0>(intrinsics::Foo<uint32_t, 4>(arg0, arg1));", 239 " case intrinsics::kVectorU64x2:" , 240 " return std::get<0>(intrinsics::Foo<uint64_t, 2>(arg0, arg1));", 241 " default:", 242 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 243 "}")) # pyformat: disable 244 245 246 def test_get_interpreter_hook_vector_body_signed_int(self): 247 out = gen_intrinsics._get_interpreter_hook_vector_body( 248 "Foo", { 249 "class": "vector_16", 250 "in": ["vec", "vec"], 251 "out": ["vec"], 252 "variants": ["signed_16/32"], 253 }) 254 self.assertSequenceEqual(list(out), 255 ("auto format = intrinsics::GetVectorFormatInt(elem_size, elem_num, true);", 256 "switch (format) {", 257 " case intrinsics::kVectorI16x8:" , 258 " return std::get<0>(intrinsics::Foo<int16_t, 8>(arg0, arg1));", 259 " case intrinsics::kVectorI32x4:" , 260 " return std::get<0>(intrinsics::Foo<int32_t, 4>(arg0, arg1));", 261 " default:", 262 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 263 "}")) # pyformat: disable 264 265 266 def test_get_interpreter_hook_vector_body_signed_and_unsigned_int(self): 267 out = gen_intrinsics._get_interpreter_hook_vector_body( 268 "Foo", { 269 "class": "vector_16", 270 "in": ["vec", "vec"], 271 "out": ["vec"], 272 "variants": ["signed_32", "unsigned_32"], 273 }) 274 self.assertSequenceEqual(list(out), 275 ("auto format = intrinsics::GetVectorFormatInt(elem_size, elem_num, is_signed);", 276 "switch (format) {", 277 " case intrinsics::kVectorI32x4:" , 278 " return std::get<0>(intrinsics::Foo<int32_t, 4>(arg0, arg1));", 279 " case intrinsics::kVectorU32x4:" , 280 " return std::get<0>(intrinsics::Foo<uint32_t, 4>(arg0, arg1));", 281 " default:", 282 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 283 "}")) # pyformat: disable 284 285 286 def test_get_interpreter_hook_vector_body_vector_8(self): 287 out = gen_intrinsics._get_interpreter_hook_vector_body( 288 "Foo", { 289 "class": "vector_8", 290 "in": ["vec", "vec"], 291 "out": ["vec"], 292 "variants": ["unsigned_32"], 293 }) 294 self.assertSequenceEqual(list(out), 295 ("auto format = intrinsics::GetVectorFormatInt(elem_size, elem_num, false);", 296 "switch (format) {", 297 " case intrinsics::kVectorU32x2:" , 298 " return std::get<0>(intrinsics::Foo<uint32_t, 2>(arg0, arg1));", 299 " default:", 300 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 301 "}")) # pyformat: disable 302 303 304 def test_get_interpreter_hook_vector_body_single(self): 305 out = gen_intrinsics._get_interpreter_hook_vector_body( 306 "Foo", { 307 "class": "vector_8/16/single", 308 "variants": ["signed_32"], 309 "in": ["vec", "fp_flags"], 310 "out": ["vec", "fp_flags"], 311 }) 312 self.assertSequenceEqual(list(out), 313 ("auto format = intrinsics::GetVectorFormatInt(elem_size, elem_num, true);", 314 "switch (format) {", 315 " case intrinsics::kVectorI32x2:" , 316 " return intrinsics::Foo<int32_t, 2>(arg0, GPRRegToInteger<uint32_t>(arg1));", 317 " case intrinsics::kVectorI32x4:" , 318 " return intrinsics::Foo<int32_t, 4>(arg0, GPRRegToInteger<uint32_t>(arg1));", 319 " case intrinsics::kVectorI32x1:" , 320 " return intrinsics::Foo<int32_t, 1>(arg0, GPRRegToInteger<uint32_t>(arg1));", 321 " default:", 322 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 323 "}")) # pyformat: disable 324 325 326 def test_get_translator_hook_call_expr_smoke(self): 327 out = gen_intrinsics._get_translator_hook_call_expr( 328 "Foo", { 329 "in": ["uint32_t"], 330 "out": ["uint32_t"], 331 }) 332 self.assertEqual(out, "CallIntrinsic<&intrinsics::Foo, Register>(arg0)") 333 334 335 def test_get_translator_hook_call_expr_void(self): 336 out = gen_intrinsics._get_translator_hook_call_expr( 337 "Foo", { 338 "in": [], 339 "out": [], 340 }) 341 self.assertEqual(out, "CallIntrinsic<&intrinsics::Foo, void>()") 342 343 344 def test_get_translator_hook_raw_vector_body(self): 345 out = gen_intrinsics._get_semantics_player_hook_raw_vector_body( 346 "Foo", { 347 "class": "vector_8/16", 348 "in": ["vec", "vec"], 349 "out": ["vec"], 350 }, gen_intrinsics._get_translator_hook_return_stmt) 351 self.assertSequenceEqual(list(out), 352 ("switch (size) {", 353 " case 64:", 354 " return CallIntrinsic<&intrinsics::Foo<64>, SimdRegister>(arg0, arg1);", 355 " case 128:", 356 " return CallIntrinsic<&intrinsics::Foo<128>, SimdRegister>(arg0, arg1);", 357 " default:", 358 " LOG_ALWAYS_FATAL(\"Unsupported size\");", 359 "}")) # pyformat: disable 360 361 362 def test_get_translator_hook_vector_body(self): 363 out = gen_intrinsics._get_semantics_player_hook_vector_body( 364 "Foo", { 365 "class": "vector_8/16/single", 366 "variants": ["signed_32"], 367 "in": ["vec", "fp_flags"], 368 "out": ["vec", "fp_flags"], 369 }, gen_intrinsics._get_translator_hook_return_stmt) 370 self.assertSequenceEqual(list(out), 371 ("auto format = intrinsics::GetVectorFormatInt(elem_size, elem_num, true);", 372 "switch (format) {", 373 " case intrinsics::kVectorI32x2:" , 374 " return CallIntrinsic<&intrinsics::Foo<int32_t, 2>, std::tuple<SimdRegister, Register>>(arg0, arg1);", 375 " case intrinsics::kVectorI32x4:" , 376 " return CallIntrinsic<&intrinsics::Foo<int32_t, 4>, std::tuple<SimdRegister, Register>>(arg0, arg1);", 377 " case intrinsics::kVectorI32x1:" , 378 " return CallIntrinsic<&intrinsics::Foo<int32_t, 1>, std::tuple<SimdRegister, Register>>(arg0, arg1);", 379 " default:", 380 " LOG_ALWAYS_FATAL(\"Unsupported format\");", 381 "}")) # pyformat: disable 382 383if __name__ == "__main__": 384 unittest.main(verbosity=2) 385