u-boot/post/lib_powerpc/fpu/compare-fp-1.c

209 lines
4.4 KiB
C
Raw Normal View History

/*
* Copyright (C) 2007
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* SPDX-License-Identifier: GPL-2.0+
*/
/*
* Test for correctness of composite floating-point comparisons.
* Written by Paolo Bonzini, 26th May 2004.
* This file is originally a part of the GCC testsuite.
*/
#include <common.h>
#include <post.h>
FPU POST: fix warnings when building with 2.18 binutils When compile u-boot with the 2.18 binutils the following warning messages for each object file in post/lib_ppc/fpu/ is produced at the linking stage: post/libpost.a(acc1.o) uses hard float, u-boot uses soft-float ... This is because of the fact that, in general, the soft-float and hard-float ABIs are incompatible; the 2.18 binutils do checking of the Tag_GNU_Power_ABI_FP attribute of the files to be linked, and produce the worning like above if these are not compatible. The incompatibility of ABIs is concerned only the float values: e.g. the soft-float ABI assumes the float argument passing in the pair of rX registers, and the hard-float ABI assumes passing of the float argument in the fX register. When we don't pass the float arguments between the functions compiled with different floatness, then such an application will work correctly. This is the case for the FPU POST: u-boot (compiled with soft-float) doesn't pass to (and doesn't get from) the FPU POST functions any floats; there are no functions exported from the post/lib_ppc/fpu/ objects which would work with float parameters/returns too. So, we can reassure the linker not to worry about the difference in ABI attributes of linking files just by setting the 'soft-float' attribute for the objects in post/lib_ppc/fpu. And this patch does this. Also, to avoid passing both soft- and hard-float options in CFLAGS when compiling the files from post/lib_ppc/fpu (which is OK, but looks rather dirty) this patch removes the soft-float string from CFLAGS in post/lib_ppc/fpu/Makefile. Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
2008-12-20 11:54:21 +00:00
GNU_FPOST_ATTR
#if CONFIG_POST & CONFIG_SYS_POST_FPU
static int failed;
#define TEST(c) if ((c) != ok) failed++
#define ORD(a, b) (!__builtin_isunordered ((a), (b)))
#define UNORD(a, b) (__builtin_isunordered ((a), (b)))
#define UNEQ(a, b) (__builtin_isunordered ((a), (b)) || ((a) == (b)))
#define UNLT(a, b) (__builtin_isunordered ((a), (b)) || ((a) < (b)))
#define UNLE(a, b) (__builtin_isunordered ((a), (b)) || ((a) <= (b)))
#define UNGT(a, b) (__builtin_isunordered ((a), (b)) || ((a) > (b)))
#define UNGE(a, b) (__builtin_isunordered ((a), (b)) || ((a) >= (b)))
#define LTGT(a, b) (__builtin_islessgreater ((a), (b)))
static float pinf;
static float ninf;
static float NaN;
static void iuneq (float x, float y, int ok)
{
TEST (UNEQ (x, y));
TEST (!LTGT (x, y));
TEST (UNLE (x, y) && UNGE (x,y));
}
static void ieq (float x, float y, int ok)
{
TEST (ORD (x, y) && UNEQ (x, y));
}
static void iltgt (float x, float y, int ok)
{
TEST (!UNEQ (x, y)); /* Not optimizable. */
TEST (LTGT (x, y)); /* Same, __builtin_islessgreater does not trap. */
TEST (ORD (x, y) && (UNLT (x, y) || UNGT (x,y)));
}
static void ine (float x, float y, int ok)
{
TEST (UNLT (x, y) || UNGT (x, y));
}
static void iunlt (float x, float y, int ok)
{
TEST (UNLT (x, y));
TEST (UNORD (x, y) || (x < y));
}
static void ilt (float x, float y, int ok)
{
TEST (ORD (x, y) && UNLT (x, y)); /* Not optimized */
TEST ((x <= y) && (x != y));
TEST ((x <= y) && (y != x));
TEST ((x != y) && (x <= y)); /* Not optimized */
TEST ((y != x) && (x <= y)); /* Not optimized */
}
static void iunle (float x, float y, int ok)
{
TEST (UNLE (x, y));
TEST (UNORD (x, y) || (x <= y));
}
static void ile (float x, float y, int ok)
{
TEST (ORD (x, y) && UNLE (x, y)); /* Not optimized */
TEST ((x < y) || (x == y));
TEST ((y > x) || (x == y));
TEST ((x == y) || (x < y)); /* Not optimized */
TEST ((y == x) || (x < y)); /* Not optimized */
}
static void iungt (float x, float y, int ok)
{
TEST (UNGT (x, y));
TEST (UNORD (x, y) || (x > y));
}
static void igt (float x, float y, int ok)
{
TEST (ORD (x, y) && UNGT (x, y)); /* Not optimized */
TEST ((x >= y) && (x != y));
TEST ((x >= y) && (y != x));
TEST ((x != y) && (x >= y)); /* Not optimized */
TEST ((y != x) && (x >= y)); /* Not optimized */
}
static void iunge (float x, float y, int ok)
{
TEST (UNGE (x, y));
TEST (UNORD (x, y) || (x >= y));
}
static void ige (float x, float y, int ok)
{
TEST (ORD (x, y) && UNGE (x, y)); /* Not optimized */
TEST ((x > y) || (x == y));
TEST ((y < x) || (x == y));
TEST ((x == y) || (x > y)); /* Not optimized */
TEST ((y == x) || (x > y)); /* Not optimized */
}
int fpu_post_test_math6 (void)
{
pinf = __builtin_inf ();
ninf = -__builtin_inf ();
NaN = __builtin_nan ("");
iuneq (ninf, pinf, 0);
iuneq (NaN, NaN, 1);
iuneq (pinf, ninf, 0);
iuneq (1, 4, 0);
iuneq (3, 3, 1);
iuneq (5, 2, 0);
ieq (1, 4, 0);
ieq (3, 3, 1);
ieq (5, 2, 0);
iltgt (ninf, pinf, 1);
iltgt (NaN, NaN, 0);
iltgt (pinf, ninf, 1);
iltgt (1, 4, 1);
iltgt (3, 3, 0);
iltgt (5, 2, 1);
ine (1, 4, 1);
ine (3, 3, 0);
ine (5, 2, 1);
iunlt (NaN, ninf, 1);
iunlt (pinf, NaN, 1);
iunlt (pinf, ninf, 0);
iunlt (pinf, pinf, 0);
iunlt (ninf, ninf, 0);
iunlt (1, 4, 1);
iunlt (3, 3, 0);
iunlt (5, 2, 0);
ilt (1, 4, 1);
ilt (3, 3, 0);
ilt (5, 2, 0);
iunle (NaN, ninf, 1);
iunle (pinf, NaN, 1);
iunle (pinf, ninf, 0);
iunle (pinf, pinf, 1);
iunle (ninf, ninf, 1);
iunle (1, 4, 1);
iunle (3, 3, 1);
iunle (5, 2, 0);
ile (1, 4, 1);
ile (3, 3, 1);
ile (5, 2, 0);
iungt (NaN, ninf, 1);
iungt (pinf, NaN, 1);
iungt (pinf, ninf, 1);
iungt (pinf, pinf, 0);
iungt (ninf, ninf, 0);
iungt (1, 4, 0);
iungt (3, 3, 0);
iungt (5, 2, 1);
igt (1, 4, 0);
igt (3, 3, 0);
igt (5, 2, 1);
iunge (NaN, ninf, 1);
iunge (pinf, NaN, 1);
iunge (ninf, pinf, 0);
iunge (pinf, pinf, 1);
iunge (ninf, ninf, 1);
iunge (1, 4, 0);
iunge (3, 3, 1);
iunge (5, 2, 1);
ige (1, 4, 0);
ige (3, 3, 1);
ige (5, 2, 1);
if (failed) {
post_log ("Error in FPU math6 test\n");
return -1;
}
return 0;
}
#endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */