Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // crosstest.py --test=test_arith.cpp --driver=test_arith_main.cpp | |
| 2 // --prefix=Subzero_ --output=test_arith | |
| 3 | |
|
JF
2014/05/01 00:16:55
I think that this test could be partly evaluated a
Jim Stichnoth
2014/05/05 07:03:55
Done. I changed the arrays to be volatile (here a
| |
| 4 #include <stdio.h> | |
| 5 #include <stdint.h> | |
| 6 | |
| 7 #include "test_arith.h" | |
| 8 namespace Subzero_ { | |
| 9 #include "test_arith.h" | |
| 10 } | |
|
JF
2014/05/01 00:16:55
Ew. That is quite ugly... and kind of clever. Coul
Jim Stichnoth
2014/05/05 07:03:55
Done.
| |
| 11 | |
| 12 int main(int argc, char **argv) { | |
| 13 static unsigned Values[] = { 0x0, 0x1, 0x7ffffffe, 0x7fffffff, | |
| 14 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff, | |
| 15 0x7e, 0x7f, 0x80, 0x81, | |
| 16 0xfe, 0xff, 0x100, 0x101, | |
| 17 0x7ffe, 0x7fff, 0x8000, 0x8001, | |
| 18 0xfffe, 0xffff, 0x10000, 0x10001, }; | |
| 19 const static unsigned NumValues = sizeof(Values) / sizeof(*Values); | |
|
JF
2014/05/01 00:16:55
size_t, same on loop bounds.
Jim Stichnoth
2014/05/05 07:03:55
Done.
| |
| 20 | |
| 21 typedef uint8_t (*FuncType8)(uint8_t, uint8_t); | |
| 22 typedef int8_t (*FuncTypeS8)(int8_t, int8_t); | |
| 23 static struct { | |
| 24 const char *Name; | |
| 25 FuncType8 FuncLlc; | |
| 26 FuncType8 FuncSz; | |
| 27 bool DisallowIllegal; // for divide related tests | |
|
JF
2014/05/01 00:16:55
Could you instead figure out that the test is ille
Jim Stichnoth
2014/05/05 07:03:55
The name is only meant for printing failing tests,
| |
| 28 } Func8[] = { | |
| 29 { "testAdd8", (FuncType8)testAdd, (FuncType8)Subzero_::testAdd }, | |
| 30 { "testSub8", (FuncType8)testSub, (FuncType8)Subzero_::testSub }, | |
| 31 { "testMul8", (FuncType8)testMul, (FuncType8)Subzero_::testMul }, | |
| 32 { "testUdiv8", (FuncType8)testUdiv, (FuncType8)Subzero_::testUdiv, true }, | |
| 33 { "testSdiv8", | |
| 34 (FuncType8)(FuncTypeS8)testSdiv, | |
| 35 (FuncType8)(FuncTypeS8)Subzero_::testSdiv, | |
| 36 true }, | |
| 37 { "testUrem8", (FuncType8)testUrem, (FuncType8)Subzero_::testUrem, true }, | |
| 38 { "testSrem8", | |
| 39 (FuncType8)(FuncTypeS8)testSrem, | |
| 40 (FuncType8)(FuncTypeS8)Subzero_::testSrem, | |
| 41 true }, | |
| 42 { "testShl8", (FuncType8)testShl, (FuncType8)Subzero_::testShl }, | |
| 43 { "testLshr8", (FuncType8)testLshr, (FuncType8)Subzero_::testLshr }, | |
| 44 { "testAshr8", (FuncType8)(FuncTypeS8)testAshr, | |
| 45 (FuncType8)(FuncTypeS8)Subzero_::testAshr }, | |
| 46 { "testAnd8", (FuncType8)testAnd, (FuncType8)Subzero_::testAnd }, | |
| 47 { "testOr8", (FuncType8)testOr, (FuncType8)Subzero_::testOr }, | |
| 48 { "testXor8", (FuncType8)testXor, (FuncType8)Subzero_::testXor }, | |
| 49 }; | |
|
JF
2014/05/01 00:16:55
xmacros!!! It seems like the test declaration/defi
Jim Stichnoth
2014/05/05 07:03:55
Done.
| |
| 50 const static unsigned NumFunc8 = sizeof(Func8) / sizeof(*Func8); | |
| 51 | |
| 52 typedef uint16_t (*FuncType16)(uint16_t, uint16_t); | |
| 53 typedef int16_t (*FuncTypeS16)(int16_t, int16_t); | |
| 54 static struct { | |
| 55 const char *Name; | |
| 56 FuncType16 FuncLlc; | |
| 57 FuncType16 FuncSz; | |
| 58 bool DisallowIllegal; // on the second arg, for divide related tests | |
| 59 } Func16[] = | |
| 60 { { "testAdd16", (FuncType16)testAdd, (FuncType16)Subzero_::testAdd }, | |
| 61 { "testSub16", (FuncType16)testSub, (FuncType16)Subzero_::testSub }, | |
| 62 { "testMul16", (FuncType16)testMul, (FuncType16)Subzero_::testMul }, | |
| 63 { "testUdiv16", (FuncType16)testUdiv, | |
| 64 (FuncType16)Subzero_::testUdiv, true }, | |
| 65 { "testSdiv16", | |
| 66 (FuncType16)(FuncTypeS16)testSdiv, | |
| 67 (FuncType16)(FuncTypeS16)Subzero_::testSdiv, | |
| 68 true }, | |
| 69 { "testUrem16", (FuncType16)testUrem, | |
| 70 (FuncType16)Subzero_::testUrem, true }, | |
| 71 { "testSrem16", | |
| 72 (FuncType16)(FuncTypeS16)testSrem, | |
| 73 (FuncType16)(FuncTypeS16)Subzero_::testSrem, | |
| 74 true }, | |
| 75 { "testShl16", (FuncType16)testShl, (FuncType16)Subzero_::testShl }, | |
| 76 { "testLshr16", (FuncType16)testLshr, | |
| 77 (FuncType16)Subzero_::testLshr }, | |
| 78 { "testAshr16", (FuncType16)(FuncTypeS16)testAshr, | |
| 79 (FuncType16)(FuncTypeS16)Subzero_::testAshr }, | |
| 80 { "testAnd16", (FuncType16)testAnd, (FuncType16)Subzero_::testAnd }, | |
| 81 { "testOr16", (FuncType16)testOr, (FuncType16)Subzero_::testOr }, | |
| 82 { "testXor16", (FuncType16)testXor, | |
| 83 (FuncType16)Subzero_::testXor }, }; | |
| 84 const static unsigned NumFunc16 = sizeof(Func16) / sizeof(*Func16); | |
| 85 | |
| 86 typedef uint32_t (*FuncType32)(uint32_t, uint32_t); | |
| 87 typedef int32_t (*FuncTypeS32)(int32_t, int32_t); | |
| 88 static struct { | |
| 89 const char *Name; | |
| 90 FuncType32 FuncLlc; | |
| 91 FuncType32 FuncSz; | |
| 92 bool DisallowIllegal; // on the second arg, for divide related tests | |
| 93 } Func32[] = | |
| 94 { { "testAdd32", (FuncType32)testAdd, (FuncType32)Subzero_::testAdd }, | |
| 95 { "testSub32", (FuncType32)testSub, (FuncType32)Subzero_::testSub }, | |
| 96 { "testMul32", (FuncType32)testMul, (FuncType32)Subzero_::testMul }, | |
| 97 { "testUdiv32", (FuncType32)testUdiv, | |
| 98 (FuncType32)Subzero_::testUdiv, true }, | |
| 99 { "testSdiv32", | |
| 100 (FuncType32)(FuncTypeS32)testSdiv, | |
| 101 (FuncType32)(FuncTypeS32)Subzero_::testSdiv, | |
| 102 true }, | |
| 103 { "testUrem32", (FuncType32)testUrem, | |
| 104 (FuncType32)Subzero_::testUrem, true }, | |
| 105 { "testSrem32", | |
| 106 (FuncType32)(FuncTypeS32)testSrem, | |
| 107 (FuncType32)(FuncTypeS32)Subzero_::testSrem, | |
| 108 true }, | |
| 109 { "testShl32", (FuncType32)testShl, (FuncType32)Subzero_::testShl }, | |
| 110 { "testLshr32", (FuncType32)testLshr, | |
| 111 (FuncType32)Subzero_::testLshr }, | |
| 112 { "testAshr32", (FuncType32)(FuncTypeS32)testAshr, | |
| 113 (FuncType32)(FuncTypeS32)Subzero_::testAshr }, | |
| 114 { "testAnd32", (FuncType32)testAnd, (FuncType32)Subzero_::testAnd }, | |
| 115 { "testOr32", (FuncType32)testOr, (FuncType32)Subzero_::testOr }, | |
| 116 { "testXor32", (FuncType32)testXor, | |
| 117 (FuncType32)Subzero_::testXor }, }; | |
| 118 const static unsigned NumFunc32 = sizeof(Func32) / sizeof(*Func32); | |
| 119 | |
| 120 typedef uint64_t (*FuncType64)(uint64_t, uint64_t); | |
| 121 typedef int64_t (*FuncTypeS64)(int64_t, int64_t); | |
| 122 static struct { | |
| 123 const char *Name; | |
| 124 FuncType64 FuncLlc; | |
| 125 FuncType64 FuncSz; | |
| 126 bool DisallowIllegal; // on the second arg, for divide related tests | |
| 127 } Func64[] = | |
| 128 { { "testAdd64", (FuncType64)testAdd, (FuncType64)Subzero_::testAdd }, | |
| 129 { "testSub64", (FuncType64)testSub, (FuncType64)Subzero_::testSub }, | |
| 130 { "testMul64", (FuncType64)testMul, (FuncType64)Subzero_::testMul }, | |
| 131 { "testUdiv64", (FuncType64)testUdiv, | |
| 132 (FuncType64)Subzero_::testUdiv, true }, | |
| 133 { "testSdiv64", | |
| 134 (FuncType64)(FuncTypeS64)testSdiv, | |
| 135 (FuncType64)(FuncTypeS64)Subzero_::testSdiv, | |
| 136 true }, | |
| 137 { "testUrem64", (FuncType64)testUrem, | |
| 138 (FuncType64)Subzero_::testUrem, true }, | |
| 139 { "testSrem64", | |
| 140 (FuncType64)(FuncTypeS64)testSrem, | |
| 141 (FuncType64)(FuncTypeS64)Subzero_::testSrem, | |
| 142 true }, | |
| 143 { "testShl64", (FuncType64)testShl, (FuncType64)Subzero_::testShl }, | |
| 144 { "testLshr64", (FuncType64)testLshr, | |
| 145 (FuncType64)Subzero_::testLshr }, | |
| 146 { "testAshr64", (FuncType64)(FuncTypeS64)testAshr, | |
| 147 (FuncType64)(FuncTypeS64)Subzero_::testAshr }, | |
| 148 { "testAnd64", (FuncType64)testAnd, (FuncType64)Subzero_::testAnd }, | |
| 149 { "testOr64", (FuncType64)testOr, (FuncType64)Subzero_::testOr }, | |
| 150 { "testXor64", (FuncType64)testXor, | |
| 151 (FuncType64)Subzero_::testXor }, }; | |
| 152 const static unsigned NumFunc64 = sizeof(Func64) / sizeof(*Func64); | |
| 153 | |
| 154 unsigned TotalTests = 0; | |
| 155 unsigned Passes = 0; | |
| 156 unsigned Failures = 0; | |
| 157 | |
| 158 for (unsigned f = 0; f < NumFunc8; ++f) { | |
| 159 for (unsigned i = 0; i < NumValues; ++i) { | |
| 160 for (unsigned j = 0; j < NumValues; ++j) { | |
| 161 if (Func8[f].DisallowIllegal && ((uint8_t)Values[j] == 0)) | |
| 162 continue; | |
| 163 ++TotalTests; | |
| 164 uint8_t ResultSz = Func8[f].FuncSz(Values[i], Values[j]); | |
| 165 uint8_t ResultLlc = Func8[f].FuncLlc(Values[i], Values[j]); | |
| 166 if (ResultSz == ResultLlc) { | |
| 167 ++Passes; | |
| 168 } else { | |
| 169 ++Failures; | |
| 170 printf("%s(0x%08x, 0x%08x): sz=%d llc=%d\n", Func8[f].Name, Values[i], | |
| 171 Values[j], ResultSz, ResultLlc); | |
| 172 } | |
| 173 } | |
| 174 } | |
| 175 } | |
| 176 | |
| 177 for (unsigned f = 0; f < NumFunc16; ++f) { | |
| 178 for (unsigned i = 0; i < NumValues; ++i) { | |
| 179 for (unsigned j = 0; j < NumValues; ++j) { | |
| 180 if (Func16[f].DisallowIllegal && ((uint16_t)Values[j] == 0)) | |
| 181 continue; | |
| 182 ++TotalTests; | |
| 183 uint16_t ResultSz = Func16[f].FuncSz(Values[i], Values[j]); | |
| 184 uint16_t ResultLlc = Func16[f].FuncLlc(Values[i], Values[j]); | |
| 185 if (ResultSz == ResultLlc) { | |
| 186 ++Passes; | |
| 187 } else { | |
| 188 ++Failures; | |
| 189 printf("%s(0x%08x, 0x%08x): sz=%d llc=%d\n", Func16[f].Name, | |
| 190 Values[i], Values[j], ResultSz, ResultLlc); | |
| 191 } | |
| 192 } | |
| 193 } | |
| 194 } | |
| 195 | |
| 196 for (unsigned f = 0; f < NumFunc32; ++f) { | |
| 197 for (unsigned i = 0; i < NumValues; ++i) { | |
| 198 for (unsigned j = 0; j < NumValues; ++j) { | |
| 199 if (Func32[f].DisallowIllegal && Values[j] == 0) | |
| 200 continue; | |
| 201 if (Func32[f].DisallowIllegal && Values[i] == 0x80000000 && | |
| 202 Values[j] == 0xffffffff) | |
| 203 continue; | |
| 204 ++TotalTests; | |
| 205 uint32_t ResultSz = Func32[f].FuncSz(Values[i], Values[j]); | |
| 206 uint32_t ResultLlc = Func32[f].FuncLlc(Values[i], Values[j]); | |
| 207 if (ResultSz == ResultLlc) { | |
| 208 ++Passes; | |
| 209 } else { | |
| 210 ++Failures; | |
| 211 printf("%s(0x%08x, 0x%08x): sz=%d llc=%d\n", Func32[f].Name, | |
| 212 Values[i], Values[j], ResultSz, ResultLlc); | |
| 213 } | |
| 214 } | |
| 215 } | |
| 216 } | |
|
JF
2014/05/01 00:16:55
It seems like the 3 loops above are pretty much th
Jim Stichnoth
2014/05/05 07:03:55
Done. BTW, after refactoring, I discovered that I
| |
| 217 | |
| 218 for (unsigned f = 0; f < NumFunc64; ++f) { | |
| 219 for (unsigned iLo = 0; iLo < NumValues; ++iLo) { | |
| 220 for (unsigned iHi = 0; iHi < NumValues; ++iHi) { | |
| 221 for (unsigned jLo = 0; jLo < NumValues; ++jLo) { | |
| 222 for (unsigned jHi = 0; jHi < NumValues; ++jHi) { | |
| 223 uint64_t Value1 = (((uint64_t)Values[iHi]) << 32) + Values[iLo]; | |
| 224 uint64_t Value2 = (((uint64_t)Values[jHi]) << 32) + Values[jLo]; | |
| 225 | |
| 226 if (Func64[f].DisallowIllegal && Value2 == 0) | |
| 227 continue; | |
| 228 ++TotalTests; | |
| 229 uint64_t ResultSz = Func64[f].FuncSz(Value1, Value2); | |
| 230 uint64_t ResultLlc = Func64[f].FuncLlc(Value1, Value2); | |
| 231 if (ResultSz == ResultLlc) { | |
| 232 ++Passes; | |
| 233 } else { | |
| 234 ++Failures; | |
| 235 printf("%s(0x%016llx, 0x%016llx): sz=%llx llc=%llx\n", | |
| 236 Func64[f].Name, Value1, Value2, ResultSz, ResultLlc); | |
| 237 } | |
| 238 } | |
| 239 } | |
| 240 } | |
| 241 } | |
| 242 } | |
| 243 | |
| 244 printf("TotalTests=%u Passes=%u Failures=%u\n", TotalTests, Passes, Failures); | |
| 245 return Failures; | |
| 246 } | |
| OLD | NEW |