| // Copyright 2023 Google LLC |
| // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| // SPDX-License-Identifier: Apache-2.0 |
| // |
| |
| #include <cstdio> |
| |
| #include "tests/kelvin_isa/kelvin_test.h" |
| |
| // clang-format off |
| #define TEST_GETVL_X(T, op, in) \ |
| { \ |
| int ref, dut; \ |
| if (sizeof(T) == 1) { \ |
| ref = std::min(vlb, in); \ |
| } else if (sizeof(T) == 2) { \ |
| ref = std::min(vlh, in); \ |
| } else if (sizeof(T) == 4) { \ |
| ref = std::min(vlw, in); \ |
| } else { \ |
| printf("**error(%d)[unknown getvl]\n", __LINE__); \ |
| exit(-1); \ |
| } \ |
| __asm__ __volatile_always__(ARGS_F_A_A(op, %0, %1) \ |
| : "=r"(dut) \ |
| : "r"(in)); \ |
| if (ref != dut) { \ |
| printf("**error(%d)[%s] %d : %d %d\n", __LINE__, op, in, ref, dut); \ |
| exit(-1); \ |
| } \ |
| } |
| #define TEST_GETVL_XX(T, op, in0, in1) \ |
| { \ |
| int ref, dut; \ |
| if (sizeof(T) == 1) { \ |
| ref = std::min(vlb, std::min(in0, in1)); \ |
| } else if (sizeof(T) == 2) { \ |
| ref = std::min(vlh, std::min(in0, in1)); \ |
| } else if (sizeof(T) == 4) { \ |
| ref = std::min(vlw, std::min(in0, in1)); \ |
| } else { \ |
| printf("**error(%d)[unknown getvl]\n", __LINE__); \ |
| exit(-1); \ |
| } \ |
| __asm__ __volatile_always__(ARGS_F_A_A_A(op, %0, %1, %2) \ |
| : "=r"(dut) \ |
| : "r"(in0), "r"(in1)); \ |
| if (ref != dut) { \ |
| printf("**error(%d)[%s] %d %d : %d %d\n", __LINE__, op, in0, in1, ref, \ |
| dut); \ |
| exit(-1); \ |
| } \ |
| } |
| // clang-format on |
| |
| int main() { |
| const int pad = 3; |
| int vlb, vlh, vlw; |
| // --------------------------------------------------------------------------- |
| // Test baseline. |
| getmaxvl_w(vlw); |
| getmaxvl_h(vlh); |
| getmaxvl_b(vlb); |
| if (vlw != VLENW) { |
| printf("**error(%d)[%s] %d\n", __LINE__, "getmaxvl.w", vlw); |
| exit(-1); |
| } |
| if (vlh != vlw * 2) { |
| printf("**error(%d)[%s] %d\n", __LINE__, "getmaxvl.h", vlh); |
| exit(-1); |
| } |
| if (vlb != vlw * 4) { |
| printf("**error(%d)[%s] %d\n", __LINE__, "getmaxvl.b", vlb); |
| exit(-1); |
| } |
| for (int i = 0; i < vlb + pad; ++i) { |
| TEST_GETVL_X(uint8_t, "getvl.b.x", i); |
| } |
| for (int i = 0; i < vlh + pad; ++i) { |
| TEST_GETVL_X(uint16_t, "getvl.h.x", i); |
| } |
| for (int i = 0; i < vlw + pad; ++i) { |
| TEST_GETVL_X(uint32_t, "getvl.w.x", i); |
| } |
| for (int i = 0; i < vlb + pad; ++i) { |
| for (int j = 0; j < vlb + pad; ++j) { |
| TEST_GETVL_XX(uint8_t, "getvl.b.xx", i, j); |
| } |
| } |
| for (int i = 0; i < vlh + pad; ++i) { |
| for (int j = 0; j < vlh + pad; ++j) { |
| TEST_GETVL_XX(uint16_t, "getvl.h.xx", i, j); |
| } |
| } |
| for (int i = 0; i < vlw + pad; ++i) { |
| for (int j = 0; j < vlw + pad; ++j) { |
| TEST_GETVL_XX(uint32_t, "getvl.w.xx", i, j); |
| } |
| } |
| // --------------------------------------------------------------------------- |
| // Test stripmine. |
| int vlw_p = vlw; |
| getmaxvl_w_m(vlw); |
| getmaxvl_h_m(vlh); |
| getmaxvl_b_m(vlb); |
| if (vlw != 4 * vlw_p) { |
| printf("**error(%d)[%s] %d\n", __LINE__, "getmaxvl.w.m", vlw); |
| exit(-1); |
| } |
| if (vlh != vlw * 2) { |
| printf("**error(%d)[%s] %d\n", __LINE__, "getmaxvl.h.m", vlh); |
| exit(-1); |
| } |
| if (vlb != vlw * 4) { |
| printf("**error(%d)[%s] %d\n", __LINE__, "getmaxvl.b.m", vlb); |
| exit(-1); |
| } |
| for (int i = 0; i < vlb + pad; ++i) { |
| TEST_GETVL_X(uint8_t, "getvl.b.x.m", i); |
| } |
| for (int i = 0; i < vlh + pad; ++i) { |
| TEST_GETVL_X(uint16_t, "getvl.h.x.m", i); |
| } |
| for (int i = 0; i < vlw + pad; ++i) { |
| TEST_GETVL_X(uint32_t, "getvl.w.x.m", i); |
| } |
| for (int i = 0; i < vlb + pad; ++i) { |
| for (int j = 0; j < vlb + pad; ++j) { |
| TEST_GETVL_XX(uint8_t, "getvl.b.xx.m", i, j); |
| } |
| } |
| for (int i = 0; i < vlh + pad; ++i) { |
| for (int j = 0; j < vlh + pad; ++j) { |
| TEST_GETVL_XX(uint16_t, "getvl.h.xx.m", i, j); |
| } |
| } |
| for (int i = 0; i < vlw + pad; ++i) { |
| for (int j = 0; j < vlw + pad; ++j) { |
| TEST_GETVL_XX(uint32_t, "getvl.w.xx.m", i, j); |
| } |
| } |
| return 0; |
| } |