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 25class 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 50EMITED_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 58EMITED_TWO_PARAM_INST_LIST(C_EXTERN_TWO_PARAM) 59 60TEST_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