From b7decb3923548ed2e0b9b15231ddbfc1e53f0957 Mon Sep 17 00:00:00 2001 From: Madeline Busig Date: Thu, 29 Aug 2024 22:07:08 -0700 Subject: [PATCH] Add fixed point multiplication tests --- CMakeLists.txt | 2 +- include/mtl/tests/fixed.hpp | 41 ++++++++++++++++++++++ src/tests/fixed.cpp | 69 +++++++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 include/mtl/tests/fixed.hpp create mode 100644 src/tests/fixed.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 712f259..366925e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ message("Compiling MTL for ${CMAKE_SYSTEM_PROCESSOR}") # build system to automatically re-run CMake if the glob changes, solving the # major issue with globbing. May have a performance impact, but it should be # negligible compared to the time spent building. -file(GLOB mtl_sources_common LIST_DIRECTORIES false CONFIGURE_DEPENDS src/*.cpp src/*.c src/*.s) +file(GLOB mtl_sources_common LIST_DIRECTORIES false CONFIGURE_DEPENDS src/*.cpp src/*.c src/*.s src/tests/*.cpp) file(GLOB mtl_sources_armv4t LIST_DIRECTORIES false CONFIGURE_DEPENDS src/armv4t/*.cpp src/armv4t/*.c src/armv4t/*.s) file(GLOB mtl_sources_gba LIST_DIRECTORIES false CONFIGURE_DEPENDS src/gba/*.cpp src/gba/*.c src/gba/*.s) diff --git a/include/mtl/tests/fixed.hpp b/include/mtl/tests/fixed.hpp new file mode 100644 index 0000000..63b5774 --- /dev/null +++ b/include/mtl/tests/fixed.hpp @@ -0,0 +1,41 @@ +#pragma once + +#include "mtl/test.hpp" + +#include "mtl/fixed.hpp" + +namespace mtl { + +namespace test { + +class fixed_suite : public suite { +public: + fixed_suite() { + add_test(&construction, "construction"); + add_test(&addition, "addition"); + add_test(&subtraction, "subtraction"); + add_test(&multiplication, "multiplication"); + add_test(&mult_overflow, "mult_overflow"); + add_test(&division, "division"); + } + + virtual string_view name() { + return "fixed_suite"; + } + + static bool construction() { + return fixed(7).raw() == 7 * 64; + } + + // All tests are placed in IWRAM in ARM mode. + GBA_IWRAM ARM_MODE static bool addition(); + GBA_IWRAM ARM_MODE static bool subtraction(); + GBA_IWRAM ARM_MODE static bool multiplication(); + GBA_IWRAM ARM_MODE static bool mult_overflow(); + GBA_IWRAM ARM_MODE static bool division(); +}; + +} // namespace test + +} // namespace mtl + diff --git a/src/tests/fixed.cpp b/src/tests/fixed.cpp new file mode 100644 index 0000000..6f14fef --- /dev/null +++ b/src/tests/fixed.cpp @@ -0,0 +1,69 @@ +#include "mtl/tests/fixed.hpp" + +#include "mtl/target.hpp" +#include "mtl/fixed.hpp" + +TARGET_ARM_MODE + +namespace mtl { +namespace test{ + +bool fixed_suite::addition() { + struct { + NOINLINE fixed operator()(fixed x, fixed y) { + return x + y; + } + } f; + + return f(3, 4) == fixed(7); +} + +bool fixed_suite::subtraction() { + struct { + NOINLINE fixed operator()(fixed x, fixed y) { + return x - y; + } + } f; + + return f(8, 3) == fixed(5); +} + +bool fixed_suite::multiplication() { + struct { + NOINLINE fixed operator()(fixed x, fixed y) { + return x * y; + } + } f; + + return f(3, 4) == fixed(12); +} + +bool fixed_suite::mult_overflow() { + // This tests fixed point multiplication where the intermediate result + // (x.raw * y.raw) overflows int32 max still works. (IE. int64 multiplication + // is used internally) + struct { + NOINLINE fixed operator()(fixed x, fixed y) { + return x * y; + } + } f; + + return f(1048575, 8) == fixed(8388600); +} + +bool fixed_suite::division() { + struct { + NOINLINE fixed operator()(fixed x, fixed y) { + return x / y; + } + } f; + + return f(73, 13) == fixed(73.0 / 13.0); +} + + +} +} + +TARGET_END_MODE +