https://git.reactos.org/?p=reactos.git;a=commitdiff;h=6fd6e9c306e35bac0225292854fd4c481797f567

commit 6fd6e9c306e35bac0225292854fd4c481797f567
Author:     Timo Kreuzer <timo.kreu...@reactos.org>
AuthorDate: Wed Aug 21 22:40:58 2024 +0300
Commit:     Timo Kreuzer <timo.kreu...@reactos.org>
CommitDate: Tue Aug 27 21:34:50 2024 +0300

    [COMPILER_APITEST] Add tests for float to int conversion
    
    These tests come with a VS solution, because that is the only way to test 
against a known good system, as the required runtime functions (like _ftol) are 
statically linked from the VS runtime library.
---
 modules/rostests/apitests/compiler/CMakeLists.txt  |   1 +
 .../apitests/compiler/compiler_apitest.sln         |  31 +++
 .../apitests/compiler/compiler_apitest.vcxproj     |  93 +++++++
 modules/rostests/apitests/compiler/floatconv.c     | 277 +++++++++++++++++++++
 modules/rostests/apitests/compiler/testlist.c      |   4 +
 5 files changed, 406 insertions(+)

diff --git a/modules/rostests/apitests/compiler/CMakeLists.txt 
b/modules/rostests/apitests/compiler/CMakeLists.txt
index 163a0220c03..f43a47600a8 100644
--- a/modules/rostests/apitests/compiler/CMakeLists.txt
+++ b/modules/rostests/apitests/compiler/CMakeLists.txt
@@ -6,6 +6,7 @@ if (MSVC OR ARCH STREQUAL "i386")
 endif()
 
 list(APPEND SOURCE
+    floatconv.c
     pseh.c
     pseh_cpp.cpp
     psehtest2.c
diff --git a/modules/rostests/apitests/compiler/compiler_apitest.sln 
b/modules/rostests/apitests/compiler/compiler_apitest.sln
new file mode 100644
index 00000000000..819d3e90633
--- /dev/null
+++ b/modules/rostests/apitests/compiler/compiler_apitest.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.11.35219.272
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "compiler_apitest", 
"compiler_apitest.vcxproj", "{CBB00980-3B4F-4006-973E-61B462D057B3}"
+EndProject
+Global
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution
+               Debug|x64 = Debug|x64
+               Debug|x86 = Debug|x86
+               Release|x64 = Release|x64
+               Release|x86 = Release|x86
+       EndGlobalSection
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Debug|x64.ActiveCfg = 
Debug|x64
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Debug|x64.Build.0 = 
Debug|x64
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Debug|x86.ActiveCfg = 
Debug|Win32
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Debug|x86.Build.0 = 
Debug|Win32
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Release|x64.ActiveCfg = 
Release|x64
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Release|x64.Build.0 = 
Release|x64
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Release|x86.ActiveCfg = 
Release|Win32
+               {CBB00980-3B4F-4006-973E-61B462D057B3}.Release|x86.Build.0 = 
Release|Win32
+       EndGlobalSection
+       GlobalSection(SolutionProperties) = preSolution
+               HideSolutionNode = FALSE
+       EndGlobalSection
+       GlobalSection(ExtensibilityGlobals) = postSolution
+               SolutionGuid = {F64379E4-70F2-4E62-90BC-00B1308C96D4}
+       EndGlobalSection
+EndGlobal
diff --git a/modules/rostests/apitests/compiler/compiler_apitest.vcxproj 
b/modules/rostests/apitests/compiler/compiler_apitest.vcxproj
new file mode 100644
index 00000000000..fa0fc6bd34f
--- /dev/null
+++ b/modules/rostests/apitests/compiler/compiler_apitest.vcxproj
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" 
xmlns="http://schemas.microsoft.com/developer/msbuild/2003";>
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>17.0</VCProjectVersion>
+    <Keyword>Win32Proj</Keyword>
+    <ProjectGuid>{cbb00980-3b4f-4006-973e-61b462d057b3}</ProjectGuid>
+    <RootNamespace>compilerapitest</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup>
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v142</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <UseDebugLibraries>true</UseDebugLibraries>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" 
Label="Configuration">
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" 
Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" 
Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <ItemDefinitionGroup>
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <SDLCheck>true</SDLCheck>
+      <ConformanceMode>true</ConformanceMode>
+      
<AdditionalIncludeDirectories>$(ProjectDir)..\include;$(ProjectDir)..\..\..\..\sdk\include\reactos;$(ProjectDir)..\..\..\..\sdk\lib\pseh\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      
<PreprocessorDefinitions>_CONSOLE;__VS_PROJECT__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <DisableSpecificWarnings>4532;4996</DisableSpecificWarnings>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
+    <ClCompile>
+      
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
+    <ClCompile>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
+    <ClCompile>
+      
<PreprocessorDefinitions>_X86_;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Platform)'=='x64'">
+    <ClCompile>
+      
<PreprocessorDefinitions>_AMD64_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="floatconv.c" />
+    <ClCompile Include="testlist.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/modules/rostests/apitests/compiler/floatconv.c 
b/modules/rostests/apitests/compiler/floatconv.c
new file mode 100644
index 00000000000..195c587b60b
--- /dev/null
+++ b/modules/rostests/apitests/compiler/floatconv.c
@@ -0,0 +1,277 @@
+/*
+ * PROJECT:     ReactOS API tests
+ * LICENSE:     MIT (https://spdx.org/licenses/MIT)
+ * PURPOSE:     Test for floating point conversion
+ * COPYRIGHT:   Copyright 2024 Timo Kreuzer <timo.kreu...@reactos.org>
+ */
+
+#include <apitest.h>
+
+/* Note: There are 2 behaviors for float to unsigned integer conversion:
+ * 1. The old behavior, which exists only on x86 and CL versions up to 
somewhere
+ *    between 19.40.33811 and 19.41.33923:
+ *     - If a negative float is cast to an unsigned integer, the result is 
ULONG_MAX
+ *       for uint32 and ULLONG_MAX for uint64.
+ *     - If a float is cast to an unsigned long and the value is larger than 
ULONG_MAX,
+ *       the result is ULONG_MAX.
+ * 2. The new behavior (all x64 and x86 versions after the ones mentioned 
above):
+ *     - If a negative float is cast to an unsigned integer, the result is the 
same as
+         first casting to the signed type, then casting to the unsigned type.
+ *     - If a float is cast to an unsigned integer and the value is too large 
for the type,
+ *       the result is 0 for uint32 and 0x8000000000000000 for uint64.
+ * In the old version, the float to unsigned conversion was inlined and used 
_ftoul2 and
+ * a comparison against 0x43e0000000000000 (9223372036854775808.0) to check 
for overflow.
+ * In the new version, the float to unsigned conversion is done by a call to 
_ftoul2_legacy,
+ * which checks for overflow by comparing against 0x5f800000 
(18446744073709551616.0) and
+ * then forwards the call to either _ftol2 or _ftoul2.
+ */
+
+#if defined(_M_IX86) && defined(__VS_PROJECT__) && (_MSC_FULL_VER < 194133923)
+#define OLD_BEHAVIOR
+#endif
+
+#ifdef OLD_BEHAVIOR
+#define ULONG_OVERFLOW ULONG_MAX
+#define ULONGLONG_OVERFLOW ULLONG_MAX
+#else
+#define ULONG_OVERFLOW 0ul
+#define ULONGLONG_OVERFLOW 0x8000000000000000ull
+#endif
+
+#ifdef __GNUC__
+#define todo_gcc todo_ros
+#else
+#define todo_gcc
+#endif
+
+__declspec(noinline)
+long cast_float_to_long(float f)
+{
+    return (long)f;
+}
+
+__declspec(noinline)
+unsigned long cast_float_to_ulong(float f)
+{
+    return (unsigned long)f;
+}
+
+__declspec(noinline)
+long cast_double_to_long(double d)
+{
+    return (long)d;
+}
+
+__declspec(noinline)
+unsigned long cast_double_to_ulong(double d)
+{
+    return (unsigned long)d;
+}
+
+__declspec(noinline)
+long long cast_float_to_longlong(float f)
+{
+    return (long long)f;
+}
+
+__declspec(noinline)
+unsigned long long cast_float_to_ulonglong(float f)
+{
+    return (unsigned long long)f;
+}
+
+__declspec(noinline)
+long long cast_double_to_longlong(double d)
+{
+    return (long long)d;
+}
+
+__declspec(noinline)
+unsigned long long cast_double_to_ulonglong(double d)
+{
+    return (unsigned long long)d;
+}
+
+void Test_float(void)
+{
+    // float to long cast
+    ok_eq_long(cast_float_to_long(0.0f), 0l);
+    ok_eq_long(cast_float_to_long(1.0f), 1l);
+    ok_eq_long(cast_float_to_long(-1.0f), -1l);
+    ok_eq_long(cast_float_to_long(0.5f), 0l);
+    ok_eq_long(cast_float_to_long(-0.5f), 0l);
+    ok_eq_long(cast_float_to_long(0.999999f), 0l);
+    ok_eq_long(cast_float_to_long(-0.999999f), 0l);
+    ok_eq_long(cast_float_to_long(2147483500.0f), 2147483520l);
+    ok_eq_long(cast_float_to_long(2147483583.999f), 2147483520l);
+    ok_eq_long(cast_float_to_long(-2147483583.999f), -2147483520l);
+    ok_eq_long(cast_float_to_long(2147483584.0f), LONG_MIN); // -2147483648
+    ok_eq_long(cast_float_to_long(2147483648.0f), LONG_MIN); // -2147483648
+    ok_eq_long(cast_float_to_long(-2147483648.0f), LONG_MIN); // -2147483648
+    ok_eq_long(cast_float_to_long(10000000000.0f), LONG_MIN);
+    ok_eq_long(cast_float_to_long(-10000000000.0f), LONG_MIN);
+
+    // float to unsigned long cast (positive values)
+    ok_eq_ulong(cast_float_to_ulong(0.0f), 0ul);
+    ok_eq_ulong(cast_float_to_ulong(1.0f), 1ul);
+    ok_eq_ulong(cast_float_to_ulong(0.5f), 0ul);
+    ok_eq_ulong(cast_float_to_ulong(0.999999f), 0ul);
+    ok_eq_ulong(cast_float_to_ulong(2147483648.0f), 2147483648ul); // 
0x80000000
+    ok_eq_ulong(cast_float_to_ulong(4294967150.0f), 4294967040ul); // 
0xFFFFFF00
+    ok_eq_ulong(cast_float_to_ulong(4294967294.0f), ULONG_OVERFLOW);
+
+    // float to unsigned long cast (negative values)
+    ok_eq_ulong(cast_float_to_ulong(-0.0f), 0ul);
+    ok_eq_ulong(cast_float_to_ulong(-0.5f), 0ul);
+    ok_eq_ulong(cast_float_to_ulong(-1.0f), ULONG_MAX);
+#ifdef OLD_BEHAVIOR
+    ok_eq_ulong(cast_float_to_ulong(-10.0f), ULONG_MAX);
+    ok_eq_ulong(cast_float_to_ulong(-1147483648.0f), ULONG_MAX);
+    ok_eq_ulong(cast_float_to_ulong(-2147483648.0f), ULONG_MAX);
+#else
+    ok_eq_ulong(cast_float_to_ulong(-10.0f), (unsigned long)-10);
+    ok_eq_ulong(cast_float_to_ulong(-1147483648.0f), (unsigned 
long)-1147483648ll);
+    ok_eq_ulong(cast_float_to_ulong(-2147483648.0f), (unsigned 
long)-2147483648ll);
+#endif
+
+    // float to long long cast
+    ok_eq_longlong(cast_float_to_longlong(0.0f), 0ll);
+    ok_eq_longlong(cast_float_to_longlong(1.0f), 1ll);
+    ok_eq_longlong(cast_float_to_longlong(-1.0f), -1ll);
+    ok_eq_longlong(cast_float_to_longlong(0.5f), 0ll);
+    ok_eq_longlong(cast_float_to_longlong(-0.5f), 0ll);
+    ok_eq_longlong(cast_float_to_longlong(0.999999f), 0ll);
+    ok_eq_longlong(cast_float_to_longlong(-0.999999f), 0ll);
+    ok_eq_longlong(cast_float_to_longlong(9223371761976868863.9999f), 
9223371487098961920ll);
+    ok_eq_longlong(cast_float_to_longlong(9223371761976868864.0f), LLONG_MIN);
+    ok_eq_longlong(cast_float_to_longlong(-9223371761976868863.9999f), 
-9223371487098961920ll);
+    ok_eq_longlong(cast_float_to_longlong(-9223371761976868864.0f), LLONG_MIN);
+    ok_eq_longlong(cast_float_to_longlong(100000000000000000000.0f), 
LLONG_MIN);
+    ok_eq_longlong(cast_float_to_longlong(-100000000000000000000.0f), 
LLONG_MIN);
+
+    // float to unsigned long long cast (positive values)
+    ok_eq_ulonglong(cast_float_to_ulonglong(0.0f), 0ull);
+    ok_eq_ulonglong(cast_float_to_ulonglong(1.0f), 1ull);
+    ok_eq_ulonglong(cast_float_to_ulonglong(0.5f), 0ull);
+    ok_eq_ulonglong(cast_float_to_ulonglong(0.999999f), 0ull);
+    ok_eq_ulonglong(cast_float_to_ulonglong(9223371487098961920.0f), 
9223371487098961920ull); // 0x7FFFFF8000000000
+    ok_eq_ulonglong(cast_float_to_ulonglong(9223372036854775808.0f), 
9223372036854775808ull); // 0x8000000000000000
+    ok_eq_ulonglong(cast_float_to_ulonglong(18446743523953737727.9f), 
18446742974197923840ull); // 0xFFFFFF0000000000
+    todo_gcc ok_eq_ulonglong(cast_float_to_ulonglong(18446743523953737728.0f), 
ULONGLONG_OVERFLOW); // 0x8000000000000000 / 0xFFFFFFFFFFFFFFFF
+    todo_gcc ok_eq_ulonglong(cast_float_to_ulonglong(20000000000000000000.0f), 
ULONGLONG_OVERFLOW); // 0x8000000000000000 / 0xFFFFFFFFFFFFFFFF
+
+    // float to unsigned long long cast (negative values)
+    ok_eq_ulonglong(cast_float_to_ulonglong(-0.0f), 0ull);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-0.5f), 0ull);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-1.0f), 18446744073709551615ull);
+#ifdef OLD_BEHAVIOR
+    ok_eq_ulonglong(cast_float_to_ulonglong(-10.0f), ULLONG_MAX);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-1147483648.0f), ULLONG_MAX);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-2147483648.0f), ULLONG_MAX);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-9223371761976868863.9f), 
ULLONG_MAX);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-9223371761976868864.0f), 
ULLONG_MAX);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-9223372036854775808.0f), 
ULLONG_MAX);
+#else
+    ok_eq_ulonglong(cast_float_to_ulonglong(-10.0f), (unsigned long long)-10);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-1147483648.0f), (unsigned long 
long)-1147483648ll);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-2147483648.0f), (unsigned long 
long)-2147483648ll);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-9223371761976868863.9f), 
(unsigned long long)-9223371487098961920);
+    ok_eq_ulonglong(cast_float_to_ulonglong(-9223371761976868864.0f), 
(unsigned long long)(-9223372036854775807ll - 1)); // 0x8000000000000000 / 
ULONGLONG_OVERFLOW
+    ok_eq_ulonglong(cast_float_to_ulonglong(-9223372036854775808.0f), 
(unsigned long long)(-9223372036854775807ll - 1)); // 0x8000000000000000 / 
ULONGLONG_OVERFLOW
+#endif
+    ok_eq_ulonglong(cast_float_to_ulonglong(-100000000000000000000.0f), 
ULONGLONG_OVERFLOW);
+}
+
+void Test_double(void)
+{
+    // double to long cast
+    ok_eq_long(cast_double_to_long(0.0), 0l);
+    ok_eq_long(cast_double_to_long(1.0), 1l);
+    ok_eq_long(cast_double_to_long(-1.0), -1l);
+    ok_eq_long(cast_double_to_long(0.5), 0l);
+    ok_eq_long(cast_double_to_long(-0.5), 0l);
+    ok_eq_long(cast_double_to_long(0.999999999), 0l);
+    ok_eq_long(cast_double_to_long(-0.999999999), 0l);
+    ok_eq_long(cast_double_to_long(2147483647.99999), 2147483647l);
+    ok_eq_long(cast_double_to_long(-2147483647.99999), -2147483647l);
+    ok_eq_long(cast_double_to_long(2147483648.0), LONG_MIN); // -2147483648
+    ok_eq_long(cast_double_to_long(-2147483648.0), LONG_MIN); // -2147483648
+    ok_eq_long(cast_double_to_long(10000000000.0), LONG_MIN);
+    ok_eq_long(cast_double_to_long(-10000000000.0), LONG_MIN);
+
+    // double to unsigned long cast (positive values)
+    ok_eq_ulong(cast_double_to_ulong(0.0), 0ul);
+    ok_eq_ulong(cast_double_to_ulong(1.0), 1ul);
+    ok_eq_ulong(cast_double_to_ulong(0.5), 0ul);
+    ok_eq_ulong(cast_double_to_ulong(0.999999999), 0ul);
+    ok_eq_ulong(cast_double_to_ulong(2147483648.0), 2147483648ul); // 
0x80000000
+    ok_eq_ulong(cast_double_to_ulong(4294967295.0), 4294967295ul); // 
0xFFFFFFFF
+    ok_eq_ulong(cast_double_to_ulong(4294967296.0), ULONG_OVERFLOW);
+
+    // double to unsigned long cast (negative values)
+    ok_eq_ulong(cast_double_to_ulong(-0.0), 0ul);
+    ok_eq_ulong(cast_double_to_ulong(-0.5), 0ul);
+    ok_eq_ulong(cast_double_to_ulong(-1.0), ULONG_MAX);
+#ifdef OLD_BEHAVIOR
+    ok_eq_ulong(cast_double_to_ulong(-10.0), ULONG_MAX);
+    ok_eq_ulong(cast_double_to_ulong(-1147483648.0), ULONG_MAX);
+    ok_eq_ulong(cast_double_to_ulong(-2147483648.0), ULONG_MAX);
+#else
+    ok_eq_ulong(cast_double_to_ulong(-10.0), (unsigned long)-10);
+    ok_eq_ulong(cast_double_to_ulong(-1147483648.0), (unsigned 
long)-1147483648ll);
+    ok_eq_ulong(cast_double_to_ulong(-2147483648.0), (unsigned 
long)-2147483648ll);
+#endif
+
+    // double to long long cast
+    ok_eq_longlong(cast_double_to_longlong(0.0), 0ll);
+    ok_eq_longlong(cast_double_to_longlong(1.0), 1ll);
+    ok_eq_longlong(cast_double_to_longlong(-1.0), -1ll);
+    ok_eq_longlong(cast_double_to_longlong(0.5), 0ll);
+    ok_eq_longlong(cast_double_to_longlong(-0.5), 0ll);
+    ok_eq_longlong(cast_double_to_longlong(0.999999), 0ll);
+    ok_eq_longlong(cast_double_to_longlong(-0.999999), 0ll);
+    ok_eq_longlong(cast_double_to_longlong(9223372036854775295.9), 
9223372036854774784ll);
+    ok_eq_longlong(cast_double_to_longlong(9223372036854775296.0), LLONG_MIN);
+    ok_eq_longlong(cast_double_to_longlong(-9223372036854775295.9), 
-9223372036854774784ll);
+    ok_eq_longlong(cast_double_to_longlong(-9223372036854775296.0), LLONG_MIN);
+    ok_eq_longlong(cast_double_to_longlong(100000000000000000000.0), 
LLONG_MIN);
+    ok_eq_longlong(cast_double_to_longlong(-100000000000000000000.0), 
LLONG_MIN);
+
+    // double to unsigned long long cast (positive values)
+    ok_eq_ulonglong(cast_double_to_ulonglong(0.0), 0ull);
+    ok_eq_ulonglong(cast_double_to_ulonglong(1.0), 1ull);
+    ok_eq_ulonglong(cast_double_to_ulonglong(0.5), 0ull);
+    ok_eq_ulonglong(cast_double_to_ulonglong(0.999999), 0ull);
+    ok_eq_ulonglong(cast_double_to_ulonglong(9223372036854774784.0), 
9223372036854774784ull); // 0x7FFFFFFFFFFFFC00
+    ok_eq_ulonglong(cast_double_to_ulonglong(9223372036854775808.0), 
9223372036854775808ull); // 0x8000000000000000
+    ok_eq_ulonglong(cast_double_to_ulonglong(18446744073709550591.9), 
18446744073709549568ull); // 0xFFFFFFFFFFFFF800
+    todo_gcc ok_eq_ulonglong(cast_double_to_ulonglong(18446744073709550592.0), 
ULONGLONG_OVERFLOW); // 0x8000000000000000 / 0xFFFFFFFFFFFFFFFF
+    todo_gcc ok_eq_ulonglong(cast_double_to_ulonglong(18446744073709551616.0), 
ULONGLONG_OVERFLOW); // 0x8000000000000000 / 0xFFFFFFFFFFFFFFFF
+    todo_gcc ok_eq_ulonglong(cast_double_to_ulonglong(20000000000000000000.0), 
ULONGLONG_OVERFLOW); // 0x8000000000000000 / 0xFFFFFFFFFFFFFFFF
+
+    // float to unsigned long long cast (negative values)
+    ok_eq_ulonglong(cast_double_to_ulonglong(-0.0), 0ull);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-0.5), 0ull);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-1.0), 18446744073709551615ull);
+#ifdef OLD_BEHAVIOR
+    ok_eq_ulonglong(cast_double_to_ulonglong(-10.0), ULLONG_MAX);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-1147483648.0), ULLONG_MAX);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-2147483648.0), ULLONG_MAX);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-9223371761976868863.9), 
ULLONG_MAX);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-9223371761976868864.0), 
ULLONG_MAX);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-9223372036854775808.0), 
ULLONG_MAX);
+#else
+    ok_eq_ulonglong(cast_double_to_ulonglong(-10.0), (unsigned long long)-10);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-1147483648.0), (unsigned long 
long)-1147483648ll);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-2147483648.0), (unsigned long 
long)-2147483648ll);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-9223372036854775000.0), 
(unsigned long long)-9223372036854774784ll);
+    ok_eq_ulonglong(cast_double_to_ulonglong(-9223372036854775808.0), 
(unsigned long long)(-9223372036854775807ll - 1));
+#endif
+    ok_eq_ulonglong(cast_double_to_ulonglong(-100000000000000000000.0), 
ULONGLONG_OVERFLOW);
+}
+
+START_TEST(floatconv)
+{
+    Test_float();
+    Test_double();
+}
diff --git a/modules/rostests/apitests/compiler/testlist.c 
b/modules/rostests/apitests/compiler/testlist.c
index d73f7fd70bb..fe4b55adc21 100644
--- a/modules/rostests/apitests/compiler/testlist.c
+++ b/modules/rostests/apitests/compiler/testlist.c
@@ -1,16 +1,20 @@
 #define STANDALONE
 #include <apitest.h>
 
+extern void func_floatconv(void);
 extern void func_ms_seh(void);
 extern void func_pseh(void);
 extern void func_pseh_cpp(void);
 
 const struct test winetest_testlist[] =
 {
+    { "floatconv", func_floatconv },
+#ifndef __VS_PROJECT__
 #if !(defined(__GNUC__) && defined(_M_AMD64))
     { "ms-seh", func_ms_seh },
 #endif
     { "pseh", func_pseh },
     { "pseh_cpp", func_pseh_cpp },
+#endif /* __VS_PROJECT__ */
     { 0, 0 }
 };

Reply via email to