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 // Test call from asembly
17
18 #include <iostream>
19 #include <cstdint>
20 #include <cmath>
21 #include <cassert>
22
23 #include <gtest/gtest.h>
24
25 class AsmCaller : public ::testing::Test {
26 };
27
28 #define EMITED_ONE_PARAM_INST_LIST(DEF) \
29 DEF(mov, [](auto param) { return param; }) \
30 DEF(neg, [](auto param) { return -param; }) \
31 DEF(abs, [](auto param) { return (param > 0) ? param : -param; }) \
32 DEF(not, [](auto param) { return -param - 1L; })
33
34 #define EMITED_TWO_PARAM_INST_LIST(DEF) \
35 DEF(add, [](auto param1, auto param2) { return param1 + param2; }) \
36 DEF(sub, [](auto param1, auto param2) { return param1 - param2; }) \
37 DEF(mul, [](auto param1, auto param2) { return param1 * param2; }) \
38 DEF(and, [](auto param1, auto param2) { return param1 & param2; }) \
39 DEF(or, [](auto param1, auto param2) { return param1 | param2; }) \
40 DEF(xor, [](auto param1, auto param2) { \
41 return param1 ^ param2; \
42 })
43
44 #define C_EXTERN_ONE_PARAM(opc, param) \
45 extern "C" std::uint8_t test_##opc##_8(std::uint8_t); \
46 extern "C" std::uint16_t test_##opc##_16(std::uint16_t); \
47 extern "C" std::uint32_t test_##opc##_32(std::uint32_t); \
48 extern "C" std::uint64_t test_##opc##_64(std::uint64_t);
49
50 EMITED_ONE_PARAM_INST_LIST(C_EXTERN_ONE_PARAM)
51
52 #define C_EXTERN_TWO_PARAM(opc, param) \
53 extern "C" std::uint8_t test_##opc##_8(std::uint8_t, std::uint8_t); \
54 extern "C" std::uint16_t test_##opc##_16(std::uint16_t, std::uint16_t); \
55 extern "C" std::uint32_t test_##opc##_32(std::uint32_t, std::uint32_t); \
56 extern "C" std::uint64_t test_##opc##_64(std::uint64_t, std::uint64_t);
57
58 EMITED_TWO_PARAM_INST_LIST(C_EXTERN_TWO_PARAM)
59
TEST_F(AsmCaller, call_math)60 TEST_F(AsmCaller, call_math)
61 {
62 std::int8_t ui8 = 1;
63 std::int8_t ui8_2 = -12;
64 std::int16_t ui16 = 6518;
65 std::int16_t ui16_2 = 6;
66 std::int32_t ui32 = 3;
67 std::int32_t ui32_2 = 0xecf27abf;
68 std::int64_t ui64 = 2423590325;
69 std::int64_t ui64_2 = 8;
70
71 #ifdef STDOUT_PRINT
72 #define CALL_ONE_PARAM_OUTPUT(opc, param) \
73 std::cerr << "------------ OUTPUT FOR " << #opc << "------------\n"; \
74 std::cerr << "ui8 result:" << std::hex << static_cast<uint64_t>(test_##opc##_8(ui8)) \
75 << " input:" << static_cast<uint64_t>(ui8) << "\n"; \
76 std::cerr << "ui16 result:" << std::hex << static_cast<uint64_t>(test_##opc##_16(ui16)) \
77 << " input:" << static_cast<uint64_t>(ui16) << "\n"; \
78 std::cerr << "ui32 result:" << std::hex << static_cast<uint64_t>(test_##opc##_32(ui32)) \
79 << " input:" << static_cast<uint64_t>(ui32) << "\n"; \
80 std::cerr << "ui64 result:" << std::hex << static_cast<uint64_t>(test_##opc##_64(ui64)) \
81 << " input:" << static_cast<uint64_t>(ui64) << "\n";
82 #else
83 #define CALL_ONE_PARAM_OUTPUT(opc, param) \
84 EXPECT_EQ(test_##opc##_8(ui8), static_cast<uint8_t>(param(ui8))); \
85 EXPECT_EQ(test_##opc##_16(ui16), static_cast<uint16_t>(param(ui16))); \
86 EXPECT_EQ(test_##opc##_32(ui32), static_cast<uint32_t>(param(ui32))); \
87 EXPECT_EQ(test_##opc##_64(ui64), static_cast<uint64_t>(param(ui64)));
88 #endif
89
90 EMITED_ONE_PARAM_INST_LIST(CALL_ONE_PARAM_OUTPUT)
91
92 #ifdef STDOUT_PRINT
93 #define CALL_TWO_PARAM_OUTPUT(opc, param) \
94 std::cerr << "------------ OUTPUT FOR " << #opc << "------------\n"; \
95 std::cerr << "ui8 result:" << std::hex << static_cast<uint64_t>(test_##opc##_8(ui8, ui8_2)) \
96 << " input_1:" << static_cast<uint64_t>(ui8) << " input_2:" << static_cast<uint64_t>(ui8_2) << "\n"; \
97 std::cerr << "ui16 result:" << std::hex << static_cast<uint64_t>(test_##opc##_16(ui16, ui16_2)) \
98 << " input:" << static_cast<uint64_t>(ui16) << " input_2:" << static_cast<uint64_t>(ui16_2) << "\n"; \
99 std::cerr << "ui32 result:" << std::hex << static_cast<uint64_t>(test_##opc##_32(ui32, ui32_2)) \
100 << " input:" << static_cast<uint64_t>(ui32) << " input_2:" << static_cast<uint64_t>(ui32_2) << "\n"; \
101 std::cerr << "ui64 result:" << std::hex << static_cast<uint64_t>(test_##opc##_64(ui64, ui64_2)) \
102 << " input:" << static_cast<uint64_t>(ui64) << " input_2:" << static_cast<uint64_t>(ui64_2) << "\n";
103 #else
104 #define CALL_TWO_PARAM_OUTPUT(opc, param) \
105 EXPECT_EQ(test_##opc##_8(ui8, ui8_2), static_cast<uint8_t>(param(ui8, ui8_2))); \
106 EXPECT_EQ(test_##opc##_16(ui16, ui16_2), static_cast<uint16_t>(param(ui16, ui16_2))); \
107 EXPECT_EQ(test_##opc##_32(ui32, ui32_2), static_cast<uint32_t>(param(ui32, ui32_2))); \
108 EXPECT_EQ(test_##opc##_64(ui64, ui64_2), static_cast<uint64_t>(param(ui64, ui64_2)));
109 #endif
110 EMITED_TWO_PARAM_INST_LIST(CALL_TWO_PARAM_OUTPUT)
111 }
112