Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 1 | // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef V8_CCTEST_COMPILER_VALUE_HELPER_H_ |
| 6 | #define V8_CCTEST_COMPILER_VALUE_HELPER_H_ |
| 7 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 8 | #include <stdint.h> |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 9 | |
| 10 | #include "src/compiler/common-operator.h" |
| 11 | #include "src/compiler/node.h" |
| 12 | #include "src/compiler/node-matchers.h" |
| 13 | #include "src/isolate.h" |
| 14 | #include "src/objects.h" |
| 15 | #include "test/cctest/cctest.h" |
| 16 | |
| 17 | namespace v8 { |
| 18 | namespace internal { |
| 19 | namespace compiler { |
| 20 | |
| 21 | // A collection of utilities related to numerical and heap values, including |
| 22 | // example input values of various types, including int32_t, uint32_t, double, |
| 23 | // etc. |
| 24 | class ValueHelper { |
| 25 | public: |
| 26 | Isolate* isolate_; |
| 27 | |
| 28 | ValueHelper() : isolate_(CcTest::InitIsolateOnce()) {} |
| 29 | |
| 30 | void CheckFloat64Constant(double expected, Node* node) { |
| 31 | CHECK_EQ(IrOpcode::kFloat64Constant, node->opcode()); |
| 32 | CHECK_EQ(expected, OpParameter<double>(node)); |
| 33 | } |
| 34 | |
| 35 | void CheckNumberConstant(double expected, Node* node) { |
| 36 | CHECK_EQ(IrOpcode::kNumberConstant, node->opcode()); |
| 37 | CHECK_EQ(expected, OpParameter<double>(node)); |
| 38 | } |
| 39 | |
| 40 | void CheckInt32Constant(int32_t expected, Node* node) { |
| 41 | CHECK_EQ(IrOpcode::kInt32Constant, node->opcode()); |
| 42 | CHECK_EQ(expected, OpParameter<int32_t>(node)); |
| 43 | } |
| 44 | |
| 45 | void CheckUint32Constant(int32_t expected, Node* node) { |
| 46 | CHECK_EQ(IrOpcode::kInt32Constant, node->opcode()); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 47 | CHECK_EQ(expected, OpParameter<int32_t>(node)); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 48 | } |
| 49 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 50 | void CheckHeapConstant(HeapObject* expected, Node* node) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 51 | CHECK_EQ(IrOpcode::kHeapConstant, node->opcode()); |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 52 | CHECK_EQ(expected, *OpParameter<Handle<HeapObject>>(node)); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | void CheckTrue(Node* node) { |
| 56 | CheckHeapConstant(isolate_->heap()->true_value(), node); |
| 57 | } |
| 58 | |
| 59 | void CheckFalse(Node* node) { |
| 60 | CheckHeapConstant(isolate_->heap()->false_value(), node); |
| 61 | } |
| 62 | |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 63 | static std::vector<float> float32_vector() { |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 64 | static const float nan = std::numeric_limits<float>::quiet_NaN(); |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 65 | static const float kValues[] = { |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 66 | -std::numeric_limits<float>::infinity(), |
| 67 | -2.70497e+38f, |
| 68 | -1.4698e+37f, |
| 69 | -1.22813e+35f, |
| 70 | -1.20555e+35f, |
| 71 | -1.34584e+34f, |
| 72 | -1.0079e+32f, |
| 73 | -6.49364e+26f, |
| 74 | -3.06077e+25f, |
| 75 | -1.46821e+25f, |
| 76 | -1.17658e+23f, |
| 77 | -1.9617e+22f, |
| 78 | -2.7357e+20f, |
| 79 | -9223372036854775808.0f, // INT64_MIN |
| 80 | -1.48708e+13f, |
| 81 | -1.89633e+12f, |
| 82 | -4.66622e+11f, |
| 83 | -2.22581e+11f, |
| 84 | -1.45381e+10f, |
| 85 | -1.3956e+09f, |
| 86 | -1.32951e+09f, |
| 87 | -1.30721e+09f, |
| 88 | -1.19756e+09f, |
| 89 | -9.26822e+08f, |
| 90 | -6.35647e+08f, |
| 91 | -4.00037e+08f, |
| 92 | -1.81227e+08f, |
| 93 | -5.09256e+07f, |
| 94 | -964300.0f, |
| 95 | -192446.0f, |
| 96 | -28455.0f, |
| 97 | -27194.0f, |
| 98 | -26401.0f, |
| 99 | -20575.0f, |
| 100 | -17069.0f, |
| 101 | -9167.0f, |
| 102 | -960.178f, |
| 103 | -113.0f, |
| 104 | -62.0f, |
| 105 | -15.0f, |
| 106 | -7.0f, |
| 107 | -1.0f, |
| 108 | -0.0256635f, |
| 109 | -4.60374e-07f, |
| 110 | -3.63759e-10f, |
| 111 | -4.30175e-14f, |
| 112 | -5.27385e-15f, |
| 113 | -1.48084e-15f, |
| 114 | -1.05755e-19f, |
| 115 | -3.2995e-21f, |
| 116 | -1.67354e-23f, |
| 117 | -1.11885e-23f, |
| 118 | -1.78506e-30f, |
| 119 | -5.07594e-31f, |
| 120 | -3.65799e-31f, |
| 121 | -1.43718e-34f, |
| 122 | -1.27126e-38f, |
| 123 | -0.0f, |
| 124 | 0.0f, |
| 125 | 1.17549e-38f, |
| 126 | 1.56657e-37f, |
| 127 | 4.08512e-29f, |
| 128 | 3.31357e-28f, |
| 129 | 6.25073e-22f, |
| 130 | 4.1723e-13f, |
| 131 | 1.44343e-09f, |
| 132 | 5.27004e-08f, |
| 133 | 9.48298e-08f, |
| 134 | 5.57888e-07f, |
| 135 | 4.89988e-05f, |
| 136 | 0.244326f, |
| 137 | 1.0f, |
| 138 | 12.4895f, |
| 139 | 19.0f, |
| 140 | 47.0f, |
| 141 | 106.0f, |
| 142 | 538.324f, |
| 143 | 564.536f, |
| 144 | 819.124f, |
| 145 | 7048.0f, |
| 146 | 12611.0f, |
| 147 | 19878.0f, |
| 148 | 20309.0f, |
| 149 | 797056.0f, |
| 150 | 1.77219e+09f, |
| 151 | 1.51116e+11f, |
| 152 | 4.18193e+13f, |
| 153 | 3.59167e+16f, |
| 154 | 9223372036854775807.0f, // INT64_MAX |
| 155 | 18446744073709551615.0f, // UINT64_MAX |
| 156 | 3.38211e+19f, |
| 157 | 2.67488e+20f, |
| 158 | 1.78831e+21f, |
| 159 | 9.20914e+21f, |
| 160 | 8.35654e+23f, |
| 161 | 1.4495e+24f, |
| 162 | 5.94015e+25f, |
| 163 | 4.43608e+30f, |
| 164 | 2.44502e+33f, |
| 165 | 2.61152e+33f, |
| 166 | 1.38178e+37f, |
| 167 | 1.71306e+37f, |
| 168 | 3.31899e+38f, |
| 169 | 3.40282e+38f, |
| 170 | std::numeric_limits<float>::infinity(), |
| 171 | nan, |
| 172 | -nan, |
| 173 | }; |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 174 | return std::vector<float>(&kValues[0], &kValues[arraysize(kValues)]); |
| 175 | } |
| 176 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 177 | static std::vector<double> float64_vector() { |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 178 | static const double nan = std::numeric_limits<double>::quiet_NaN(); |
| 179 | static const double values[] = {-2e66, |
| 180 | -9223373136366403584.0, |
| 181 | -9223372036854775808.0, // INT64_MIN |
| 182 | -2147483649.5, |
| 183 | -2147483648.25, |
| 184 | -2147483648.0, |
| 185 | -2147483647.875, |
| 186 | -2147483647.125, |
| 187 | -2147483647.0, |
| 188 | -999.75, |
| 189 | -2e66, |
| 190 | -1.75, |
| 191 | -1.0, |
| 192 | -0.5, |
| 193 | -0.0, |
| 194 | 0.0, |
| 195 | 3e-88, |
| 196 | 0.125, |
| 197 | 0.25, |
| 198 | 0.375, |
| 199 | 0.5, |
| 200 | 1.0, |
| 201 | 1.25, |
| 202 | 2, |
| 203 | 3.1e7, |
| 204 | 5.125, |
| 205 | 6.25, |
| 206 | 888, |
| 207 | 982983.25, |
| 208 | 2147483647.0, |
| 209 | 2147483647.375, |
| 210 | 2147483647.75, |
| 211 | 2147483648.0, |
| 212 | 2147483648.25, |
| 213 | 2147483649.25, |
| 214 | 9223372036854775807.0, // INT64_MAX |
| 215 | 9223373136366403584.0, |
| 216 | 18446744073709551615.0, // UINT64_MAX |
| 217 | 2e66, |
| 218 | V8_INFINITY, |
| 219 | -V8_INFINITY, |
| 220 | -nan, |
| 221 | nan}; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 222 | return std::vector<double>(&values[0], &values[arraysize(values)]); |
| 223 | } |
| 224 | |
| 225 | static const std::vector<int32_t> int32_vector() { |
| 226 | std::vector<uint32_t> values = uint32_vector(); |
| 227 | return std::vector<int32_t>(values.begin(), values.end()); |
| 228 | } |
| 229 | |
| 230 | static const std::vector<uint32_t> uint32_vector() { |
| 231 | static const uint32_t kValues[] = { |
| 232 | 0x00000000, 0x00000001, 0xffffffff, 0x1b09788b, 0x04c5fce8, 0xcc0de5bf, |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 233 | // This row is useful for testing lea optimizations on intel. |
| 234 | 0x00000002, 0x00000003, 0x00000004, 0x00000005, 0x00000008, 0x00000009, |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 235 | 0x273a798e, 0x187937a3, 0xece3af83, 0x5495a16b, 0x0b668ecc, 0x11223344, |
| 236 | 0x0000009e, 0x00000043, 0x0000af73, 0x0000116b, 0x00658ecc, 0x002b3b4c, |
| 237 | 0x88776655, 0x70000000, 0x07200000, 0x7fffffff, 0x56123761, 0x7fffff00, |
| 238 | 0x761c4761, 0x80000000, 0x88888888, 0xa0000000, 0xdddddddd, 0xe0000000, |
| 239 | 0xeeeeeeee, 0xfffffffd, 0xf0000000, 0x007fffff, 0x003fffff, 0x001fffff, |
| 240 | 0x000fffff, 0x0007ffff, 0x0003ffff, 0x0001ffff, 0x0000ffff, 0x00007fff, |
| 241 | 0x00003fff, 0x00001fff, 0x00000fff, 0x000007ff, 0x000003ff, 0x000001ff}; |
| 242 | return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
| 243 | } |
| 244 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 245 | static const std::vector<int64_t> int64_vector() { |
| 246 | std::vector<uint64_t> values = uint64_vector(); |
| 247 | return std::vector<int64_t>(values.begin(), values.end()); |
| 248 | } |
| 249 | |
| 250 | static const std::vector<uint64_t> uint64_vector() { |
| 251 | static const uint64_t kValues[] = { |
| 252 | 0x00000000, 0x00000001, 0xffffffff, |
| 253 | 0x1b09788b, 0x04c5fce8, 0xcc0de5bf, |
| 254 | 0x00000002, 0x00000003, 0x00000004, |
| 255 | 0x00000005, 0x00000008, 0x00000009, |
| 256 | 0xffffffffffffffff, 0xfffffffffffffffe, 0xfffffffffffffffd, |
| 257 | 0x0000000000000000, 0x0000000100000000, 0xffffffff00000000, |
| 258 | 0x1b09788b00000000, 0x04c5fce800000000, 0xcc0de5bf00000000, |
| 259 | 0x0000000200000000, 0x0000000300000000, 0x0000000400000000, |
| 260 | 0x0000000500000000, 0x0000000800000000, 0x0000000900000000, |
| 261 | 0x273a798e187937a3, 0xece3af835495a16b, 0x0b668ecc11223344, |
| 262 | 0x0000009e, 0x00000043, 0x0000af73, |
| 263 | 0x0000116b, 0x00658ecc, 0x002b3b4c, |
| 264 | 0x88776655, 0x70000000, 0x07200000, |
| 265 | 0x7fffffff, 0x56123761, 0x7fffff00, |
| 266 | 0x761c4761eeeeeeee, 0x80000000eeeeeeee, 0x88888888dddddddd, |
| 267 | 0xa0000000dddddddd, 0xddddddddaaaaaaaa, 0xe0000000aaaaaaaa, |
| 268 | 0xeeeeeeeeeeeeeeee, 0xfffffffdeeeeeeee, 0xf0000000dddddddd, |
| 269 | 0x007fffffdddddddd, 0x003fffffaaaaaaaa, 0x001fffffaaaaaaaa, |
| 270 | 0x000fffff, 0x0007ffff, 0x0003ffff, |
| 271 | 0x0001ffff, 0x0000ffff, 0x00007fff, |
| 272 | 0x00003fff, 0x00001fff, 0x00000fff, |
| 273 | 0x000007ff, 0x000003ff, 0x000001ff, |
| 274 | 0x00003fffffffffff, 0x00001fffffffffff, 0x00000fffffffffff, |
| 275 | 0x000007ffffffffff, 0x000003ffffffffff, 0x000001ffffffffff, |
| 276 | 0x8000008000000000, 0x8000008000000001, 0x8000000000000400, |
| 277 | 0x8000000000000401}; |
| 278 | return std::vector<uint64_t>(&kValues[0], &kValues[arraysize(kValues)]); |
| 279 | } |
| 280 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 281 | static const std::vector<double> nan_vector(size_t limit = 0) { |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 282 | static const double nan = std::numeric_limits<double>::quiet_NaN(); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 283 | static const double values[] = {-nan, -V8_INFINITY * -0.0, |
| 284 | -V8_INFINITY * 0.0, V8_INFINITY * -0.0, |
| 285 | V8_INFINITY * 0.0, nan}; |
| 286 | return std::vector<double>(&values[0], &values[arraysize(values)]); |
| 287 | } |
| 288 | |
| 289 | static const std::vector<uint32_t> ror_vector() { |
| 290 | static const uint32_t kValues[31] = { |
| 291 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, |
| 292 | 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31}; |
| 293 | return std::vector<uint32_t>(&kValues[0], &kValues[arraysize(kValues)]); |
| 294 | } |
| 295 | }; |
| 296 | |
| 297 | // Helper macros that can be used in FOR_INT32_INPUTS(i) { ... *i ... } |
| 298 | // Watch out, these macros aren't hygenic; they pollute your scope. Thanks STL. |
| 299 | #define FOR_INPUTS(ctype, itype, var) \ |
| 300 | std::vector<ctype> var##_vec = ValueHelper::itype##_vector(); \ |
| 301 | for (std::vector<ctype>::iterator var = var##_vec.begin(); \ |
| 302 | var != var##_vec.end(); ++var) |
| 303 | |
| 304 | #define FOR_INT32_INPUTS(var) FOR_INPUTS(int32_t, int32, var) |
| 305 | #define FOR_UINT32_INPUTS(var) FOR_INPUTS(uint32_t, uint32, var) |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 306 | #define FOR_INT64_INPUTS(var) FOR_INPUTS(int64_t, int64, var) |
| 307 | #define FOR_UINT64_INPUTS(var) FOR_INPUTS(uint64_t, uint64, var) |
Emily Bernier | d0a1eb7 | 2015-03-24 16:35:39 -0400 | [diff] [blame] | 308 | #define FOR_FLOAT32_INPUTS(var) FOR_INPUTS(float, float32, var) |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 309 | #define FOR_FLOAT64_INPUTS(var) FOR_INPUTS(double, float64, var) |
| 310 | |
| 311 | #define FOR_INT32_SHIFTS(var) for (int32_t var = 0; var < 32; var++) |
| 312 | |
| 313 | #define FOR_UINT32_SHIFTS(var) for (uint32_t var = 0; var < 32; var++) |
| 314 | |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame^] | 315 | // TODO(bmeurer): Drop this crap once we switch to GTest/Gmock. |
| 316 | static inline void CheckFloatEq(volatile float x, volatile float y) { |
| 317 | if (std::isnan(x)) { |
| 318 | CHECK(std::isnan(y)); |
| 319 | } else { |
| 320 | CHECK_EQ(x, y); |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | static inline void CheckDoubleEq(volatile double x, volatile double y) { |
| 325 | if (std::isnan(x)) { |
| 326 | CHECK(std::isnan(y)); |
| 327 | } else { |
| 328 | CHECK_EQ(x, y); |
| 329 | } |
| 330 | } |
| 331 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame] | 332 | } // namespace compiler |
| 333 | } // namespace internal |
| 334 | } // namespace v8 |
| 335 | |
| 336 | #endif // V8_CCTEST_COMPILER_VALUE_HELPER_H_ |