| Index: crosstest/test_cast_main.cpp | 
| diff --git a/crosstest/test_cast_main.cpp b/crosstest/test_cast_main.cpp | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..330f98416c3db36485cae90ed7349aa3d0632e2b | 
| --- /dev/null | 
| +++ b/crosstest/test_cast_main.cpp | 
| @@ -0,0 +1,225 @@ | 
| +/* crosstest.py --test=test_cast.cpp --test=test_cast_to_u1.ll \ | 
| +   --driver=test_cast_main.cpp --prefix=Subzero_ --output=test_cast */ | 
| + | 
| +#include <cstring> | 
| +#include <iostream> | 
| +#include <stdint.h> | 
| + | 
| +// Include test_cast.h twice - once normally, and once within the | 
| +// Subzero_ namespace, corresponding to the llc and Subzero translated | 
| +// object files, respectively. | 
| +#include "test_cast.h" | 
| +namespace Subzero_ { | 
| +#include "test_cast.h" | 
| +} | 
| + | 
| +#define XSTR(s) STR(s) | 
| +#define STR(s) #s | 
| +#define COMPARE(Func, FromCName, ToCName, Input)                               \ | 
| +  do {                                                                         \ | 
| +    ToCName ResultSz, ResultLlc;                                               \ | 
| +    ResultLlc = Func<FromCName, ToCName>(Input);                               \ | 
| +    ResultSz = Subzero_::Func<FromCName, ToCName>(Input);                      \ | 
| +    ++TotalTests;                                                              \ | 
| +    if (!memcmp(&ResultLlc, &ResultSz, sizeof(ToCName))) {                     \ | 
| +      ++Passes;                                                                \ | 
| +    } else {                                                                   \ | 
| +      ++Failures;                                                              \ | 
| +      std::cout << std::fixed << XSTR(Func)                                    \ | 
| +                << "<" XSTR(FromCName) ", " XSTR(ToCName) ">(" << Input        \ | 
| +                << "): sz=" << ResultSz << " llc=" << ResultLlc << "\n";       \ | 
| +    }                                                                          \ | 
| +  } while (0) | 
| + | 
| +template <typename FromType> | 
| +void testValue(FromType Val, size_t &TotalTests, size_t &Passes, | 
| +               size_t &Failures) { | 
| +  COMPARE(cast, FromType, bool, Val); | 
| +  COMPARE(cast, FromType, uint8_t, Val); | 
| +  COMPARE(cast, FromType, int8_t, Val); | 
| +  COMPARE(cast, FromType, uint16_t, Val); | 
| +  COMPARE(cast, FromType, int16_t, Val); | 
| +  COMPARE(cast, FromType, uint32_t, Val); | 
| +  COMPARE(cast, FromType, int32_t, Val); | 
| +  COMPARE(cast, FromType, uint64_t, Val); | 
| +  COMPARE(cast, FromType, int64_t, Val); | 
| +  COMPARE(cast, FromType, float, Val); | 
| +  COMPARE(cast, FromType, double, Val); | 
| +} | 
| + | 
| +int main(int argc, char **argv) { | 
| +  size_t TotalTests = 0; | 
| +  size_t Passes = 0; | 
| +  size_t Failures = 0; | 
| + | 
| +  volatile bool ValsUi1[] = { false, true }; | 
| +  static const size_t NumValsUi1 = sizeof(ValsUi1) / sizeof(*ValsUi1); | 
| +  volatile uint8_t ValsUi8[] = { 0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff }; | 
| +  static const size_t NumValsUi8 = sizeof(ValsUi8) / sizeof(*ValsUi8); | 
| + | 
| +  volatile int8_t ValsSi8[] = { 0, 1, 0x7e, 0x7f, 0x80, 0x81, 0xfe, 0xff }; | 
| +  static const size_t NumValsSi8 = sizeof(ValsSi8) / sizeof(*ValsSi8); | 
| + | 
| +  volatile uint16_t ValsUi16[] = { 0,      1,      0x7e,   0x7f,   0x80, | 
| +                                   0x81,   0xfe,   0xff,   0x7ffe, 0x7fff, | 
| +                                   0x8000, 0x8001, 0xfffe, 0xffff }; | 
| +  static const size_t NumValsUi16 = sizeof(ValsUi16) / sizeof(*ValsUi16); | 
| + | 
| +  volatile int16_t ValsSi16[] = { 0,      1,      0x7e,   0x7f,   0x80, | 
| +                                  0x81,   0xfe,   0xff,   0x7ffe, 0x7fff, | 
| +                                  0x8000, 0x8001, 0xfffe, 0xffff }; | 
| +  static const size_t NumValsSi16 = sizeof(ValsSi16) / sizeof(*ValsSi16); | 
| + | 
| +  volatile size_t ValsUi32[] = { | 
| +    0,          1,          0x7e,       0x7f,       0x80, | 
| +    0x81,       0xfe,       0xff,       0x7ffe,     0x7fff, | 
| +    0x8000,     0x8001,     0xfffe,     0xffff,     0x7ffffffe, | 
| +    0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff | 
| +  }; | 
| +  static const size_t NumValsUi32 = sizeof(ValsUi32) / sizeof(*ValsUi32); | 
| + | 
| +  volatile size_t ValsSi32[] = { | 
| +    0,          1,          0x7e,       0x7f,       0x80, | 
| +    0x81,       0xfe,       0xff,       0x7ffe,     0x7fff, | 
| +    0x8000,     0x8001,     0xfffe,     0xffff,     0x7ffffffe, | 
| +    0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff | 
| +  }; | 
| +  static const size_t NumValsSi32 = sizeof(ValsSi32) / sizeof(*ValsSi32); | 
| + | 
| +  volatile uint64_t ValsUi64[] = { | 
| +    0,                     1,                     0x7e, | 
| +    0x7f,                  0x80,                  0x81, | 
| +    0xfe,                  0xff,                  0x7ffe, | 
| +    0x7fff,                0x8000,                0x8001, | 
| +    0xfffe,                0xffff,                0x7ffffffe, | 
| +    0x7fffffff,            0x80000000,            0x80000001, | 
| +    0xfffffffe,            0xffffffff,            0x100000000ull, | 
| +    0x100000001ull,        0x7ffffffffffffffeull, 0x7fffffffffffffffull, | 
| +    0x8000000000000000ull, 0x8000000000000001ull, 0xfffffffffffffffeull, | 
| +    0xffffffffffffffffull | 
| +  }; | 
| +  static const size_t NumValsUi64 = sizeof(ValsUi64) / sizeof(*ValsUi64); | 
| + | 
| +  volatile int64_t ValsSi64[] = { | 
| +    0,                    1,                    0x7e, | 
| +    0x7f,                 0x80,                 0x81, | 
| +    0xfe,                 0xff,                 0x7ffe, | 
| +    0x7fff,               0x8000,               0x8001, | 
| +    0xfffe,               0xffff,               0x7ffffffe, | 
| +    0x7fffffff,           0x80000000,           0x80000001, | 
| +    0xfffffffe,           0xffffffff,           0x100000000ll, | 
| +    0x100000001ll,        0x7ffffffffffffffell, 0x7fffffffffffffffll, | 
| +    0x8000000000000000ll, 0x8000000000000001ll, 0xfffffffffffffffell, | 
| +    0xffffffffffffffffll | 
| +  }; | 
| +  static const size_t NumValsSi64 = sizeof(ValsSi64) / sizeof(*ValsSi64); | 
| + | 
| +  volatile float ValsF32[] = { | 
| +    0,                    1,                    0x7e, | 
| +    0x7f,                 0x80,                 0x81, | 
| +    0xfe,                 0xff,                 0x7ffe, | 
| +    0x7fff,               0x8000,               0x8001, | 
| +    0xfffe,               0xffff,               0x7ffffffe, | 
| +    0x7fffffff,           0x80000000,           0x80000001, | 
| +    0xfffffffe,           0xffffffff,           0x100000000ll, | 
| +    0x100000001ll,        0x7ffffffffffffffell, 0x7fffffffffffffffll, | 
| +    0x8000000000000000ll, 0x8000000000000001ll, 0xfffffffffffffffell, | 
| +    0xffffffffffffffffll | 
| +  }; | 
| +  static const size_t NumValsF32 = sizeof(ValsF32) / sizeof(*ValsF32); | 
| + | 
| +  volatile double ValsF64[] = { | 
| +    0,                    1,                    0x7e, | 
| +    0x7f,                 0x80,                 0x81, | 
| +    0xfe,                 0xff,                 0x7ffe, | 
| +    0x7fff,               0x8000,               0x8001, | 
| +    0xfffe,               0xffff,               0x7ffffffe, | 
| +    0x7fffffff,           0x80000000,           0x80000001, | 
| +    0xfffffffe,           0xffffffff,           0x100000000ll, | 
| +    0x100000001ll,        0x7ffffffffffffffell, 0x7fffffffffffffffll, | 
| +    0x8000000000000000ll, 0x8000000000000001ll, 0xfffffffffffffffell, | 
| +    0xffffffffffffffffll | 
| +  }; | 
| +  static const size_t NumValsF64 = sizeof(ValsF64) / sizeof(*ValsF64); | 
| + | 
| +  for (size_t i = 0; i < NumValsUi1; ++i) { | 
| +    bool Val = ValsUi1[i]; | 
| +    testValue<bool>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsUi8; ++i) { | 
| +    uint8_t Val = ValsUi8[i]; | 
| +    testValue<uint8_t>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsSi8; ++i) { | 
| +    int8_t Val = ValsSi8[i]; | 
| +    testValue<int8_t>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsUi16; ++i) { | 
| +    uint16_t Val = ValsUi16[i]; | 
| +    testValue<uint16_t>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsSi16; ++i) { | 
| +    int16_t Val = ValsSi16[i]; | 
| +    testValue<int16_t>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsUi32; ++i) { | 
| +    uint32_t Val = ValsUi32[i]; | 
| +    testValue<uint32_t>(Val, TotalTests, Passes, Failures); | 
| +    COMPARE(castBits, uint32_t, float, Val); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsSi32; ++i) { | 
| +    int32_t Val = ValsSi32[i]; | 
| +    testValue<int32_t>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsUi64; ++i) { | 
| +    uint64_t Val = ValsUi64[i]; | 
| +    testValue<uint64_t>(Val, TotalTests, Passes, Failures); | 
| +    COMPARE(castBits, uint64_t, double, Val); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsSi64; ++i) { | 
| +    int64_t Val = ValsSi64[i]; | 
| +    testValue<int64_t>(Val, TotalTests, Passes, Failures); | 
| +  } | 
| +  for (size_t i = 0; i < NumValsF32; ++i) { | 
| +    for (unsigned j = 0; j < 2; ++j) { | 
| +      float Val = ValsF32[i]; | 
| +      if (j > 0) | 
| +        Val = -Val; | 
| +      testValue<float>(Val, TotalTests, Passes, Failures); | 
| +      COMPARE(castBits, float, uint32_t, Val); | 
| +    } | 
| +  } | 
| +  for (size_t i = 0; i < NumValsF64; ++i) { | 
| +    for (unsigned j = 0; j < 2; ++j) { | 
| +      double Val = ValsF64[i]; | 
| +      if (j > 0) | 
| +        Val = -Val; | 
| +      testValue<double>(Val, TotalTests, Passes, Failures); | 
| +      COMPARE(castBits, double, uint64_t, Val); | 
| +    } | 
| +  } | 
| + | 
| +  std::cout << "TotalTests=" << TotalTests << " Passes=" << Passes | 
| +            << " Failures=" << Failures << "\n"; | 
| +  return Failures; | 
| +} | 
| + | 
| +//////////////////////////////////////////////////////////////// | 
| + | 
| +// The following are helper definitions that should be part of the | 
| +// Subzero runtime. | 
| + | 
| +extern "C" { | 
| +uint32_t cvtdtoui32(double a) { return (uint32_t)a; } | 
| +uint32_t cvtftoui32(float a) { return (uint32_t)a; } | 
| +int64_t cvtdtosi64(double a) { return (int64_t)a; } | 
| +int64_t cvtftosi64(float a) { return (int64_t)a; } | 
| +uint64_t cvtdtoui64(double a) { return (uint64_t)a; } | 
| +uint64_t cvtftoui64(float a) { return (uint64_t)a; } | 
| +float cvtui64tof(uint64_t a) { return (float)a; } | 
| +double cvtui64tod(uint64_t a) { return (double)a; } | 
| +float cvtsi64tof(int64_t a) { return (float)a; } | 
| +float cvtui32tof(uint32_t a) { return (float)a; } | 
| +double cvtui32tod(uint32_t a) { return (double)a; } | 
| +double cvtsi64tod(int64_t a) { return (double)a; } | 
| +} | 
|  |