Index: crosstest/test_fcmp_main.cpp |
diff --git a/crosstest/test_fcmp_main.cpp b/crosstest/test_fcmp_main.cpp |
index 0c98c0ada8ca3d3b344499f4c4a48bbc067f1a5d..f04b2e50f63966db493e71459391b20d0f8043b9 100644 |
--- a/crosstest/test_fcmp_main.cpp |
+++ b/crosstest/test_fcmp_main.cpp |
@@ -1,22 +1,42 @@ |
+//===- subzero/crosstest/test_fcmp_main.cpp - Driver for tests ------------===// |
+// |
+// The Subzero Code Generator |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+// |
+// Driver for cross testing the fcmp bitcode instruction |
+// |
+//===----------------------------------------------------------------------===// |
+ |
/* crosstest.py --test=test_fcmp.pnacl.ll --driver=test_fcmp_main.cpp \ |
--prefix=Subzero_ --output=test_fcmp */ |
#include <cassert> |
#include <cfloat> |
#include <cmath> |
+#include <cstring> |
#include <iostream> |
+#include "vectors.h" |
#include "test_fcmp.def" |
#define X(cmp) \ |
extern "C" bool fcmp##cmp##Float(float a, float b); \ |
extern "C" bool fcmp##cmp##Double(double a, double b); \ |
+ extern "C" v4si32 fcmp##cmp##Vector(v4f32 a, v4f32 b); \ |
extern "C" bool Subzero_fcmp##cmp##Float(float a, float b); \ |
- extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); |
+ extern "C" bool Subzero_fcmp##cmp##Double(double a, double b); \ |
+ extern "C" v4si32 Subzero_fcmp##cmp##Vector(v4f32 a, v4f32 b); |
FCMP_TABLE; |
#undef X |
-int main(int argc, char **argv) { |
+volatile double *Values; |
+size_t NumValues; |
+ |
+void initializeValues() { |
static const double NegInf = -1.0 / 0.0; |
static const double Zero = 0.0; |
static const double Ten = 10.0; |
@@ -30,12 +50,14 @@ int main(int argc, char **argv) { |
assert(NegInf < Zero); |
assert(NegInf < PosInf); |
assert(Zero < PosInf); |
+ static volatile double InitValues[] = {NegInf, -Zero, Zero, DBL_MIN, |
+ FLT_MIN, Ten, FLT_MAX, DBL_MAX, |
+ PosInf, Nan, NegNan}; |
+ NumValues = sizeof(InitValues) / sizeof(*InitValues); |
+ Values = InitValues; |
+} |
- volatile double Values[] = { NegInf, -Zero, Zero, DBL_MIN, FLT_MIN, |
- Ten, FLT_MAX, DBL_MAX, PosInf, Nan, |
- NegNan }; |
- const static size_t NumValues = sizeof(Values) / sizeof(*Values); |
- |
+void testsScalar(size_t &TotalTests, size_t &Passes, size_t &Failures) { |
typedef bool (*FuncTypeFloat)(float, float); |
typedef bool (*FuncTypeDouble)(double, double); |
static struct { |
@@ -58,9 +80,7 @@ int main(int argc, char **argv) { |
bool ResultSz, ResultLlc; |
- size_t TotalTests = 0; |
- size_t Passes = 0; |
- size_t Failures = 0; |
+ assert(Values && NumValues); |
for (size_t f = 0; f < NumFuncs; ++f) { |
for (size_t i = 0; i < NumValues; ++i) { |
@@ -76,7 +96,7 @@ int main(int argc, char **argv) { |
++Failures; |
std::cout << Funcs[f].Name << "Float(" << Value1Float << ", " |
<< Value2Float << "): sz=" << ResultSz |
- << " llc=" << ResultLlc << std::endl; |
+ << " llc=" << ResultLlc << "\n"; |
} |
++TotalTests; |
double Value1Double = Values[i]; |
@@ -89,11 +109,66 @@ int main(int argc, char **argv) { |
++Failures; |
std::cout << Funcs[f].Name << "Double(" << Value1Double << ", " |
<< Value2Double << "): sz=" << ResultSz |
- << " llc=" << ResultLlc << std::endl; |
+ << " llc=" << ResultLlc << "\n"; |
} |
} |
} |
} |
+} |
+ |
+void testsVector(size_t &TotalTests, size_t &Passes, size_t &Failures) { |
+ typedef v4si32 (*FuncTypeVector)(v4f32, v4f32); |
+ static struct { |
+ const char *Name; |
+ FuncTypeVector FuncVectorSz; |
+ FuncTypeVector FuncVectorLlc; |
+ } Funcs[] = { |
+#define X(cmp) \ |
+ { "fcmp" STR(cmp), Subzero_fcmp##cmp##Vector, fcmp##cmp##Vector } \ |
+ , |
+ FCMP_TABLE |
+#undef X |
+ }; |
+ const static size_t NumFuncs = sizeof(Funcs) / sizeof(*Funcs); |
+ const static size_t NumElementsInType = 4; |
+ const static size_t MaxTestsPerFunc = 100000; |
+ |
+ assert(Values && NumValues); |
+ |
+ for (size_t f = 0; f < NumFuncs; ++f) { |
+ PRNG Index; |
+ for (size_t i = 0; i < MaxTestsPerFunc; ++i) { |
+ v4f32 Value1, Value2; |
+ for (size_t j = 0; j < NumElementsInType; ++j) { |
+ Value1[j] = Values[Index() % NumValues]; |
+ Value2[j] = Values[Index() % NumValues]; |
+ } |
+ ++TotalTests; |
+ v4si32 ResultSz, ResultLlc; |
+ ResultSz = Funcs[f].FuncVectorSz(Value1, Value2); |
+ ResultLlc = Funcs[f].FuncVectorLlc(Value1, Value2); |
+ if (!memcmp(&ResultSz, &ResultLlc, sizeof(ResultSz))) { |
+ ++Passes; |
+ } else { |
+ ++Failures; |
+ std::cout << Funcs[f].Name << "Vector(" << vectAsString<v4f32>(Value1) |
+ << ", " << vectAsString<v4f32>(Value2) |
+ << "): sz=" << vectAsString<v4si32>(ResultSz) |
+ << " llc=" << vectAsString<v4si32>(ResultLlc) << "\n"; |
+ } |
+ } |
+ } |
+} |
+ |
+int main(int argc, char **argv) { |
+ size_t TotalTests = 0; |
+ size_t Passes = 0; |
+ size_t Failures = 0; |
+ |
+ initializeValues(); |
+ |
+ testsScalar(TotalTests, Passes, Failures); |
+ testsVector(TotalTests, Passes, Failures); |
std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes |
<< " Failures=" << Failures << "\n"; |