1 /* 2 * Copyright (C) 2007 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * See file CREDITS for list of people who contributed to this 6 * project. 7 * 8 * This program is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU General Public License as 10 * published by the Free Software Foundation; either version 2 of 11 * the License, or (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 21 * MA 02111-1307 USA 22 */ 23 /* 24 * Test for correctness of composite floating-point comparisons. 25 * Written by Paolo Bonzini, 26th May 2004. 26 * This file is originally a part of the GCC testsuite. 27 */ 28 29 #include <common.h> 30 31 #include <post.h> 32 33 GNU_FPOST_ATTR 34 35 #if CONFIG_POST & CONFIG_SYS_POST_FPU 36 37 static int failed; 38 39 #define TEST(c) if ((c) != ok) failed++ 40 #define ORD(a, b) (!__builtin_isunordered ((a), (b))) 41 #define UNORD(a, b) (__builtin_isunordered ((a), (b))) 42 #define UNEQ(a, b) (__builtin_isunordered ((a), (b)) || ((a) == (b))) 43 #define UNLT(a, b) (__builtin_isunordered ((a), (b)) || ((a) < (b))) 44 #define UNLE(a, b) (__builtin_isunordered ((a), (b)) || ((a) <= (b))) 45 #define UNGT(a, b) (__builtin_isunordered ((a), (b)) || ((a) > (b))) 46 #define UNGE(a, b) (__builtin_isunordered ((a), (b)) || ((a) >= (b))) 47 #define LTGT(a, b) (__builtin_islessgreater ((a), (b))) 48 49 static float pinf; 50 static float ninf; 51 static float NaN; 52 53 static void iuneq (float x, float y, int ok) 54 { 55 TEST (UNEQ (x, y)); 56 TEST (!LTGT (x, y)); 57 TEST (UNLE (x, y) && UNGE (x,y)); 58 } 59 60 static void ieq (float x, float y, int ok) 61 { 62 TEST (ORD (x, y) && UNEQ (x, y)); 63 } 64 65 static void iltgt (float x, float y, int ok) 66 { 67 TEST (!UNEQ (x, y)); /* Not optimizable. */ 68 TEST (LTGT (x, y)); /* Same, __builtin_islessgreater does not trap. */ 69 TEST (ORD (x, y) && (UNLT (x, y) || UNGT (x,y))); 70 } 71 72 static void ine (float x, float y, int ok) 73 { 74 TEST (UNLT (x, y) || UNGT (x, y)); 75 } 76 77 static void iunlt (float x, float y, int ok) 78 { 79 TEST (UNLT (x, y)); 80 TEST (UNORD (x, y) || (x < y)); 81 } 82 83 static void ilt (float x, float y, int ok) 84 { 85 TEST (ORD (x, y) && UNLT (x, y)); /* Not optimized */ 86 TEST ((x <= y) && (x != y)); 87 TEST ((x <= y) && (y != x)); 88 TEST ((x != y) && (x <= y)); /* Not optimized */ 89 TEST ((y != x) && (x <= y)); /* Not optimized */ 90 } 91 92 static void iunle (float x, float y, int ok) 93 { 94 TEST (UNLE (x, y)); 95 TEST (UNORD (x, y) || (x <= y)); 96 } 97 98 static void ile (float x, float y, int ok) 99 { 100 TEST (ORD (x, y) && UNLE (x, y)); /* Not optimized */ 101 TEST ((x < y) || (x == y)); 102 TEST ((y > x) || (x == y)); 103 TEST ((x == y) || (x < y)); /* Not optimized */ 104 TEST ((y == x) || (x < y)); /* Not optimized */ 105 } 106 107 static void iungt (float x, float y, int ok) 108 { 109 TEST (UNGT (x, y)); 110 TEST (UNORD (x, y) || (x > y)); 111 } 112 113 static void igt (float x, float y, int ok) 114 { 115 TEST (ORD (x, y) && UNGT (x, y)); /* Not optimized */ 116 TEST ((x >= y) && (x != y)); 117 TEST ((x >= y) && (y != x)); 118 TEST ((x != y) && (x >= y)); /* Not optimized */ 119 TEST ((y != x) && (x >= y)); /* Not optimized */ 120 } 121 122 static void iunge (float x, float y, int ok) 123 { 124 TEST (UNGE (x, y)); 125 TEST (UNORD (x, y) || (x >= y)); 126 } 127 128 static void ige (float x, float y, int ok) 129 { 130 TEST (ORD (x, y) && UNGE (x, y)); /* Not optimized */ 131 TEST ((x > y) || (x == y)); 132 TEST ((y < x) || (x == y)); 133 TEST ((x == y) || (x > y)); /* Not optimized */ 134 TEST ((y == x) || (x > y)); /* Not optimized */ 135 } 136 137 int fpu_post_test_math6 (void) 138 { 139 pinf = __builtin_inf (); 140 ninf = -__builtin_inf (); 141 NaN = __builtin_nan (""); 142 143 iuneq (ninf, pinf, 0); 144 iuneq (NaN, NaN, 1); 145 iuneq (pinf, ninf, 0); 146 iuneq (1, 4, 0); 147 iuneq (3, 3, 1); 148 iuneq (5, 2, 0); 149 150 ieq (1, 4, 0); 151 ieq (3, 3, 1); 152 ieq (5, 2, 0); 153 154 iltgt (ninf, pinf, 1); 155 iltgt (NaN, NaN, 0); 156 iltgt (pinf, ninf, 1); 157 iltgt (1, 4, 1); 158 iltgt (3, 3, 0); 159 iltgt (5, 2, 1); 160 161 ine (1, 4, 1); 162 ine (3, 3, 0); 163 ine (5, 2, 1); 164 165 iunlt (NaN, ninf, 1); 166 iunlt (pinf, NaN, 1); 167 iunlt (pinf, ninf, 0); 168 iunlt (pinf, pinf, 0); 169 iunlt (ninf, ninf, 0); 170 iunlt (1, 4, 1); 171 iunlt (3, 3, 0); 172 iunlt (5, 2, 0); 173 174 ilt (1, 4, 1); 175 ilt (3, 3, 0); 176 ilt (5, 2, 0); 177 178 iunle (NaN, ninf, 1); 179 iunle (pinf, NaN, 1); 180 iunle (pinf, ninf, 0); 181 iunle (pinf, pinf, 1); 182 iunle (ninf, ninf, 1); 183 iunle (1, 4, 1); 184 iunle (3, 3, 1); 185 iunle (5, 2, 0); 186 187 ile (1, 4, 1); 188 ile (3, 3, 1); 189 ile (5, 2, 0); 190 191 iungt (NaN, ninf, 1); 192 iungt (pinf, NaN, 1); 193 iungt (pinf, ninf, 1); 194 iungt (pinf, pinf, 0); 195 iungt (ninf, ninf, 0); 196 iungt (1, 4, 0); 197 iungt (3, 3, 0); 198 iungt (5, 2, 1); 199 200 igt (1, 4, 0); 201 igt (3, 3, 0); 202 igt (5, 2, 1); 203 204 iunge (NaN, ninf, 1); 205 iunge (pinf, NaN, 1); 206 iunge (ninf, pinf, 0); 207 iunge (pinf, pinf, 1); 208 iunge (ninf, ninf, 1); 209 iunge (1, 4, 0); 210 iunge (3, 3, 1); 211 iunge (5, 2, 1); 212 213 ige (1, 4, 0); 214 ige (3, 3, 1); 215 ige (5, 2, 1); 216 217 if (failed) { 218 post_log ("Error in FPU math6 test\n"); 219 return -1; 220 } 221 return 0; 222 } 223 224 #endif /* CONFIG_POST & CONFIG_SYS_POST_FPU */ 225