mirror of
https://github.com/KhronosGroup/OpenCL-CTS.git
synced 2026-03-19 06:09:01 +00:00
conversions: Use ARM emulation for aarch64 (#967)
The host compiler will not always calculate reference values the same, depending on optimization level. It generates instructions that do not respond to CPU rounding mode in the same way. Use QCOM rounding mode emulation to correctly calculate reference values on aarch64.
This commit is contained in:
committed by
GitHub
parent
90c9ea5d7c
commit
b165de7649
@@ -4,7 +4,7 @@ set (${MODULE_NAME}_SOURCES
|
||||
Sleep.cpp test_conversions.cpp basic_test_conversions.cpp
|
||||
)
|
||||
|
||||
if("${CLConform_TARGET_ARCH}" STREQUAL "ARM")
|
||||
if("${CLConform_TARGET_ARCH}" STREQUAL "ARM" OR "${CLConform_TARGET_ARCH}" STREQUAL "ARM64")
|
||||
list(APPEND ${MODULE_NAME}_SOURCES fplib.cpp)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
|
||||
#include "harness/mt19937.h"
|
||||
|
||||
#if defined( __arm__ ) && defined( __GNUC__ )
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
|
||||
#include "fplib.h"
|
||||
#endif
|
||||
|
||||
#if defined( __arm__ ) && defined( __GNUC__ )
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
|
||||
/* Rounding modes and saturation for use with qcom 64 bit to float conversion library */
|
||||
bool qcom_sat;
|
||||
roundingMode qcom_rm;
|
||||
@@ -759,12 +759,18 @@ static void ulong2float( void *out, void *in)
|
||||
((float*) out)[0] = (l == 0 ? 0.0f : (((cl_long)l < 0) ? result * 2.0f : result));
|
||||
#else
|
||||
cl_ulong l = ((cl_ulong*) in)[0];
|
||||
#if defined( __arm__ ) && defined( __GNUC__ )
|
||||
/* ARM VFP doesn't have hardware instruction for converting from 64-bit integer to float types, hence GCC ARM uses the floating-point emulation code
|
||||
* despite which -mfloat-abi setting it is. But the emulation code in libgcc.a has only one rounding mode (round to nearest even in this case)
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
|
||||
/* ARM VFP doesn't have hardware instruction for converting from 64-bit
|
||||
* integer to float types, hence GCC ARM uses the floating-point emulation
|
||||
* code despite which -mfloat-abi setting it is. But the emulation code in
|
||||
* libgcc.a has only one rounding mode (round to nearest even in this case)
|
||||
* and ignores the user rounding mode setting in hardware.
|
||||
* As a result setting rounding modes in hardware won't give correct rounding results for type covert from 64-bit integer to float using GCC for ARM compiler
|
||||
* so for testing different rounding modes, we need to use alternative reference function */
|
||||
* As a result setting rounding modes in hardware won't give correct
|
||||
* rounding results for type covert from 64-bit integer to float using GCC
|
||||
* for ARM compiler so for testing different rounding modes, we need to use
|
||||
* alternative reference function. ARM64 does have an instruction, however
|
||||
* we cannot guarantee the compiler will use it. On all ARM architechures
|
||||
* use emulation to calculate reference.*/
|
||||
((float*) out)[0] = qcom_u64_2_f32(l, qcom_sat, qcom_rm);
|
||||
#else
|
||||
((float*) out)[0] = (l == 0 ? 0.0f : (float) l); // Per IEEE-754-2008 5.4.1, 0's always convert to +0.0
|
||||
@@ -806,12 +812,18 @@ static void long2float( void *out, void *in)
|
||||
((float*) out)[0] = (l == 0 ? 0.0f : result); // Per IEEE-754-2008 5.4.1, 0's always convert to +0.0
|
||||
#else
|
||||
cl_long l = ((cl_long*) in)[0];
|
||||
#if defined( __arm__ ) && defined( __GNUC__ )
|
||||
/* ARM VFP doesn't have hardware instruction for converting from 64-bit integer to float types, hence GCC ARM uses the floating-point emulation code
|
||||
* despite which -mfloat-abi setting it is. But the emulation code in libgcc.a has only one rounding mode (round to nearest even in this case)
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
|
||||
/* ARM VFP doesn't have hardware instruction for converting from 64-bit
|
||||
* integer to float types, hence GCC ARM uses the floating-point emulation
|
||||
* code despite which -mfloat-abi setting it is. But the emulation code in
|
||||
* libgcc.a has only one rounding mode (round to nearest even in this case)
|
||||
* and ignores the user rounding mode setting in hardware.
|
||||
* As a result setting rounding modes in hardware won't give correct rounding results for type covert from 64-bit integer to float using GCC for ARM compiler
|
||||
* so for testing different rounding modes, we need to use alternative reference function */
|
||||
* As a result setting rounding modes in hardware won't give correct
|
||||
* rounding results for type covert from 64-bit integer to float using GCC
|
||||
* for ARM compiler so for testing different rounding modes, we need to use
|
||||
* alternative reference function. ARM64 does have an instruction, however
|
||||
* we cannot guarantee the compiler will use it. On all ARM architechures
|
||||
* use emulation to calculate reference.*/
|
||||
((float*) out)[0] = (l == 0 ? 0.0f : qcom_s64_2_f32(l, qcom_sat, qcom_rm));
|
||||
#else
|
||||
((float*) out)[0] = (l == 0 ? 0.0f : (float) l); // Per IEEE-754-2008 5.4.1, 0's always convert to +0.0
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
#define kCallStyleCount (kVectorSizeCount + 1 /* for implicit scalar */)
|
||||
|
||||
#if defined( __arm__ ) && defined( __GNUC__ )
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
|
||||
#include "fplib.h"
|
||||
extern bool qcom_sat;
|
||||
extern roundingMode qcom_rm;
|
||||
@@ -884,12 +884,18 @@ cl_int PrepareReference( cl_uint job_id, cl_uint thread_id, void *p )
|
||||
if( info->sat )
|
||||
f = gSaturatedConversions[ outType ][ inType ];
|
||||
|
||||
#if defined( __arm__ ) && defined( __GNUC__ )
|
||||
/* ARM VFP doesn't have hardware instruction for converting from 64-bit integer to float types, hence GCC ARM uses the floating-point emulation code
|
||||
* despite which -mfloat-abi setting it is. But the emulation code in libgcc.a has only one rounding mode (round to nearest even in this case)
|
||||
* and ignores the user rounding mode setting in hardware.
|
||||
* As a result setting rounding modes in hardware won't give correct rounding results for type covert from 64-bit integer to float using GCC for ARM compiler
|
||||
* so for testing different rounding modes, we need to use alternative reference function */
|
||||
#if (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
|
||||
/* ARM VFP doesn't have hardware instruction for converting from 64-bit
|
||||
* integer to float types, hence GCC ARM uses the floating-point
|
||||
* emulation code despite which -mfloat-abi setting it is. But the
|
||||
* emulation code in libgcc.a has only one rounding mode (round to
|
||||
* nearest even in this case) and ignores the user rounding mode setting
|
||||
* in hardware. As a result setting rounding modes in hardware won't
|
||||
* give correct rounding results for type covert from 64-bit integer to
|
||||
* float using GCC for ARM compiler so for testing different rounding
|
||||
* modes, we need to use alternative reference function. ARM64 does have
|
||||
* an instruction, however we cannot guarantee the compiler will use it.
|
||||
* On all ARM architechures use emulation to calculate reference.*/
|
||||
switch (round)
|
||||
{
|
||||
/* conversions to floating-point type use the current rounding mode.
|
||||
|
||||
Reference in New Issue
Block a user