From 6df1eda7e7e7cc00f900f06b0370ebf4bc05795e Mon Sep 17 00:00:00 2001 From: $_9 Date: Sun, 6 Aug 2023 22:27:54 +0200 Subject: [PATCH 1/2] inline assembly to masm change --- asm_lib/Source.cpp | 21 +++- asm_lib/asm_lib.vcxproj | 7 ++ asm_lib/asm_lib.vcxproj.filters | 5 + asm_lib/asm_math.asm | 117 ++++++++++++++++++ asm_lib/asm_math.cpp | 212 ++++++++++++++++---------------- asm_lib/asm_math.hpp | 65 +++++++--- 6 files changed, 299 insertions(+), 128 deletions(-) create mode 100644 asm_lib/asm_math.asm diff --git a/asm_lib/Source.cpp b/asm_lib/Source.cpp index 156d095..22f3721 100644 --- a/asm_lib/Source.cpp +++ b/asm_lib/Source.cpp @@ -1,9 +1,24 @@ #include #include +#include + #include "asm_math.hpp" -int main() -{ - getchar(); +int main() { + srand(time(NULL)); + for (auto i = 0u; i < 10000; ++i) { + float a = (rand() % 1000) + 1; + float b = (rand() % 1000) + 1; + int cpp_mod = (int)a % (int)b; + float asm_mod = asm_math::asm_mod(a, b); + printf("C++ Modulo: %d\n", cpp_mod); + printf("ASM Modulo: %f\n", asm_mod); + if (cpp_mod != asm_mod) { + printf("C++ Modulo doesnt match the ASM modulo, stopping at iteration %ud with a: %f and b: %f!\n", i, a, b); + Sleep(10'000); + break; + } + } + (void)_getch(); return 0; } \ No newline at end of file diff --git a/asm_lib/asm_lib.vcxproj b/asm_lib/asm_lib.vcxproj index 4c628b0..74947b0 100644 --- a/asm_lib/asm_lib.vcxproj +++ b/asm_lib/asm_lib.vcxproj @@ -55,6 +55,7 @@ + @@ -132,6 +133,8 @@ true NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true + stdcpp20 + stdc17 Console @@ -147,7 +150,11 @@ + + + + \ No newline at end of file diff --git a/asm_lib/asm_lib.vcxproj.filters b/asm_lib/asm_lib.vcxproj.filters index 0b24f95..22e94b1 100644 --- a/asm_lib/asm_lib.vcxproj.filters +++ b/asm_lib/asm_lib.vcxproj.filters @@ -27,4 +27,9 @@ Header Files + + + Source Files + + \ No newline at end of file diff --git a/asm_lib/asm_math.asm b/asm_lib/asm_math.asm new file mode 100644 index 0000000..efd48c9 --- /dev/null +++ b/asm_lib/asm_math.asm @@ -0,0 +1,117 @@ +.code + +asm_abs proc + sub rsp, 16 + + movups [rsp], xmm0 + + fld dword ptr [rsp] + + fabs + + fstp dword ptr [rsp] + + movups xmm0, [rsp] + + add rsp, 16 + ret +asm_abs endp + +asm_mod proc + sub rsp, 32 + + movups dword ptr [rsp], xmm0 + movups dword ptr [rsp+16], xmm1 + + fld dword ptr [rsp+16] + fld dword ptr [rsp] + + fprem + + fstp dword ptr [rsp] + fstp ST(1) ; Clear ST(1) where we store the divisor + + movups xmm0, dword ptr [rsp] + + add rsp, 32 + + ret +asm_mod endp + +asm_ceil proc + vroundss xmm0, xmm0, xmm0, 2h + ret +asm_ceil endp + +asm_floor proc + vroundss xmm0, xmm0, xmm0, 1h + ret +asm_floor endp + +asm_round proc + vroundss xmm0, xmm0, xmm0, 0h + ret +asm_round endp + +asm_sqrt proc + vsqrtss xmm0, xmm0, xmm0 + ret +asm_sqrt endp + +asm_pow proc + mov rcx, rdx + dec rcx + movss xmm1, xmm0 + asm_loop: + mulss xmm0, xmm1 + loop asm_loop + ret +asm_pow endp + +asm_sin proc + sub rsp, 16 + movups dword ptr [rsp], xmm0 + fld dword ptr [rsp] + fsin + fstp dword ptr [rsp] + movups xmm0, [rsp] + add rsp, 16 + ret +asm_sin endp + +asm_cos proc + sub rsp, 16 + movups dword ptr [rsp], xmm0 + fld dword ptr [rsp] + fcos + fstp dword ptr [rsp] + movups xmm0, [rsp] + add rsp, 16 + ret +asm_cos endp + +asm_tan proc + sub rsp, 16 + movups dword ptr [rsp], xmm0 + fld dword ptr [rsp] + fptan + fstp ST(0) ; Skip over the first value on the FPU stack, because fptan pushes 1.0 onto the stack and stores the result in ST(1)... + fstp dword ptr [rsp] + movups xmm0, [rsp] + add rsp, 16 + ret +asm_tan endp + +asm_atan proc + sub rsp, 16 + movups dword ptr [rsp], xmm0 + fld1 + fld dword ptr [rsp] + fpatan + fstp dword ptr [rsp] + movups xmm0, [rsp] + add rsp, 16 + ret +asm_atan endp + +end diff --git a/asm_lib/asm_math.cpp b/asm_lib/asm_math.cpp index 72eca80..ea38b3d 100644 --- a/asm_lib/asm_math.cpp +++ b/asm_lib/asm_math.cpp @@ -1,109 +1,109 @@ #include "asm_math.hpp" -float asm_math::asm_abs(float x) -{ - __asm - { - fld x - fabs - fstp x - } - return x; -} +//float asm_math::asm_abs(float x) +//{ +// __asm +// { +// fld x +// fabs +// fstp x +// } +// return x; +//} +// +//float asm_math::asm_mod(float x, float y) +//{ +// __asm +// { +// fld y +// fld x +// fprem +// fstp x +// fstp y +// } +// return x; +//} +// +//float asm_math::asm_floor(float x) +//{ +// __asm +// { +// fld x +// frndint +// fstp x +// } +// return x; +//} +// +//float __vectorcall asm_math::asm_sqrt(float x) +//{ +// /*__asm +// { +// fld x +// fsqrt +// fstp x +// }*/ +// return masm_sqrt(x);; +//} -float asm_math::asm_mod(float x, float y) -{ - __asm - { - fld y - fld x - fprem - fstp x - fstp y - } - return x; -} - -float asm_math::asm_floor(float x) -{ - __asm - { - fld x - frndint - fstp x - } - return x; -} - -float asm_math::asm_sqrt(float x) -{ - __asm - { - fld x - fsqrt - fstp x - } - return x; -} - -float asm_math::asm_pow(float x, int y) -{ - __asm - { - mov eax, y - fld x - - asm_loop: - fmul x - dec eax - cmp eax, 1 - jne asm_loop - - fstp x - } - return x; -} - -float asm_math::asm_sin(float x) -{ - __asm - { - fld x - fsin - fstp x - } - return x; -} - -float asm_math::asm_cos(float x) -{ - __asm - { - fld x - fcos - fstp x - } - return x; -} - -float asm_math::asm_tan(float x) -{ - __asm - { - fld x - fptan - fstp x - } - return x; -} - -float asm_math::asm_atan(float x) -{ - __asm - { - fld x - fpatan - fstp x - } - return x; -} +//float asm_math::asm_pow(float x, int y) +//{ +// __asm +// { +// mov eax, y +// fld x +// +// asm_loop: +// fmul x +// dec eax +// cmp eax, 1 +// jne asm_loop +// +// fstp x +// } +// return x; +//} +// +//float asm_math::asm_sinq(float x) +//{ +// __asm +// { +// fld x +// fsin +// fstp x +// } +// return x; +//} +// +//float asm_math::asm_cos(float x) +//{ +// __asm +// { +// fld x +// fcos +// fstp x +// } +// return x; +//} +// +//float asm_math::asm_tan(float x) +//{ +// __asm +// { +// fld x +// fptan +// fstp x +// } +// return x; +//} +// +//float asm_math::asm_atan(float x) +//{ +// __asm +// { +// fld x +// fpatan +// fstp x +// } +// return x; +//} diff --git a/asm_lib/asm_math.hpp b/asm_lib/asm_math.hpp index 21d9cbe..9473a6b 100644 --- a/asm_lib/asm_math.hpp +++ b/asm_lib/asm_math.hpp @@ -1,22 +1,49 @@ #pragma once -namespace asm_math -{ - float asm_abs(float x); - - float asm_mod(float x, float y); - - float asm_floor(float x); - - float asm_sqrt(float x); - - float asm_pow(float x, int y); - - float asm_sin(float x); - - float asm_cos(float x); - - float asm_tan(float x); - - float asm_atan(float x); +namespace asm_math { + extern "C" float asm_abs(float x); + + extern "C" float asm_mod(float x, float y); + + extern "C" float asm_ceil(float x); + + extern "C" float asm_floor(float x); + + extern "C" float asm_round(float x); + + extern "C" float asm_sqrt(float x); + + extern "C" float asm_pow(float x, int y); + + /** + * Calculates a sine for a given number. + * + * @param[in] x The number which the sine will be calculated for. + * @returns The sine in radians. + */ + extern "C" float asm_sin(float x); + + /** + * Calculates a cosine for a given number. + * + * @param[in] x The number which the cosine will be calculated for. + * @returns The cosine in radians. + */ + extern "C" float asm_cos(float x); + + /** + * Calculates a tangent for a given number. + * + * @param[in] x The number which the tangent will be calculated for. + * @returns The tangent in radians. + */ + extern "C" float asm_tan(float x); + + /** + * Calculates an inverse tangent for a given number. + * + * @param[in] x The number which the inverse tangent will be calculated for. + * @returns The inverse tangent in radians. + */ + extern "C" float asm_atan(float x); } \ No newline at end of file From 2aeeae430d732a96e9e442caefb7eb1cb395923d Mon Sep 17 00:00:00 2001 From: $_9 Date: Mon, 7 Aug 2023 10:33:02 +0200 Subject: [PATCH 2/2] minor changes --- asm_lib/Source.cpp | 16 +---- asm_lib/asm_lib.vcxproj | 1 - asm_lib/asm_lib.vcxproj.filters | 3 - asm_lib/asm_math.asm | 59 +++++++++-------- asm_lib/asm_math.cpp | 109 -------------------------------- asm_lib/asm_math.hpp | 58 ++++------------- 6 files changed, 46 insertions(+), 200 deletions(-) delete mode 100644 asm_lib/asm_math.cpp diff --git a/asm_lib/Source.cpp b/asm_lib/Source.cpp index 22f3721..55ac962 100644 --- a/asm_lib/Source.cpp +++ b/asm_lib/Source.cpp @@ -4,21 +4,7 @@ #include "asm_math.hpp" -int main() { - srand(time(NULL)); - for (auto i = 0u; i < 10000; ++i) { - float a = (rand() % 1000) + 1; - float b = (rand() % 1000) + 1; - int cpp_mod = (int)a % (int)b; - float asm_mod = asm_math::asm_mod(a, b); - printf("C++ Modulo: %d\n", cpp_mod); - printf("ASM Modulo: %f\n", asm_mod); - if (cpp_mod != asm_mod) { - printf("C++ Modulo doesnt match the ASM modulo, stopping at iteration %ud with a: %f and b: %f!\n", i, a, b); - Sleep(10'000); - break; - } - } +int main() { (void)_getch(); return 0; } \ No newline at end of file diff --git a/asm_lib/asm_lib.vcxproj b/asm_lib/asm_lib.vcxproj index 74947b0..76d1ecf 100644 --- a/asm_lib/asm_lib.vcxproj +++ b/asm_lib/asm_lib.vcxproj @@ -144,7 +144,6 @@ - diff --git a/asm_lib/asm_lib.vcxproj.filters b/asm_lib/asm_lib.vcxproj.filters index 22e94b1..f6289d8 100644 --- a/asm_lib/asm_lib.vcxproj.filters +++ b/asm_lib/asm_lib.vcxproj.filters @@ -18,9 +18,6 @@ Source Files - - Source Files - diff --git a/asm_lib/asm_math.asm b/asm_lib/asm_math.asm index efd48c9..819d462 100644 --- a/asm_lib/asm_math.asm +++ b/asm_lib/asm_math.asm @@ -1,6 +1,6 @@ .code -asm_abs proc +abs proc sub rsp, 16 movups [rsp], xmm0 @@ -11,13 +11,13 @@ asm_abs proc fstp dword ptr [rsp] - movups xmm0, [rsp] + mov rax, [rsp] add rsp, 16 ret -asm_abs endp +abs endp -asm_mod proc +modulo proc sub rsp, 32 movups dword ptr [rsp], xmm0 @@ -29,36 +29,36 @@ asm_mod proc fprem fstp dword ptr [rsp] - fstp ST(1) ; Clear ST(1) where we store the divisor + fstp ST(0) movups xmm0, dword ptr [rsp] add rsp, 32 ret -asm_mod endp +modulo endp -asm_ceil proc +ceil proc vroundss xmm0, xmm0, xmm0, 2h ret -asm_ceil endp +ceil endp -asm_floor proc +floor proc vroundss xmm0, xmm0, xmm0, 1h ret -asm_floor endp +floor endp -asm_round proc +round proc vroundss xmm0, xmm0, xmm0, 0h ret -asm_round endp +round endp -asm_sqrt proc +sqrt proc vsqrtss xmm0, xmm0, xmm0 ret -asm_sqrt endp +sqrt endp -asm_pow proc +pow proc mov rcx, rdx dec rcx movss xmm1, xmm0 @@ -66,9 +66,9 @@ asm_pow proc mulss xmm0, xmm1 loop asm_loop ret -asm_pow endp +pow endp -asm_sin proc +sin proc sub rsp, 16 movups dword ptr [rsp], xmm0 fld dword ptr [rsp] @@ -77,9 +77,9 @@ asm_sin proc movups xmm0, [rsp] add rsp, 16 ret -asm_sin endp +sin endp -asm_cos proc +cos proc sub rsp, 16 movups dword ptr [rsp], xmm0 fld dword ptr [rsp] @@ -88,30 +88,37 @@ asm_cos proc movups xmm0, [rsp] add rsp, 16 ret -asm_cos endp +cos endp -asm_tan proc +tan proc sub rsp, 16 movups dword ptr [rsp], xmm0 fld dword ptr [rsp] fptan - fstp ST(0) ; Skip over the first value on the FPU stack, because fptan pushes 1.0 onto the stack and stores the result in ST(1)... + fstp ST(0) fstp dword ptr [rsp] movups xmm0, [rsp] add rsp, 16 ret -asm_tan endp +tan endp -asm_atan proc - sub rsp, 16 +atan proc + sub rsp, 16 + movups dword ptr [rsp], xmm0 + fld1 fld dword ptr [rsp] + fpatan + fstp dword ptr [rsp] + fstp ST(0) + movups xmm0, [rsp] + add rsp, 16 ret -asm_atan endp +atan endp end diff --git a/asm_lib/asm_math.cpp b/asm_lib/asm_math.cpp deleted file mode 100644 index ea38b3d..0000000 --- a/asm_lib/asm_math.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "asm_math.hpp" - -//float asm_math::asm_abs(float x) -//{ -// __asm -// { -// fld x -// fabs -// fstp x -// } -// return x; -//} -// -//float asm_math::asm_mod(float x, float y) -//{ -// __asm -// { -// fld y -// fld x -// fprem -// fstp x -// fstp y -// } -// return x; -//} -// -//float asm_math::asm_floor(float x) -//{ -// __asm -// { -// fld x -// frndint -// fstp x -// } -// return x; -//} -// -//float __vectorcall asm_math::asm_sqrt(float x) -//{ -// /*__asm -// { -// fld x -// fsqrt -// fstp x -// }*/ -// return masm_sqrt(x);; -//} - -//float asm_math::asm_pow(float x, int y) -//{ -// __asm -// { -// mov eax, y -// fld x -// -// asm_loop: -// fmul x -// dec eax -// cmp eax, 1 -// jne asm_loop -// -// fstp x -// } -// return x; -//} -// -//float asm_math::asm_sinq(float x) -//{ -// __asm -// { -// fld x -// fsin -// fstp x -// } -// return x; -//} -// -//float asm_math::asm_cos(float x) -//{ -// __asm -// { -// fld x -// fcos -// fstp x -// } -// return x; -//} -// -//float asm_math::asm_tan(float x) -//{ -// __asm -// { -// fld x -// fptan -// fstp x -// } -// return x; -//} -// -//float asm_math::asm_atan(float x) -//{ -// __asm -// { -// fld x -// fpatan -// fstp x -// } -// return x; -//} diff --git a/asm_lib/asm_math.hpp b/asm_lib/asm_math.hpp index 9473a6b..1e71880 100644 --- a/asm_lib/asm_math.hpp +++ b/asm_lib/asm_math.hpp @@ -1,49 +1,15 @@ #pragma once -namespace asm_math { - extern "C" float asm_abs(float x); - - extern "C" float asm_mod(float x, float y); - - extern "C" float asm_ceil(float x); - - extern "C" float asm_floor(float x); - - extern "C" float asm_round(float x); - - extern "C" float asm_sqrt(float x); - - extern "C" float asm_pow(float x, int y); - - /** - * Calculates a sine for a given number. - * - * @param[in] x The number which the sine will be calculated for. - * @returns The sine in radians. - */ - extern "C" float asm_sin(float x); - - /** - * Calculates a cosine for a given number. - * - * @param[in] x The number which the cosine will be calculated for. - * @returns The cosine in radians. - */ - extern "C" float asm_cos(float x); - - /** - * Calculates a tangent for a given number. - * - * @param[in] x The number which the tangent will be calculated for. - * @returns The tangent in radians. - */ - extern "C" float asm_tan(float x); - - /** - * Calculates an inverse tangent for a given number. - * - * @param[in] x The number which the inverse tangent will be calculated for. - * @returns The inverse tangent in radians. - */ - extern "C" float asm_atan(float x); +extern "C" namespace asm_math { + int abs(float x); + double modulo(float x, float y); + double ceil(float x); + double floor(float x); + double round(float x); + double sqrt(float x); + double pow(float x, int y); + double sin(float x); + double cos(float x); + double tan(float x); + double atan(float x); } \ No newline at end of file