1 // Copyright 2014 the V8 project authors. All rights reserved. Use of this 2 // source code is governed by a BSD-style license that can be found in the 3 // LICENSE file. 4 5 #include <cmath> 6 #include <functional> 7 #include <limits> 8 9 #include "src/base/bits.h" 10 #include "src/base/utils/random-number-generator.h" 11 #include "src/codegen.h" 12 #include "test/cctest/cctest.h" 13 #include "test/cctest/compiler/codegen-tester.h" 14 #include "test/cctest/compiler/graph-builder-tester.h" 15 #include "test/cctest/compiler/value-helper.h" 16 17 using namespace v8::base; 18 19 namespace v8 { 20 namespace internal { 21 namespace compiler { 22 23 24 TEST(RunInt32Add) { 25 RawMachineAssemblerTester<int32_t> m; 26 Node* add = m.Int32Add(m.Int32Constant(0), m.Int32Constant(1)); 27 m.Return(add); 28 CHECK_EQ(1, m.Call()); 29 } 30 31 32 TEST(RunWord32Ctz) { 33 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 34 if (!m.machine()->Word32Ctz().IsSupported()) { 35 // We can only test the operator if it exists on the testing platform. 36 return; 37 } 38 m.Return(m.AddNode(m.machine()->Word32Ctz().op(), m.Parameter(0))); 39 40 CHECK_EQ(32, m.Call(uint32_t(0x00000000))); 41 CHECK_EQ(31, m.Call(uint32_t(0x80000000))); 42 CHECK_EQ(30, m.Call(uint32_t(0x40000000))); 43 CHECK_EQ(29, m.Call(uint32_t(0x20000000))); 44 CHECK_EQ(28, m.Call(uint32_t(0x10000000))); 45 CHECK_EQ(27, m.Call(uint32_t(0xa8000000))); 46 CHECK_EQ(26, m.Call(uint32_t(0xf4000000))); 47 CHECK_EQ(25, m.Call(uint32_t(0x62000000))); 48 CHECK_EQ(24, m.Call(uint32_t(0x91000000))); 49 CHECK_EQ(23, m.Call(uint32_t(0xcd800000))); 50 CHECK_EQ(22, m.Call(uint32_t(0x09400000))); 51 CHECK_EQ(21, m.Call(uint32_t(0xaf200000))); 52 CHECK_EQ(20, m.Call(uint32_t(0xac100000))); 53 CHECK_EQ(19, m.Call(uint32_t(0xe0b80000))); 54 CHECK_EQ(18, m.Call(uint32_t(0x9ce40000))); 55 CHECK_EQ(17, m.Call(uint32_t(0xc7920000))); 56 CHECK_EQ(16, m.Call(uint32_t(0xb8f10000))); 57 CHECK_EQ(15, m.Call(uint32_t(0x3b9f8000))); 58 CHECK_EQ(14, m.Call(uint32_t(0xdb4c4000))); 59 CHECK_EQ(13, m.Call(uint32_t(0xe9a32000))); 60 CHECK_EQ(12, m.Call(uint32_t(0xfca61000))); 61 CHECK_EQ(11, m.Call(uint32_t(0x6c8a7800))); 62 CHECK_EQ(10, m.Call(uint32_t(0x8ce5a400))); 63 CHECK_EQ(9, m.Call(uint32_t(0xcb7d0200))); 64 CHECK_EQ(8, m.Call(uint32_t(0xcb4dc100))); 65 CHECK_EQ(7, m.Call(uint32_t(0xdfbec580))); 66 CHECK_EQ(6, m.Call(uint32_t(0x27a9db40))); 67 CHECK_EQ(5, m.Call(uint32_t(0xde3bcb20))); 68 CHECK_EQ(4, m.Call(uint32_t(0xd7e8a610))); 69 CHECK_EQ(3, m.Call(uint32_t(0x9afdbc88))); 70 CHECK_EQ(2, m.Call(uint32_t(0x9afdbc84))); 71 CHECK_EQ(1, m.Call(uint32_t(0x9afdbc82))); 72 CHECK_EQ(0, m.Call(uint32_t(0x9afdbc81))); 73 } 74 75 76 TEST(RunWord32Clz) { 77 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 78 m.Return(m.Word32Clz(m.Parameter(0))); 79 80 CHECK_EQ(0, m.Call(uint32_t(0x80001000))); 81 CHECK_EQ(1, m.Call(uint32_t(0x40000500))); 82 CHECK_EQ(2, m.Call(uint32_t(0x20000300))); 83 CHECK_EQ(3, m.Call(uint32_t(0x10000003))); 84 CHECK_EQ(4, m.Call(uint32_t(0x08050000))); 85 CHECK_EQ(5, m.Call(uint32_t(0x04006000))); 86 CHECK_EQ(6, m.Call(uint32_t(0x02000000))); 87 CHECK_EQ(7, m.Call(uint32_t(0x010000a0))); 88 CHECK_EQ(8, m.Call(uint32_t(0x00800c00))); 89 CHECK_EQ(9, m.Call(uint32_t(0x00400000))); 90 CHECK_EQ(10, m.Call(uint32_t(0x0020000d))); 91 CHECK_EQ(11, m.Call(uint32_t(0x00100f00))); 92 CHECK_EQ(12, m.Call(uint32_t(0x00080000))); 93 CHECK_EQ(13, m.Call(uint32_t(0x00041000))); 94 CHECK_EQ(14, m.Call(uint32_t(0x00020020))); 95 CHECK_EQ(15, m.Call(uint32_t(0x00010300))); 96 CHECK_EQ(16, m.Call(uint32_t(0x00008040))); 97 CHECK_EQ(17, m.Call(uint32_t(0x00004005))); 98 CHECK_EQ(18, m.Call(uint32_t(0x00002050))); 99 CHECK_EQ(19, m.Call(uint32_t(0x00001700))); 100 CHECK_EQ(20, m.Call(uint32_t(0x00000870))); 101 CHECK_EQ(21, m.Call(uint32_t(0x00000405))); 102 CHECK_EQ(22, m.Call(uint32_t(0x00000203))); 103 CHECK_EQ(23, m.Call(uint32_t(0x00000101))); 104 CHECK_EQ(24, m.Call(uint32_t(0x00000089))); 105 CHECK_EQ(25, m.Call(uint32_t(0x00000041))); 106 CHECK_EQ(26, m.Call(uint32_t(0x00000022))); 107 CHECK_EQ(27, m.Call(uint32_t(0x00000013))); 108 CHECK_EQ(28, m.Call(uint32_t(0x00000008))); 109 CHECK_EQ(29, m.Call(uint32_t(0x00000004))); 110 CHECK_EQ(30, m.Call(uint32_t(0x00000002))); 111 CHECK_EQ(31, m.Call(uint32_t(0x00000001))); 112 CHECK_EQ(32, m.Call(uint32_t(0x00000000))); 113 } 114 115 116 TEST(RunWord32Popcnt) { 117 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 118 if (!m.machine()->Word32Popcnt().IsSupported()) { 119 // We can only test the operator if it exists on the testing platform. 120 return; 121 } 122 m.Return(m.AddNode(m.machine()->Word32Popcnt().op(), m.Parameter(0))); 123 124 CHECK_EQ(0, m.Call(uint32_t(0x00000000))); 125 CHECK_EQ(1, m.Call(uint32_t(0x00000001))); 126 CHECK_EQ(1, m.Call(uint32_t(0x80000000))); 127 CHECK_EQ(32, m.Call(uint32_t(0xffffffff))); 128 CHECK_EQ(6, m.Call(uint32_t(0x000dc100))); 129 CHECK_EQ(9, m.Call(uint32_t(0xe00dc100))); 130 CHECK_EQ(11, m.Call(uint32_t(0xe00dc103))); 131 CHECK_EQ(9, m.Call(uint32_t(0x000dc107))); 132 } 133 134 135 #if V8_TARGET_ARCH_64_BIT 136 TEST(RunWord64Clz) { 137 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64()); 138 m.Return(m.Word64Clz(m.Parameter(0))); 139 140 CHECK_EQ(0, m.Call(uint64_t(0x8000100000000000))); 141 CHECK_EQ(1, m.Call(uint64_t(0x4000050000000000))); 142 CHECK_EQ(2, m.Call(uint64_t(0x2000030000000000))); 143 CHECK_EQ(3, m.Call(uint64_t(0x1000000300000000))); 144 CHECK_EQ(4, m.Call(uint64_t(0x0805000000000000))); 145 CHECK_EQ(5, m.Call(uint64_t(0x0400600000000000))); 146 CHECK_EQ(6, m.Call(uint64_t(0x0200000000000000))); 147 CHECK_EQ(7, m.Call(uint64_t(0x010000a000000000))); 148 CHECK_EQ(8, m.Call(uint64_t(0x00800c0000000000))); 149 CHECK_EQ(9, m.Call(uint64_t(0x0040000000000000))); 150 CHECK_EQ(10, m.Call(uint64_t(0x0020000d00000000))); 151 CHECK_EQ(11, m.Call(uint64_t(0x00100f0000000000))); 152 CHECK_EQ(12, m.Call(uint64_t(0x0008000000000000))); 153 CHECK_EQ(13, m.Call(uint64_t(0x0004100000000000))); 154 CHECK_EQ(14, m.Call(uint64_t(0x0002002000000000))); 155 CHECK_EQ(15, m.Call(uint64_t(0x0001030000000000))); 156 CHECK_EQ(16, m.Call(uint64_t(0x0000804000000000))); 157 CHECK_EQ(17, m.Call(uint64_t(0x0000400500000000))); 158 CHECK_EQ(18, m.Call(uint64_t(0x0000205000000000))); 159 CHECK_EQ(19, m.Call(uint64_t(0x0000170000000000))); 160 CHECK_EQ(20, m.Call(uint64_t(0x0000087000000000))); 161 CHECK_EQ(21, m.Call(uint64_t(0x0000040500000000))); 162 CHECK_EQ(22, m.Call(uint64_t(0x0000020300000000))); 163 CHECK_EQ(23, m.Call(uint64_t(0x0000010100000000))); 164 CHECK_EQ(24, m.Call(uint64_t(0x0000008900000000))); 165 CHECK_EQ(25, m.Call(uint64_t(0x0000004100000000))); 166 CHECK_EQ(26, m.Call(uint64_t(0x0000002200000000))); 167 CHECK_EQ(27, m.Call(uint64_t(0x0000001300000000))); 168 CHECK_EQ(28, m.Call(uint64_t(0x0000000800000000))); 169 CHECK_EQ(29, m.Call(uint64_t(0x0000000400000000))); 170 CHECK_EQ(30, m.Call(uint64_t(0x0000000200000000))); 171 CHECK_EQ(31, m.Call(uint64_t(0x0000000100000000))); 172 CHECK_EQ(32, m.Call(uint64_t(0x0000000080001000))); 173 CHECK_EQ(33, m.Call(uint64_t(0x0000000040000500))); 174 CHECK_EQ(34, m.Call(uint64_t(0x0000000020000300))); 175 CHECK_EQ(35, m.Call(uint64_t(0x0000000010000003))); 176 CHECK_EQ(36, m.Call(uint64_t(0x0000000008050000))); 177 CHECK_EQ(37, m.Call(uint64_t(0x0000000004006000))); 178 CHECK_EQ(38, m.Call(uint64_t(0x0000000002000000))); 179 CHECK_EQ(39, m.Call(uint64_t(0x00000000010000a0))); 180 CHECK_EQ(40, m.Call(uint64_t(0x0000000000800c00))); 181 CHECK_EQ(41, m.Call(uint64_t(0x0000000000400000))); 182 CHECK_EQ(42, m.Call(uint64_t(0x000000000020000d))); 183 CHECK_EQ(43, m.Call(uint64_t(0x0000000000100f00))); 184 CHECK_EQ(44, m.Call(uint64_t(0x0000000000080000))); 185 CHECK_EQ(45, m.Call(uint64_t(0x0000000000041000))); 186 CHECK_EQ(46, m.Call(uint64_t(0x0000000000020020))); 187 CHECK_EQ(47, m.Call(uint64_t(0x0000000000010300))); 188 CHECK_EQ(48, m.Call(uint64_t(0x0000000000008040))); 189 CHECK_EQ(49, m.Call(uint64_t(0x0000000000004005))); 190 CHECK_EQ(50, m.Call(uint64_t(0x0000000000002050))); 191 CHECK_EQ(51, m.Call(uint64_t(0x0000000000001700))); 192 CHECK_EQ(52, m.Call(uint64_t(0x0000000000000870))); 193 CHECK_EQ(53, m.Call(uint64_t(0x0000000000000405))); 194 CHECK_EQ(54, m.Call(uint64_t(0x0000000000000203))); 195 CHECK_EQ(55, m.Call(uint64_t(0x0000000000000101))); 196 CHECK_EQ(56, m.Call(uint64_t(0x0000000000000089))); 197 CHECK_EQ(57, m.Call(uint64_t(0x0000000000000041))); 198 CHECK_EQ(58, m.Call(uint64_t(0x0000000000000022))); 199 CHECK_EQ(59, m.Call(uint64_t(0x0000000000000013))); 200 CHECK_EQ(60, m.Call(uint64_t(0x0000000000000008))); 201 CHECK_EQ(61, m.Call(uint64_t(0x0000000000000004))); 202 CHECK_EQ(62, m.Call(uint64_t(0x0000000000000002))); 203 CHECK_EQ(63, m.Call(uint64_t(0x0000000000000001))); 204 CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000))); 205 } 206 207 208 TEST(RunWord64Ctz) { 209 RawMachineAssemblerTester<int32_t> m(MachineType::Uint64()); 210 if (!m.machine()->Word64Ctz().IsSupported()) { 211 return; 212 } 213 214 m.Return(m.AddNode(m.machine()->Word64Ctz().op(), m.Parameter(0))); 215 216 CHECK_EQ(64, m.Call(uint64_t(0x0000000000000000))); 217 CHECK_EQ(63, m.Call(uint64_t(0x8000000000000000))); 218 CHECK_EQ(62, m.Call(uint64_t(0x4000000000000000))); 219 CHECK_EQ(61, m.Call(uint64_t(0x2000000000000000))); 220 CHECK_EQ(60, m.Call(uint64_t(0x1000000000000000))); 221 CHECK_EQ(59, m.Call(uint64_t(0xa800000000000000))); 222 CHECK_EQ(58, m.Call(uint64_t(0xf400000000000000))); 223 CHECK_EQ(57, m.Call(uint64_t(0x6200000000000000))); 224 CHECK_EQ(56, m.Call(uint64_t(0x9100000000000000))); 225 CHECK_EQ(55, m.Call(uint64_t(0xcd80000000000000))); 226 CHECK_EQ(54, m.Call(uint64_t(0x0940000000000000))); 227 CHECK_EQ(53, m.Call(uint64_t(0xaf20000000000000))); 228 CHECK_EQ(52, m.Call(uint64_t(0xac10000000000000))); 229 CHECK_EQ(51, m.Call(uint64_t(0xe0b8000000000000))); 230 CHECK_EQ(50, m.Call(uint64_t(0x9ce4000000000000))); 231 CHECK_EQ(49, m.Call(uint64_t(0xc792000000000000))); 232 CHECK_EQ(48, m.Call(uint64_t(0xb8f1000000000000))); 233 CHECK_EQ(47, m.Call(uint64_t(0x3b9f800000000000))); 234 CHECK_EQ(46, m.Call(uint64_t(0xdb4c400000000000))); 235 CHECK_EQ(45, m.Call(uint64_t(0xe9a3200000000000))); 236 CHECK_EQ(44, m.Call(uint64_t(0xfca6100000000000))); 237 CHECK_EQ(43, m.Call(uint64_t(0x6c8a780000000000))); 238 CHECK_EQ(42, m.Call(uint64_t(0x8ce5a40000000000))); 239 CHECK_EQ(41, m.Call(uint64_t(0xcb7d020000000000))); 240 CHECK_EQ(40, m.Call(uint64_t(0xcb4dc10000000000))); 241 CHECK_EQ(39, m.Call(uint64_t(0xdfbec58000000000))); 242 CHECK_EQ(38, m.Call(uint64_t(0x27a9db4000000000))); 243 CHECK_EQ(37, m.Call(uint64_t(0xde3bcb2000000000))); 244 CHECK_EQ(36, m.Call(uint64_t(0xd7e8a61000000000))); 245 CHECK_EQ(35, m.Call(uint64_t(0x9afdbc8800000000))); 246 CHECK_EQ(34, m.Call(uint64_t(0x9afdbc8400000000))); 247 CHECK_EQ(33, m.Call(uint64_t(0x9afdbc8200000000))); 248 CHECK_EQ(32, m.Call(uint64_t(0x9afdbc8100000000))); 249 CHECK_EQ(31, m.Call(uint64_t(0x0000000080000000))); 250 CHECK_EQ(30, m.Call(uint64_t(0x0000000040000000))); 251 CHECK_EQ(29, m.Call(uint64_t(0x0000000020000000))); 252 CHECK_EQ(28, m.Call(uint64_t(0x0000000010000000))); 253 CHECK_EQ(27, m.Call(uint64_t(0x00000000a8000000))); 254 CHECK_EQ(26, m.Call(uint64_t(0x00000000f4000000))); 255 CHECK_EQ(25, m.Call(uint64_t(0x0000000062000000))); 256 CHECK_EQ(24, m.Call(uint64_t(0x0000000091000000))); 257 CHECK_EQ(23, m.Call(uint64_t(0x00000000cd800000))); 258 CHECK_EQ(22, m.Call(uint64_t(0x0000000009400000))); 259 CHECK_EQ(21, m.Call(uint64_t(0x00000000af200000))); 260 CHECK_EQ(20, m.Call(uint64_t(0x00000000ac100000))); 261 CHECK_EQ(19, m.Call(uint64_t(0x00000000e0b80000))); 262 CHECK_EQ(18, m.Call(uint64_t(0x000000009ce40000))); 263 CHECK_EQ(17, m.Call(uint64_t(0x00000000c7920000))); 264 CHECK_EQ(16, m.Call(uint64_t(0x00000000b8f10000))); 265 CHECK_EQ(15, m.Call(uint64_t(0x000000003b9f8000))); 266 CHECK_EQ(14, m.Call(uint64_t(0x00000000db4c4000))); 267 CHECK_EQ(13, m.Call(uint64_t(0x00000000e9a32000))); 268 CHECK_EQ(12, m.Call(uint64_t(0x00000000fca61000))); 269 CHECK_EQ(11, m.Call(uint64_t(0x000000006c8a7800))); 270 CHECK_EQ(10, m.Call(uint64_t(0x000000008ce5a400))); 271 CHECK_EQ(9, m.Call(uint64_t(0x00000000cb7d0200))); 272 CHECK_EQ(8, m.Call(uint64_t(0x00000000cb4dc100))); 273 CHECK_EQ(7, m.Call(uint64_t(0x00000000dfbec580))); 274 CHECK_EQ(6, m.Call(uint64_t(0x0000000027a9db40))); 275 CHECK_EQ(5, m.Call(uint64_t(0x00000000de3bcb20))); 276 CHECK_EQ(4, m.Call(uint64_t(0x00000000d7e8a610))); 277 CHECK_EQ(3, m.Call(uint64_t(0x000000009afdbc88))); 278 CHECK_EQ(2, m.Call(uint64_t(0x000000009afdbc84))); 279 CHECK_EQ(1, m.Call(uint64_t(0x000000009afdbc82))); 280 CHECK_EQ(0, m.Call(uint64_t(0x000000009afdbc81))); 281 } 282 283 284 TEST(RunWord64Popcnt) { 285 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Uint64()); 286 if (!m.machine()->Word64Popcnt().IsSupported()) { 287 return; 288 } 289 290 m.Return(m.AddNode(m.machine()->Word64Popcnt().op(), m.Parameter(0))); 291 292 CHECK_EQ(0, m.Call(uint64_t(0x0000000000000000))); 293 CHECK_EQ(1, m.Call(uint64_t(0x0000000000000001))); 294 CHECK_EQ(1, m.Call(uint64_t(0x8000000000000000))); 295 CHECK_EQ(64, m.Call(uint64_t(0xffffffffffffffff))); 296 CHECK_EQ(12, m.Call(uint64_t(0x000dc100000dc100))); 297 CHECK_EQ(18, m.Call(uint64_t(0xe00dc100e00dc100))); 298 CHECK_EQ(22, m.Call(uint64_t(0xe00dc103e00dc103))); 299 CHECK_EQ(18, m.Call(uint64_t(0x000dc107000dc107))); 300 } 301 #endif // V8_TARGET_ARCH_64_BIT 302 303 304 static Node* Int32Input(RawMachineAssemblerTester<int32_t>* m, int index) { 305 switch (index) { 306 case 0: 307 return m->Parameter(0); 308 case 1: 309 return m->Parameter(1); 310 case 2: 311 return m->Int32Constant(0); 312 case 3: 313 return m->Int32Constant(1); 314 case 4: 315 return m->Int32Constant(-1); 316 case 5: 317 return m->Int32Constant(0xff); 318 case 6: 319 return m->Int32Constant(0x01234567); 320 case 7: 321 return m->Load(MachineType::Int32(), m->PointerConstant(NULL)); 322 default: 323 return NULL; 324 } 325 } 326 327 328 TEST(CodeGenInt32Binop) { 329 RawMachineAssemblerTester<void> m; 330 331 const Operator* kOps[] = { 332 m.machine()->Word32And(), m.machine()->Word32Or(), 333 m.machine()->Word32Xor(), m.machine()->Word32Shl(), 334 m.machine()->Word32Shr(), m.machine()->Word32Sar(), 335 m.machine()->Word32Equal(), m.machine()->Int32Add(), 336 m.machine()->Int32Sub(), m.machine()->Int32Mul(), 337 m.machine()->Int32MulHigh(), m.machine()->Int32Div(), 338 m.machine()->Uint32Div(), m.machine()->Int32Mod(), 339 m.machine()->Uint32Mod(), m.machine()->Uint32MulHigh(), 340 m.machine()->Int32LessThan(), m.machine()->Int32LessThanOrEqual(), 341 m.machine()->Uint32LessThan(), m.machine()->Uint32LessThanOrEqual()}; 342 343 for (size_t i = 0; i < arraysize(kOps); ++i) { 344 for (int j = 0; j < 8; j++) { 345 for (int k = 0; k < 8; k++) { 346 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 347 MachineType::Int32()); 348 Node* a = Int32Input(&m, j); 349 Node* b = Int32Input(&m, k); 350 m.Return(m.AddNode(kOps[i], a, b)); 351 m.GenerateCode(); 352 } 353 } 354 } 355 } 356 357 358 TEST(CodeGenNop) { 359 RawMachineAssemblerTester<void> m; 360 m.Return(m.Int32Constant(0)); 361 m.GenerateCode(); 362 } 363 364 365 #if V8_TARGET_ARCH_64_BIT 366 static Node* Int64Input(RawMachineAssemblerTester<int64_t>* m, int index) { 367 switch (index) { 368 case 0: 369 return m->Parameter(0); 370 case 1: 371 return m->Parameter(1); 372 case 2: 373 return m->Int64Constant(0); 374 case 3: 375 return m->Int64Constant(1); 376 case 4: 377 return m->Int64Constant(-1); 378 case 5: 379 return m->Int64Constant(0xff); 380 case 6: 381 return m->Int64Constant(0x0123456789abcdefLL); 382 case 7: 383 return m->Load(MachineType::Int64(), m->PointerConstant(NULL)); 384 default: 385 return NULL; 386 } 387 } 388 389 390 TEST(CodeGenInt64Binop) { 391 RawMachineAssemblerTester<void> m; 392 393 const Operator* kOps[] = { 394 m.machine()->Word64And(), m.machine()->Word64Or(), 395 m.machine()->Word64Xor(), m.machine()->Word64Shl(), 396 m.machine()->Word64Shr(), m.machine()->Word64Sar(), 397 m.machine()->Word64Equal(), m.machine()->Int64Add(), 398 m.machine()->Int64Sub(), m.machine()->Int64Mul(), m.machine()->Int64Div(), 399 m.machine()->Uint64Div(), m.machine()->Int64Mod(), 400 m.machine()->Uint64Mod(), m.machine()->Int64LessThan(), 401 m.machine()->Int64LessThanOrEqual(), m.machine()->Uint64LessThan(), 402 m.machine()->Uint64LessThanOrEqual()}; 403 404 for (size_t i = 0; i < arraysize(kOps); ++i) { 405 for (int j = 0; j < 8; j++) { 406 for (int k = 0; k < 8; k++) { 407 RawMachineAssemblerTester<int64_t> m(MachineType::Int64(), 408 MachineType::Int64()); 409 Node* a = Int64Input(&m, j); 410 Node* b = Int64Input(&m, k); 411 m.Return(m.AddNode(kOps[i], a, b)); 412 m.GenerateCode(); 413 } 414 } 415 } 416 } 417 418 419 TEST(RunInt64AddWithOverflowP) { 420 int64_t actual_val = -1; 421 RawMachineAssemblerTester<int32_t> m; 422 Int64BinopTester bt(&m); 423 Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1); 424 Node* val = m.Projection(0, add); 425 Node* ovf = m.Projection(1, add); 426 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 427 bt.AddReturn(ovf); 428 FOR_INT64_INPUTS(i) { 429 FOR_INT64_INPUTS(j) { 430 int64_t expected_val; 431 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); 432 CHECK_EQ(expected_ovf, bt.call(*i, *j)); 433 CHECK_EQ(expected_val, actual_val); 434 } 435 } 436 } 437 438 439 TEST(RunInt64AddWithOverflowImm) { 440 int64_t actual_val = -1, expected_val = 0; 441 FOR_INT64_INPUTS(i) { 442 { 443 RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); 444 Node* add = m.Int64AddWithOverflow(m.Int64Constant(*i), m.Parameter(0)); 445 Node* val = m.Projection(0, add); 446 Node* ovf = m.Projection(1, add); 447 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 448 m.Return(ovf); 449 FOR_INT64_INPUTS(j) { 450 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); 451 CHECK_EQ(expected_ovf, m.Call(*j)); 452 CHECK_EQ(expected_val, actual_val); 453 } 454 } 455 { 456 RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); 457 Node* add = m.Int64AddWithOverflow(m.Parameter(0), m.Int64Constant(*i)); 458 Node* val = m.Projection(0, add); 459 Node* ovf = m.Projection(1, add); 460 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 461 m.Return(ovf); 462 FOR_INT64_INPUTS(j) { 463 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); 464 CHECK_EQ(expected_ovf, m.Call(*j)); 465 CHECK_EQ(expected_val, actual_val); 466 } 467 } 468 FOR_INT64_INPUTS(j) { 469 RawMachineAssemblerTester<int32_t> m; 470 Node* add = 471 m.Int64AddWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j)); 472 Node* val = m.Projection(0, add); 473 Node* ovf = m.Projection(1, add); 474 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 475 m.Return(ovf); 476 int expected_ovf = bits::SignedAddOverflow64(*i, *j, &expected_val); 477 CHECK_EQ(expected_ovf, m.Call()); 478 CHECK_EQ(expected_val, actual_val); 479 } 480 } 481 } 482 483 484 TEST(RunInt64AddWithOverflowInBranchP) { 485 int constant = 911777; 486 RawMachineLabel blocka, blockb; 487 RawMachineAssemblerTester<int32_t> m; 488 Int64BinopTester bt(&m); 489 Node* add = m.Int64AddWithOverflow(bt.param0, bt.param1); 490 Node* ovf = m.Projection(1, add); 491 m.Branch(ovf, &blocka, &blockb); 492 m.Bind(&blocka); 493 bt.AddReturn(m.Int64Constant(constant)); 494 m.Bind(&blockb); 495 Node* val = m.Projection(0, add); 496 Node* truncated = m.TruncateInt64ToInt32(val); 497 bt.AddReturn(truncated); 498 FOR_INT64_INPUTS(i) { 499 FOR_INT64_INPUTS(j) { 500 int32_t expected = constant; 501 int64_t result; 502 if (!bits::SignedAddOverflow64(*i, *j, &result)) { 503 expected = static_cast<int32_t>(result); 504 } 505 CHECK_EQ(expected, bt.call(*i, *j)); 506 } 507 } 508 } 509 510 511 TEST(RunInt64SubWithOverflowP) { 512 int64_t actual_val = -1; 513 RawMachineAssemblerTester<int32_t> m; 514 Int64BinopTester bt(&m); 515 Node* add = m.Int64SubWithOverflow(bt.param0, bt.param1); 516 Node* val = m.Projection(0, add); 517 Node* ovf = m.Projection(1, add); 518 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 519 bt.AddReturn(ovf); 520 FOR_INT64_INPUTS(i) { 521 FOR_INT64_INPUTS(j) { 522 int64_t expected_val; 523 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val); 524 CHECK_EQ(expected_ovf, bt.call(*i, *j)); 525 CHECK_EQ(expected_val, actual_val); 526 } 527 } 528 } 529 530 531 TEST(RunInt64SubWithOverflowImm) { 532 int64_t actual_val = -1, expected_val = 0; 533 FOR_INT64_INPUTS(i) { 534 { 535 RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); 536 Node* add = m.Int64SubWithOverflow(m.Int64Constant(*i), m.Parameter(0)); 537 Node* val = m.Projection(0, add); 538 Node* ovf = m.Projection(1, add); 539 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 540 m.Return(ovf); 541 FOR_INT64_INPUTS(j) { 542 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val); 543 CHECK_EQ(expected_ovf, m.Call(*j)); 544 CHECK_EQ(expected_val, actual_val); 545 } 546 } 547 { 548 RawMachineAssemblerTester<int32_t> m(MachineType::Int64()); 549 Node* add = m.Int64SubWithOverflow(m.Parameter(0), m.Int64Constant(*i)); 550 Node* val = m.Projection(0, add); 551 Node* ovf = m.Projection(1, add); 552 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 553 m.Return(ovf); 554 FOR_INT64_INPUTS(j) { 555 int expected_ovf = bits::SignedSubOverflow64(*j, *i, &expected_val); 556 CHECK_EQ(expected_ovf, m.Call(*j)); 557 CHECK_EQ(expected_val, actual_val); 558 } 559 } 560 FOR_INT64_INPUTS(j) { 561 RawMachineAssemblerTester<int32_t> m; 562 Node* add = 563 m.Int64SubWithOverflow(m.Int64Constant(*i), m.Int64Constant(*j)); 564 Node* val = m.Projection(0, add); 565 Node* ovf = m.Projection(1, add); 566 m.StoreToPointer(&actual_val, MachineRepresentation::kWord64, val); 567 m.Return(ovf); 568 int expected_ovf = bits::SignedSubOverflow64(*i, *j, &expected_val); 569 CHECK_EQ(expected_ovf, m.Call()); 570 CHECK_EQ(expected_val, actual_val); 571 } 572 } 573 } 574 575 576 TEST(RunInt64SubWithOverflowInBranchP) { 577 int constant = 911999; 578 RawMachineLabel blocka, blockb; 579 RawMachineAssemblerTester<int32_t> m; 580 Int64BinopTester bt(&m); 581 Node* sub = m.Int64SubWithOverflow(bt.param0, bt.param1); 582 Node* ovf = m.Projection(1, sub); 583 m.Branch(ovf, &blocka, &blockb); 584 m.Bind(&blocka); 585 bt.AddReturn(m.Int64Constant(constant)); 586 m.Bind(&blockb); 587 Node* val = m.Projection(0, sub); 588 Node* truncated = m.TruncateInt64ToInt32(val); 589 bt.AddReturn(truncated); 590 FOR_INT64_INPUTS(i) { 591 FOR_INT64_INPUTS(j) { 592 int32_t expected = constant; 593 int64_t result; 594 if (!bits::SignedSubOverflow64(*i, *j, &result)) { 595 expected = static_cast<int32_t>(result); 596 } 597 CHECK_EQ(expected, static_cast<int32_t>(bt.call(*i, *j))); 598 } 599 } 600 } 601 602 603 // TODO(titzer): add tests that run 64-bit integer operations. 604 #endif // V8_TARGET_ARCH_64_BIT 605 606 607 TEST(RunGoto) { 608 RawMachineAssemblerTester<int32_t> m; 609 int constant = 99999; 610 611 RawMachineLabel next; 612 m.Goto(&next); 613 m.Bind(&next); 614 m.Return(m.Int32Constant(constant)); 615 616 CHECK_EQ(constant, m.Call()); 617 } 618 619 620 TEST(RunGotoMultiple) { 621 RawMachineAssemblerTester<int32_t> m; 622 int constant = 9999977; 623 624 RawMachineLabel labels[10]; 625 for (size_t i = 0; i < arraysize(labels); i++) { 626 m.Goto(&labels[i]); 627 m.Bind(&labels[i]); 628 } 629 m.Return(m.Int32Constant(constant)); 630 631 CHECK_EQ(constant, m.Call()); 632 } 633 634 635 TEST(RunBranch) { 636 RawMachineAssemblerTester<int32_t> m; 637 int constant = 999777; 638 639 RawMachineLabel blocka, blockb; 640 m.Branch(m.Int32Constant(0), &blocka, &blockb); 641 m.Bind(&blocka); 642 m.Return(m.Int32Constant(0 - constant)); 643 m.Bind(&blockb); 644 m.Return(m.Int32Constant(constant)); 645 646 CHECK_EQ(constant, m.Call()); 647 } 648 649 650 TEST(RunDiamond2) { 651 RawMachineAssemblerTester<int32_t> m; 652 653 int constant = 995666; 654 655 RawMachineLabel blocka, blockb, end; 656 m.Branch(m.Int32Constant(0), &blocka, &blockb); 657 m.Bind(&blocka); 658 m.Goto(&end); 659 m.Bind(&blockb); 660 m.Goto(&end); 661 m.Bind(&end); 662 m.Return(m.Int32Constant(constant)); 663 664 CHECK_EQ(constant, m.Call()); 665 } 666 667 668 TEST(RunLoop) { 669 RawMachineAssemblerTester<int32_t> m; 670 int constant = 999555; 671 672 RawMachineLabel header, body, exit; 673 m.Goto(&header); 674 m.Bind(&header); 675 m.Branch(m.Int32Constant(0), &body, &exit); 676 m.Bind(&body); 677 m.Goto(&header); 678 m.Bind(&exit); 679 m.Return(m.Int32Constant(constant)); 680 681 CHECK_EQ(constant, m.Call()); 682 } 683 684 685 template <typename R> 686 static void BuildDiamondPhi(RawMachineAssemblerTester<R>* m, Node* cond_node, 687 MachineRepresentation rep, Node* true_node, 688 Node* false_node) { 689 RawMachineLabel blocka, blockb, end; 690 m->Branch(cond_node, &blocka, &blockb); 691 m->Bind(&blocka); 692 m->Goto(&end); 693 m->Bind(&blockb); 694 m->Goto(&end); 695 696 m->Bind(&end); 697 Node* phi = m->Phi(rep, true_node, false_node); 698 m->Return(phi); 699 } 700 701 702 TEST(RunDiamondPhiConst) { 703 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 704 int false_val = 0xFF666; 705 int true_val = 0x00DDD; 706 Node* true_node = m.Int32Constant(true_val); 707 Node* false_node = m.Int32Constant(false_val); 708 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, true_node, 709 false_node); 710 CHECK_EQ(false_val, m.Call(0)); 711 CHECK_EQ(true_val, m.Call(1)); 712 } 713 714 715 TEST(RunDiamondPhiNumber) { 716 RawMachineAssemblerTester<Object*> m(MachineType::Int32()); 717 double false_val = -11.1; 718 double true_val = 200.1; 719 Node* true_node = m.NumberConstant(true_val); 720 Node* false_node = m.NumberConstant(false_val); 721 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node, 722 false_node); 723 m.CheckNumber(false_val, m.Call(0)); 724 m.CheckNumber(true_val, m.Call(1)); 725 } 726 727 728 TEST(RunDiamondPhiString) { 729 RawMachineAssemblerTester<Object*> m(MachineType::Int32()); 730 const char* false_val = "false"; 731 const char* true_val = "true"; 732 Node* true_node = m.StringConstant(true_val); 733 Node* false_node = m.StringConstant(false_val); 734 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kTagged, true_node, 735 false_node); 736 m.CheckString(false_val, m.Call(0)); 737 m.CheckString(true_val, m.Call(1)); 738 } 739 740 741 TEST(RunDiamondPhiParam) { 742 RawMachineAssemblerTester<int32_t> m( 743 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 744 BuildDiamondPhi(&m, m.Parameter(0), MachineRepresentation::kWord32, 745 m.Parameter(1), m.Parameter(2)); 746 int32_t c1 = 0x260cb75a; 747 int32_t c2 = 0xcd3e9c8b; 748 int result = m.Call(0, c1, c2); 749 CHECK_EQ(c2, result); 750 result = m.Call(1, c1, c2); 751 CHECK_EQ(c1, result); 752 } 753 754 755 TEST(RunLoopPhiConst) { 756 RawMachineAssemblerTester<int32_t> m; 757 int true_val = 0x44000; 758 int false_val = 0x00888; 759 760 Node* cond_node = m.Int32Constant(0); 761 Node* true_node = m.Int32Constant(true_val); 762 Node* false_node = m.Int32Constant(false_val); 763 764 // x = false_val; while(false) { x = true_val; } return x; 765 RawMachineLabel body, header, end; 766 767 m.Goto(&header); 768 m.Bind(&header); 769 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, true_node); 770 m.Branch(cond_node, &body, &end); 771 m.Bind(&body); 772 m.Goto(&header); 773 m.Bind(&end); 774 m.Return(phi); 775 776 CHECK_EQ(false_val, m.Call()); 777 } 778 779 780 TEST(RunLoopPhiParam) { 781 RawMachineAssemblerTester<int32_t> m( 782 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 783 784 RawMachineLabel blocka, blockb, end; 785 786 m.Goto(&blocka); 787 788 m.Bind(&blocka); 789 Node* phi = 790 m.Phi(MachineRepresentation::kWord32, m.Parameter(1), m.Parameter(2)); 791 Node* cond = 792 m.Phi(MachineRepresentation::kWord32, m.Parameter(0), m.Int32Constant(0)); 793 m.Branch(cond, &blockb, &end); 794 795 m.Bind(&blockb); 796 m.Goto(&blocka); 797 798 m.Bind(&end); 799 m.Return(phi); 800 801 int32_t c1 = 0xa81903b4; 802 int32_t c2 = 0x5a1207da; 803 int result = m.Call(0, c1, c2); 804 CHECK_EQ(c1, result); 805 result = m.Call(1, c1, c2); 806 CHECK_EQ(c2, result); 807 } 808 809 810 TEST(RunLoopPhiInduction) { 811 RawMachineAssemblerTester<int32_t> m; 812 813 int false_val = 0x10777; 814 815 // x = false_val; while(false) { x++; } return x; 816 RawMachineLabel header, body, end; 817 Node* false_node = m.Int32Constant(false_val); 818 819 m.Goto(&header); 820 821 m.Bind(&header); 822 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node); 823 m.Branch(m.Int32Constant(0), &body, &end); 824 825 m.Bind(&body); 826 Node* add = m.Int32Add(phi, m.Int32Constant(1)); 827 phi->ReplaceInput(1, add); 828 m.Goto(&header); 829 830 m.Bind(&end); 831 m.Return(phi); 832 833 CHECK_EQ(false_val, m.Call()); 834 } 835 836 837 TEST(RunLoopIncrement) { 838 RawMachineAssemblerTester<int32_t> m; 839 Int32BinopTester bt(&m); 840 841 // x = 0; while(x ^ param) { x++; } return x; 842 RawMachineLabel header, body, end; 843 Node* zero = m.Int32Constant(0); 844 845 m.Goto(&header); 846 847 m.Bind(&header); 848 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero); 849 m.Branch(m.WordXor(phi, bt.param0), &body, &end); 850 851 m.Bind(&body); 852 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); 853 m.Goto(&header); 854 855 m.Bind(&end); 856 bt.AddReturn(phi); 857 858 CHECK_EQ(11, bt.call(11, 0)); 859 CHECK_EQ(110, bt.call(110, 0)); 860 CHECK_EQ(176, bt.call(176, 0)); 861 } 862 863 864 TEST(RunLoopIncrement2) { 865 RawMachineAssemblerTester<int32_t> m; 866 Int32BinopTester bt(&m); 867 868 // x = 0; while(x < param) { x++; } return x; 869 RawMachineLabel header, body, end; 870 Node* zero = m.Int32Constant(0); 871 872 m.Goto(&header); 873 874 m.Bind(&header); 875 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero); 876 m.Branch(m.Int32LessThan(phi, bt.param0), &body, &end); 877 878 m.Bind(&body); 879 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); 880 m.Goto(&header); 881 882 m.Bind(&end); 883 bt.AddReturn(phi); 884 885 CHECK_EQ(11, bt.call(11, 0)); 886 CHECK_EQ(110, bt.call(110, 0)); 887 CHECK_EQ(176, bt.call(176, 0)); 888 CHECK_EQ(0, bt.call(-200, 0)); 889 } 890 891 892 TEST(RunLoopIncrement3) { 893 RawMachineAssemblerTester<int32_t> m; 894 Int32BinopTester bt(&m); 895 896 // x = 0; while(x < param) { x++; } return x; 897 RawMachineLabel header, body, end; 898 Node* zero = m.Int32Constant(0); 899 900 m.Goto(&header); 901 902 m.Bind(&header); 903 Node* phi = m.Phi(MachineRepresentation::kWord32, zero, zero); 904 m.Branch(m.Uint32LessThan(phi, bt.param0), &body, &end); 905 906 m.Bind(&body); 907 phi->ReplaceInput(1, m.Int32Add(phi, m.Int32Constant(1))); 908 m.Goto(&header); 909 910 m.Bind(&end); 911 bt.AddReturn(phi); 912 913 CHECK_EQ(11, bt.call(11, 0)); 914 CHECK_EQ(110, bt.call(110, 0)); 915 CHECK_EQ(176, bt.call(176, 0)); 916 CHECK_EQ(200, bt.call(200, 0)); 917 } 918 919 920 TEST(RunLoopDecrement) { 921 RawMachineAssemblerTester<int32_t> m; 922 Int32BinopTester bt(&m); 923 924 // x = param; while(x) { x--; } return x; 925 RawMachineLabel header, body, end; 926 927 m.Goto(&header); 928 929 m.Bind(&header); 930 Node* phi = 931 m.Phi(MachineRepresentation::kWord32, bt.param0, m.Int32Constant(0)); 932 m.Branch(phi, &body, &end); 933 934 m.Bind(&body); 935 phi->ReplaceInput(1, m.Int32Sub(phi, m.Int32Constant(1))); 936 m.Goto(&header); 937 938 m.Bind(&end); 939 bt.AddReturn(phi); 940 941 CHECK_EQ(0, bt.call(11, 0)); 942 CHECK_EQ(0, bt.call(110, 0)); 943 CHECK_EQ(0, bt.call(197, 0)); 944 } 945 946 947 TEST(RunLoopIncrementFloat32) { 948 RawMachineAssemblerTester<int32_t> m; 949 950 // x = -3.0f; while(x < 10f) { x = x + 0.5f; } return (int) (double) x; 951 RawMachineLabel header, body, end; 952 Node* minus_3 = m.Float32Constant(-3.0f); 953 Node* ten = m.Float32Constant(10.0f); 954 955 m.Goto(&header); 956 957 m.Bind(&header); 958 Node* phi = m.Phi(MachineRepresentation::kFloat32, minus_3, ten); 959 m.Branch(m.Float32LessThan(phi, ten), &body, &end); 960 961 m.Bind(&body); 962 phi->ReplaceInput(1, m.Float32Add(phi, m.Float32Constant(0.5f))); 963 m.Goto(&header); 964 965 m.Bind(&end); 966 m.Return(m.ChangeFloat64ToInt32(m.ChangeFloat32ToFloat64(phi))); 967 968 CHECK_EQ(10, m.Call()); 969 } 970 971 972 TEST(RunLoopIncrementFloat64) { 973 RawMachineAssemblerTester<int32_t> m; 974 975 // x = -3.0; while(x < 10) { x = x + 0.5; } return (int) x; 976 RawMachineLabel header, body, end; 977 Node* minus_3 = m.Float64Constant(-3.0); 978 Node* ten = m.Float64Constant(10.0); 979 980 m.Goto(&header); 981 982 m.Bind(&header); 983 Node* phi = m.Phi(MachineRepresentation::kFloat64, minus_3, ten); 984 m.Branch(m.Float64LessThan(phi, ten), &body, &end); 985 986 m.Bind(&body); 987 phi->ReplaceInput(1, m.Float64Add(phi, m.Float64Constant(0.5))); 988 m.Goto(&header); 989 990 m.Bind(&end); 991 m.Return(m.ChangeFloat64ToInt32(phi)); 992 993 CHECK_EQ(10, m.Call()); 994 } 995 996 997 TEST(RunSwitch1) { 998 RawMachineAssemblerTester<int32_t> m; 999 1000 int constant = 11223344; 1001 1002 RawMachineLabel block0, block1, def, end; 1003 RawMachineLabel* case_labels[] = {&block0, &block1}; 1004 int32_t case_values[] = {0, 1}; 1005 m.Switch(m.Int32Constant(0), &def, case_values, case_labels, 1006 arraysize(case_labels)); 1007 m.Bind(&block0); 1008 m.Goto(&end); 1009 m.Bind(&block1); 1010 m.Goto(&end); 1011 m.Bind(&def); 1012 m.Goto(&end); 1013 m.Bind(&end); 1014 m.Return(m.Int32Constant(constant)); 1015 1016 CHECK_EQ(constant, m.Call()); 1017 } 1018 1019 1020 TEST(RunSwitch2) { 1021 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 1022 1023 RawMachineLabel blocka, blockb, blockc; 1024 RawMachineLabel* case_labels[] = {&blocka, &blockb}; 1025 int32_t case_values[] = {std::numeric_limits<int32_t>::min(), 1026 std::numeric_limits<int32_t>::max()}; 1027 m.Switch(m.Parameter(0), &blockc, case_values, case_labels, 1028 arraysize(case_labels)); 1029 m.Bind(&blocka); 1030 m.Return(m.Int32Constant(-1)); 1031 m.Bind(&blockb); 1032 m.Return(m.Int32Constant(1)); 1033 m.Bind(&blockc); 1034 m.Return(m.Int32Constant(0)); 1035 1036 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::max())); 1037 CHECK_EQ(-1, m.Call(std::numeric_limits<int32_t>::min())); 1038 for (int i = -100; i < 100; i += 25) { 1039 CHECK_EQ(0, m.Call(i)); 1040 } 1041 } 1042 1043 1044 TEST(RunSwitch3) { 1045 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 1046 1047 RawMachineLabel blocka, blockb, blockc; 1048 RawMachineLabel* case_labels[] = {&blocka, &blockb}; 1049 int32_t case_values[] = {std::numeric_limits<int32_t>::min() + 0, 1050 std::numeric_limits<int32_t>::min() + 1}; 1051 m.Switch(m.Parameter(0), &blockc, case_values, case_labels, 1052 arraysize(case_labels)); 1053 m.Bind(&blocka); 1054 m.Return(m.Int32Constant(0)); 1055 m.Bind(&blockb); 1056 m.Return(m.Int32Constant(1)); 1057 m.Bind(&blockc); 1058 m.Return(m.Int32Constant(2)); 1059 1060 CHECK_EQ(0, m.Call(std::numeric_limits<int32_t>::min() + 0)); 1061 CHECK_EQ(1, m.Call(std::numeric_limits<int32_t>::min() + 1)); 1062 for (int i = -100; i < 100; i += 25) { 1063 CHECK_EQ(2, m.Call(i)); 1064 } 1065 } 1066 1067 1068 TEST(RunSwitch4) { 1069 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 1070 1071 const size_t kNumCases = 512; 1072 const size_t kNumValues = kNumCases + 1; 1073 int32_t values[kNumValues]; 1074 m.main_isolate()->random_number_generator()->NextBytes(values, 1075 sizeof(values)); 1076 RawMachineLabel end, def; 1077 int32_t case_values[kNumCases]; 1078 RawMachineLabel* case_labels[kNumCases]; 1079 Node* results[kNumValues]; 1080 for (size_t i = 0; i < kNumCases; ++i) { 1081 case_values[i] = static_cast<int32_t>(i); 1082 case_labels[i] = 1083 new (m.main_zone()->New(sizeof(RawMachineLabel))) RawMachineLabel; 1084 } 1085 m.Switch(m.Parameter(0), &def, case_values, case_labels, 1086 arraysize(case_labels)); 1087 for (size_t i = 0; i < kNumCases; ++i) { 1088 m.Bind(case_labels[i]); 1089 results[i] = m.Int32Constant(values[i]); 1090 m.Goto(&end); 1091 } 1092 m.Bind(&def); 1093 results[kNumCases] = m.Int32Constant(values[kNumCases]); 1094 m.Goto(&end); 1095 m.Bind(&end); 1096 const int num_results = static_cast<int>(arraysize(results)); 1097 Node* phi = 1098 m.AddNode(m.common()->Phi(MachineRepresentation::kWord32, num_results), 1099 num_results, results); 1100 m.Return(phi); 1101 1102 for (size_t i = 0; i < kNumValues; ++i) { 1103 CHECK_EQ(values[i], m.Call(static_cast<int>(i))); 1104 } 1105 } 1106 1107 1108 TEST(RunLoadInt32) { 1109 RawMachineAssemblerTester<int32_t> m; 1110 1111 int32_t p1 = 0; // loads directly from this location. 1112 m.Return(m.LoadFromPointer(&p1, MachineType::Int32())); 1113 1114 FOR_INT32_INPUTS(i) { 1115 p1 = *i; 1116 CHECK_EQ(p1, m.Call()); 1117 } 1118 } 1119 1120 1121 TEST(RunLoadInt32Offset) { 1122 int32_t p1 = 0; // loads directly from this location. 1123 1124 int32_t offsets[] = {-2000000, -100, -101, 1, 3, 1125 7, 120, 2000, 2000000000, 0xff}; 1126 1127 for (size_t i = 0; i < arraysize(offsets); i++) { 1128 RawMachineAssemblerTester<int32_t> m; 1129 int32_t offset = offsets[i]; 1130 byte* pointer = reinterpret_cast<byte*>(&p1) - offset; 1131 // generate load [#base + #index] 1132 m.Return(m.LoadFromPointer(pointer, MachineType::Int32(), offset)); 1133 1134 FOR_INT32_INPUTS(j) { 1135 p1 = *j; 1136 CHECK_EQ(p1, m.Call()); 1137 } 1138 } 1139 } 1140 1141 1142 TEST(RunLoadStoreFloat32Offset) { 1143 float p1 = 0.0f; // loads directly from this location. 1144 float p2 = 0.0f; // and stores directly into this location. 1145 1146 FOR_INT32_INPUTS(i) { 1147 int32_t magic = 0x2342aabb + *i * 3; 1148 RawMachineAssemblerTester<int32_t> m; 1149 int32_t offset = *i; 1150 byte* from = reinterpret_cast<byte*>(&p1) - offset; 1151 byte* to = reinterpret_cast<byte*>(&p2) - offset; 1152 // generate load [#base + #index] 1153 Node* load = m.Load(MachineType::Float32(), m.PointerConstant(from), 1154 m.IntPtrConstant(offset)); 1155 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(to), 1156 m.IntPtrConstant(offset), load, kNoWriteBarrier); 1157 m.Return(m.Int32Constant(magic)); 1158 1159 FOR_FLOAT32_INPUTS(j) { 1160 p1 = *j; 1161 p2 = *j - 5; 1162 CHECK_EQ(magic, m.Call()); 1163 CheckDoubleEq(p1, p2); 1164 } 1165 } 1166 } 1167 1168 1169 TEST(RunLoadStoreFloat64Offset) { 1170 double p1 = 0; // loads directly from this location. 1171 double p2 = 0; // and stores directly into this location. 1172 1173 FOR_INT32_INPUTS(i) { 1174 int32_t magic = 0x2342aabb + *i * 3; 1175 RawMachineAssemblerTester<int32_t> m; 1176 int32_t offset = *i; 1177 byte* from = reinterpret_cast<byte*>(&p1) - offset; 1178 byte* to = reinterpret_cast<byte*>(&p2) - offset; 1179 // generate load [#base + #index] 1180 Node* load = m.Load(MachineType::Float64(), m.PointerConstant(from), 1181 m.IntPtrConstant(offset)); 1182 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(to), 1183 m.IntPtrConstant(offset), load, kNoWriteBarrier); 1184 m.Return(m.Int32Constant(magic)); 1185 1186 FOR_FLOAT64_INPUTS(j) { 1187 p1 = *j; 1188 p2 = *j - 5; 1189 CHECK_EQ(magic, m.Call()); 1190 CheckDoubleEq(p1, p2); 1191 } 1192 } 1193 } 1194 1195 1196 TEST(RunInt32AddP) { 1197 RawMachineAssemblerTester<int32_t> m; 1198 Int32BinopTester bt(&m); 1199 1200 bt.AddReturn(m.Int32Add(bt.param0, bt.param1)); 1201 1202 FOR_INT32_INPUTS(i) { 1203 FOR_INT32_INPUTS(j) { 1204 // Use uint32_t because signed overflow is UB in C. 1205 int expected = static_cast<int32_t>(*i + *j); 1206 CHECK_EQ(expected, bt.call(*i, *j)); 1207 } 1208 } 1209 } 1210 1211 1212 TEST(RunInt32AddAndWord32EqualP) { 1213 { 1214 RawMachineAssemblerTester<int32_t> m( 1215 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 1216 m.Return(m.Int32Add(m.Parameter(0), 1217 m.Word32Equal(m.Parameter(1), m.Parameter(2)))); 1218 FOR_INT32_INPUTS(i) { 1219 FOR_INT32_INPUTS(j) { 1220 FOR_INT32_INPUTS(k) { 1221 // Use uint32_t because signed overflow is UB in C. 1222 int32_t const expected = 1223 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k)); 1224 CHECK_EQ(expected, m.Call(*i, *j, *k)); 1225 } 1226 } 1227 } 1228 } 1229 { 1230 RawMachineAssemblerTester<int32_t> m( 1231 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 1232 m.Return(m.Int32Add(m.Word32Equal(m.Parameter(0), m.Parameter(1)), 1233 m.Parameter(2))); 1234 FOR_INT32_INPUTS(i) { 1235 FOR_INT32_INPUTS(j) { 1236 FOR_INT32_INPUTS(k) { 1237 // Use uint32_t because signed overflow is UB in C. 1238 int32_t const expected = 1239 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k)); 1240 CHECK_EQ(expected, m.Call(*i, *j, *k)); 1241 } 1242 } 1243 } 1244 } 1245 } 1246 1247 1248 TEST(RunInt32AddAndWord32EqualImm) { 1249 { 1250 FOR_INT32_INPUTS(i) { 1251 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 1252 MachineType::Int32()); 1253 m.Return(m.Int32Add(m.Int32Constant(*i), 1254 m.Word32Equal(m.Parameter(0), m.Parameter(1)))); 1255 FOR_INT32_INPUTS(j) { 1256 FOR_INT32_INPUTS(k) { 1257 // Use uint32_t because signed overflow is UB in C. 1258 int32_t const expected = 1259 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j == *k)); 1260 CHECK_EQ(expected, m.Call(*j, *k)); 1261 } 1262 } 1263 } 1264 } 1265 { 1266 FOR_INT32_INPUTS(i) { 1267 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 1268 MachineType::Int32()); 1269 m.Return(m.Int32Add(m.Word32Equal(m.Int32Constant(*i), m.Parameter(0)), 1270 m.Parameter(1))); 1271 FOR_INT32_INPUTS(j) { 1272 FOR_INT32_INPUTS(k) { 1273 // Use uint32_t because signed overflow is UB in C. 1274 int32_t const expected = 1275 bit_cast<int32_t>((*i == *j) + bit_cast<uint32_t>(*k)); 1276 CHECK_EQ(expected, m.Call(*j, *k)); 1277 } 1278 } 1279 } 1280 } 1281 } 1282 1283 1284 TEST(RunInt32AddAndWord32NotEqualP) { 1285 { 1286 RawMachineAssemblerTester<int32_t> m( 1287 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 1288 m.Return(m.Int32Add(m.Parameter(0), 1289 m.Word32NotEqual(m.Parameter(1), m.Parameter(2)))); 1290 FOR_INT32_INPUTS(i) { 1291 FOR_INT32_INPUTS(j) { 1292 FOR_INT32_INPUTS(k) { 1293 // Use uint32_t because signed overflow is UB in C. 1294 int32_t const expected = 1295 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k)); 1296 CHECK_EQ(expected, m.Call(*i, *j, *k)); 1297 } 1298 } 1299 } 1300 } 1301 { 1302 RawMachineAssemblerTester<int32_t> m( 1303 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 1304 m.Return(m.Int32Add(m.Word32NotEqual(m.Parameter(0), m.Parameter(1)), 1305 m.Parameter(2))); 1306 FOR_INT32_INPUTS(i) { 1307 FOR_INT32_INPUTS(j) { 1308 FOR_INT32_INPUTS(k) { 1309 // Use uint32_t because signed overflow is UB in C. 1310 int32_t const expected = 1311 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k)); 1312 CHECK_EQ(expected, m.Call(*i, *j, *k)); 1313 } 1314 } 1315 } 1316 } 1317 } 1318 1319 1320 TEST(RunInt32AddAndWord32NotEqualImm) { 1321 { 1322 FOR_INT32_INPUTS(i) { 1323 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 1324 MachineType::Int32()); 1325 m.Return(m.Int32Add(m.Int32Constant(*i), 1326 m.Word32NotEqual(m.Parameter(0), m.Parameter(1)))); 1327 FOR_INT32_INPUTS(j) { 1328 FOR_INT32_INPUTS(k) { 1329 // Use uint32_t because signed overflow is UB in C. 1330 int32_t const expected = 1331 bit_cast<int32_t>(bit_cast<uint32_t>(*i) + (*j != *k)); 1332 CHECK_EQ(expected, m.Call(*j, *k)); 1333 } 1334 } 1335 } 1336 } 1337 { 1338 FOR_INT32_INPUTS(i) { 1339 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 1340 MachineType::Int32()); 1341 m.Return(m.Int32Add(m.Word32NotEqual(m.Int32Constant(*i), m.Parameter(0)), 1342 m.Parameter(1))); 1343 FOR_INT32_INPUTS(j) { 1344 FOR_INT32_INPUTS(k) { 1345 // Use uint32_t because signed overflow is UB in C. 1346 int32_t const expected = 1347 bit_cast<int32_t>((*i != *j) + bit_cast<uint32_t>(*k)); 1348 CHECK_EQ(expected, m.Call(*j, *k)); 1349 } 1350 } 1351 } 1352 } 1353 } 1354 1355 1356 TEST(RunInt32AddAndWord32SarP) { 1357 { 1358 RawMachineAssemblerTester<int32_t> m( 1359 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1360 m.Return(m.Int32Add(m.Parameter(0), 1361 m.Word32Sar(m.Parameter(1), m.Parameter(2)))); 1362 FOR_UINT32_INPUTS(i) { 1363 FOR_INT32_INPUTS(j) { 1364 FOR_UINT32_SHIFTS(shift) { 1365 // Use uint32_t because signed overflow is UB in C. 1366 int32_t expected = *i + (*j >> shift); 1367 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1368 } 1369 } 1370 } 1371 } 1372 { 1373 RawMachineAssemblerTester<int32_t> m( 1374 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); 1375 m.Return(m.Int32Add(m.Word32Sar(m.Parameter(0), m.Parameter(1)), 1376 m.Parameter(2))); 1377 FOR_INT32_INPUTS(i) { 1378 FOR_UINT32_SHIFTS(shift) { 1379 FOR_UINT32_INPUTS(k) { 1380 // Use uint32_t because signed overflow is UB in C. 1381 int32_t expected = (*i >> shift) + *k; 1382 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1383 } 1384 } 1385 } 1386 } 1387 } 1388 1389 1390 TEST(RunInt32AddAndWord32ShlP) { 1391 { 1392 RawMachineAssemblerTester<int32_t> m( 1393 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1394 m.Return(m.Int32Add(m.Parameter(0), 1395 m.Word32Shl(m.Parameter(1), m.Parameter(2)))); 1396 FOR_UINT32_INPUTS(i) { 1397 FOR_INT32_INPUTS(j) { 1398 FOR_UINT32_SHIFTS(shift) { 1399 // Use uint32_t because signed overflow is UB in C. 1400 int32_t expected = *i + (*j << shift); 1401 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1402 } 1403 } 1404 } 1405 } 1406 { 1407 RawMachineAssemblerTester<int32_t> m( 1408 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); 1409 m.Return(m.Int32Add(m.Word32Shl(m.Parameter(0), m.Parameter(1)), 1410 m.Parameter(2))); 1411 FOR_INT32_INPUTS(i) { 1412 FOR_UINT32_SHIFTS(shift) { 1413 FOR_UINT32_INPUTS(k) { 1414 // Use uint32_t because signed overflow is UB in C. 1415 int32_t expected = (*i << shift) + *k; 1416 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1417 } 1418 } 1419 } 1420 } 1421 } 1422 1423 1424 TEST(RunInt32AddAndWord32ShrP) { 1425 { 1426 RawMachineAssemblerTester<int32_t> m( 1427 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 1428 m.Return(m.Int32Add(m.Parameter(0), 1429 m.Word32Shr(m.Parameter(1), m.Parameter(2)))); 1430 FOR_UINT32_INPUTS(i) { 1431 FOR_UINT32_INPUTS(j) { 1432 FOR_UINT32_SHIFTS(shift) { 1433 // Use uint32_t because signed overflow is UB in C. 1434 int32_t expected = *i + (*j >> shift); 1435 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1436 } 1437 } 1438 } 1439 } 1440 { 1441 RawMachineAssemblerTester<int32_t> m( 1442 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 1443 m.Return(m.Int32Add(m.Word32Shr(m.Parameter(0), m.Parameter(1)), 1444 m.Parameter(2))); 1445 FOR_UINT32_INPUTS(i) { 1446 FOR_UINT32_SHIFTS(shift) { 1447 FOR_UINT32_INPUTS(k) { 1448 // Use uint32_t because signed overflow is UB in C. 1449 int32_t expected = (*i >> shift) + *k; 1450 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1451 } 1452 } 1453 } 1454 } 1455 } 1456 1457 1458 TEST(RunInt32AddInBranch) { 1459 static const int32_t constant = 987654321; 1460 { 1461 RawMachineAssemblerTester<int32_t> m; 1462 Int32BinopTester bt(&m); 1463 RawMachineLabel blocka, blockb; 1464 m.Branch( 1465 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)), 1466 &blocka, &blockb); 1467 m.Bind(&blocka); 1468 bt.AddReturn(m.Int32Constant(constant)); 1469 m.Bind(&blockb); 1470 bt.AddReturn(m.Int32Constant(0 - constant)); 1471 FOR_UINT32_INPUTS(i) { 1472 FOR_UINT32_INPUTS(j) { 1473 int32_t expected = (*i + *j) == 0 ? constant : 0 - constant; 1474 CHECK_EQ(expected, bt.call(*i, *j)); 1475 } 1476 } 1477 } 1478 { 1479 RawMachineAssemblerTester<int32_t> m; 1480 Int32BinopTester bt(&m); 1481 RawMachineLabel blocka, blockb; 1482 m.Branch( 1483 m.Word32NotEqual(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0)), 1484 &blocka, &blockb); 1485 m.Bind(&blocka); 1486 bt.AddReturn(m.Int32Constant(constant)); 1487 m.Bind(&blockb); 1488 bt.AddReturn(m.Int32Constant(0 - constant)); 1489 FOR_UINT32_INPUTS(i) { 1490 FOR_UINT32_INPUTS(j) { 1491 int32_t expected = (*i + *j) != 0 ? constant : 0 - constant; 1492 CHECK_EQ(expected, bt.call(*i, *j)); 1493 } 1494 } 1495 } 1496 { 1497 FOR_UINT32_INPUTS(i) { 1498 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1499 RawMachineLabel blocka, blockb; 1500 m.Branch(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), 1501 m.Int32Constant(0)), 1502 &blocka, &blockb); 1503 m.Bind(&blocka); 1504 m.Return(m.Int32Constant(constant)); 1505 m.Bind(&blockb); 1506 m.Return(m.Int32Constant(0 - constant)); 1507 FOR_UINT32_INPUTS(j) { 1508 uint32_t expected = (*i + *j) == 0 ? constant : 0 - constant; 1509 CHECK_EQ(expected, m.Call(*j)); 1510 } 1511 } 1512 } 1513 { 1514 FOR_UINT32_INPUTS(i) { 1515 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1516 RawMachineLabel blocka, blockb; 1517 m.Branch(m.Word32NotEqual(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), 1518 m.Int32Constant(0)), 1519 &blocka, &blockb); 1520 m.Bind(&blocka); 1521 m.Return(m.Int32Constant(constant)); 1522 m.Bind(&blockb); 1523 m.Return(m.Int32Constant(0 - constant)); 1524 FOR_UINT32_INPUTS(j) { 1525 uint32_t expected = (*i + *j) != 0 ? constant : 0 - constant; 1526 CHECK_EQ(expected, m.Call(*j)); 1527 } 1528 } 1529 } 1530 { 1531 RawMachineAssemblerTester<void> m; 1532 const Operator* shops[] = {m.machine()->Word32Sar(), 1533 m.machine()->Word32Shl(), 1534 m.machine()->Word32Shr()}; 1535 for (size_t n = 0; n < arraysize(shops); n++) { 1536 RawMachineAssemblerTester<int32_t> m( 1537 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1538 RawMachineLabel blocka, blockb; 1539 m.Branch(m.Word32Equal(m.Int32Add(m.Parameter(0), 1540 m.AddNode(shops[n], m.Parameter(1), 1541 m.Parameter(2))), 1542 m.Int32Constant(0)), 1543 &blocka, &blockb); 1544 m.Bind(&blocka); 1545 m.Return(m.Int32Constant(constant)); 1546 m.Bind(&blockb); 1547 m.Return(m.Int32Constant(0 - constant)); 1548 FOR_UINT32_INPUTS(i) { 1549 FOR_INT32_INPUTS(j) { 1550 FOR_UINT32_SHIFTS(shift) { 1551 int32_t right; 1552 switch (shops[n]->opcode()) { 1553 default: 1554 UNREACHABLE(); 1555 case IrOpcode::kWord32Sar: 1556 right = *j >> shift; 1557 break; 1558 case IrOpcode::kWord32Shl: 1559 right = *j << shift; 1560 break; 1561 case IrOpcode::kWord32Shr: 1562 right = static_cast<uint32_t>(*j) >> shift; 1563 break; 1564 } 1565 int32_t expected = ((*i + right) == 0) ? constant : 0 - constant; 1566 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1567 } 1568 } 1569 } 1570 } 1571 } 1572 } 1573 1574 1575 TEST(RunInt32AddInComparison) { 1576 { 1577 RawMachineAssemblerTester<int32_t> m; 1578 Uint32BinopTester bt(&m); 1579 bt.AddReturn( 1580 m.Word32Equal(m.Int32Add(bt.param0, bt.param1), m.Int32Constant(0))); 1581 FOR_UINT32_INPUTS(i) { 1582 FOR_UINT32_INPUTS(j) { 1583 uint32_t expected = (*i + *j) == 0; 1584 CHECK_EQ(expected, bt.call(*i, *j)); 1585 } 1586 } 1587 } 1588 { 1589 RawMachineAssemblerTester<int32_t> m; 1590 Uint32BinopTester bt(&m); 1591 bt.AddReturn( 1592 m.Word32Equal(m.Int32Constant(0), m.Int32Add(bt.param0, bt.param1))); 1593 FOR_UINT32_INPUTS(i) { 1594 FOR_UINT32_INPUTS(j) { 1595 uint32_t expected = (*i + *j) == 0; 1596 CHECK_EQ(expected, bt.call(*i, *j)); 1597 } 1598 } 1599 } 1600 { 1601 FOR_UINT32_INPUTS(i) { 1602 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1603 m.Return(m.Word32Equal(m.Int32Add(m.Int32Constant(*i), m.Parameter(0)), 1604 m.Int32Constant(0))); 1605 FOR_UINT32_INPUTS(j) { 1606 uint32_t expected = (*i + *j) == 0; 1607 CHECK_EQ(expected, m.Call(*j)); 1608 } 1609 } 1610 } 1611 { 1612 FOR_UINT32_INPUTS(i) { 1613 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1614 m.Return(m.Word32Equal(m.Int32Add(m.Parameter(0), m.Int32Constant(*i)), 1615 m.Int32Constant(0))); 1616 FOR_UINT32_INPUTS(j) { 1617 uint32_t expected = (*j + *i) == 0; 1618 CHECK_EQ(expected, m.Call(*j)); 1619 } 1620 } 1621 } 1622 { 1623 RawMachineAssemblerTester<void> m; 1624 const Operator* shops[] = {m.machine()->Word32Sar(), 1625 m.machine()->Word32Shl(), 1626 m.machine()->Word32Shr()}; 1627 for (size_t n = 0; n < arraysize(shops); n++) { 1628 RawMachineAssemblerTester<int32_t> m( 1629 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1630 m.Return(m.Word32Equal( 1631 m.Int32Add(m.Parameter(0), 1632 m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), 1633 m.Int32Constant(0))); 1634 FOR_UINT32_INPUTS(i) { 1635 FOR_INT32_INPUTS(j) { 1636 FOR_UINT32_SHIFTS(shift) { 1637 int32_t right; 1638 switch (shops[n]->opcode()) { 1639 default: 1640 UNREACHABLE(); 1641 case IrOpcode::kWord32Sar: 1642 right = *j >> shift; 1643 break; 1644 case IrOpcode::kWord32Shl: 1645 right = *j << shift; 1646 break; 1647 case IrOpcode::kWord32Shr: 1648 right = static_cast<uint32_t>(*j) >> shift; 1649 break; 1650 } 1651 int32_t expected = (*i + right) == 0; 1652 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1653 } 1654 } 1655 } 1656 } 1657 } 1658 } 1659 1660 1661 TEST(RunInt32SubP) { 1662 RawMachineAssemblerTester<int32_t> m; 1663 Uint32BinopTester bt(&m); 1664 1665 m.Return(m.Int32Sub(bt.param0, bt.param1)); 1666 1667 FOR_UINT32_INPUTS(i) { 1668 FOR_UINT32_INPUTS(j) { 1669 uint32_t expected = static_cast<int32_t>(*i - *j); 1670 CHECK_EQ(expected, bt.call(*i, *j)); 1671 } 1672 } 1673 } 1674 1675 1676 TEST(RunInt32SubImm) { 1677 { 1678 FOR_UINT32_INPUTS(i) { 1679 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1680 m.Return(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0))); 1681 FOR_UINT32_INPUTS(j) { 1682 uint32_t expected = *i - *j; 1683 CHECK_EQ(expected, m.Call(*j)); 1684 } 1685 } 1686 } 1687 { 1688 FOR_UINT32_INPUTS(i) { 1689 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1690 m.Return(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i))); 1691 FOR_UINT32_INPUTS(j) { 1692 uint32_t expected = *j - *i; 1693 CHECK_EQ(expected, m.Call(*j)); 1694 } 1695 } 1696 } 1697 } 1698 1699 1700 TEST(RunInt32SubAndWord32SarP) { 1701 { 1702 RawMachineAssemblerTester<int32_t> m( 1703 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1704 m.Return(m.Int32Sub(m.Parameter(0), 1705 m.Word32Sar(m.Parameter(1), m.Parameter(2)))); 1706 FOR_UINT32_INPUTS(i) { 1707 FOR_INT32_INPUTS(j) { 1708 FOR_UINT32_SHIFTS(shift) { 1709 int32_t expected = *i - (*j >> shift); 1710 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1711 } 1712 } 1713 } 1714 } 1715 { 1716 RawMachineAssemblerTester<int32_t> m( 1717 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); 1718 m.Return(m.Int32Sub(m.Word32Sar(m.Parameter(0), m.Parameter(1)), 1719 m.Parameter(2))); 1720 FOR_INT32_INPUTS(i) { 1721 FOR_UINT32_SHIFTS(shift) { 1722 FOR_UINT32_INPUTS(k) { 1723 int32_t expected = (*i >> shift) - *k; 1724 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1725 } 1726 } 1727 } 1728 } 1729 } 1730 1731 1732 TEST(RunInt32SubAndWord32ShlP) { 1733 { 1734 RawMachineAssemblerTester<int32_t> m( 1735 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1736 m.Return(m.Int32Sub(m.Parameter(0), 1737 m.Word32Shl(m.Parameter(1), m.Parameter(2)))); 1738 FOR_UINT32_INPUTS(i) { 1739 FOR_INT32_INPUTS(j) { 1740 FOR_UINT32_SHIFTS(shift) { 1741 int32_t expected = *i - (*j << shift); 1742 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1743 } 1744 } 1745 } 1746 } 1747 { 1748 RawMachineAssemblerTester<int32_t> m( 1749 MachineType::Int32(), MachineType::Uint32(), MachineType::Uint32()); 1750 m.Return(m.Int32Sub(m.Word32Shl(m.Parameter(0), m.Parameter(1)), 1751 m.Parameter(2))); 1752 FOR_INT32_INPUTS(i) { 1753 FOR_UINT32_SHIFTS(shift) { 1754 FOR_UINT32_INPUTS(k) { 1755 // Use uint32_t because signed overflow is UB in C. 1756 int32_t expected = (*i << shift) - *k; 1757 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1758 } 1759 } 1760 } 1761 } 1762 } 1763 1764 1765 TEST(RunInt32SubAndWord32ShrP) { 1766 { 1767 RawMachineAssemblerTester<uint32_t> m( 1768 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 1769 m.Return(m.Int32Sub(m.Parameter(0), 1770 m.Word32Shr(m.Parameter(1), m.Parameter(2)))); 1771 FOR_UINT32_INPUTS(i) { 1772 FOR_UINT32_INPUTS(j) { 1773 FOR_UINT32_SHIFTS(shift) { 1774 // Use uint32_t because signed overflow is UB in C. 1775 uint32_t expected = *i - (*j >> shift); 1776 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1777 } 1778 } 1779 } 1780 } 1781 { 1782 RawMachineAssemblerTester<uint32_t> m( 1783 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 1784 m.Return(m.Int32Sub(m.Word32Shr(m.Parameter(0), m.Parameter(1)), 1785 m.Parameter(2))); 1786 FOR_UINT32_INPUTS(i) { 1787 FOR_UINT32_SHIFTS(shift) { 1788 FOR_UINT32_INPUTS(k) { 1789 // Use uint32_t because signed overflow is UB in C. 1790 uint32_t expected = (*i >> shift) - *k; 1791 CHECK_EQ(expected, m.Call(*i, shift, *k)); 1792 } 1793 } 1794 } 1795 } 1796 } 1797 1798 1799 TEST(RunInt32SubInBranch) { 1800 static const int constant = 987654321; 1801 { 1802 RawMachineAssemblerTester<int32_t> m; 1803 Int32BinopTester bt(&m); 1804 RawMachineLabel blocka, blockb; 1805 m.Branch( 1806 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)), 1807 &blocka, &blockb); 1808 m.Bind(&blocka); 1809 bt.AddReturn(m.Int32Constant(constant)); 1810 m.Bind(&blockb); 1811 bt.AddReturn(m.Int32Constant(0 - constant)); 1812 FOR_UINT32_INPUTS(i) { 1813 FOR_UINT32_INPUTS(j) { 1814 int32_t expected = (*i - *j) == 0 ? constant : 0 - constant; 1815 CHECK_EQ(expected, bt.call(*i, *j)); 1816 } 1817 } 1818 } 1819 { 1820 RawMachineAssemblerTester<int32_t> m; 1821 Int32BinopTester bt(&m); 1822 RawMachineLabel blocka, blockb; 1823 m.Branch( 1824 m.Word32NotEqual(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0)), 1825 &blocka, &blockb); 1826 m.Bind(&blocka); 1827 bt.AddReturn(m.Int32Constant(constant)); 1828 m.Bind(&blockb); 1829 bt.AddReturn(m.Int32Constant(0 - constant)); 1830 FOR_UINT32_INPUTS(i) { 1831 FOR_UINT32_INPUTS(j) { 1832 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant; 1833 CHECK_EQ(expected, bt.call(*i, *j)); 1834 } 1835 } 1836 } 1837 { 1838 FOR_UINT32_INPUTS(i) { 1839 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1840 RawMachineLabel blocka, blockb; 1841 m.Branch(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), 1842 m.Int32Constant(0)), 1843 &blocka, &blockb); 1844 m.Bind(&blocka); 1845 m.Return(m.Int32Constant(constant)); 1846 m.Bind(&blockb); 1847 m.Return(m.Int32Constant(0 - constant)); 1848 FOR_UINT32_INPUTS(j) { 1849 uint32_t expected = (*i - *j) == 0 ? constant : 0 - constant; 1850 CHECK_EQ(expected, m.Call(*j)); 1851 } 1852 } 1853 } 1854 { 1855 FOR_UINT32_INPUTS(i) { 1856 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 1857 RawMachineLabel blocka, blockb; 1858 m.Branch(m.Word32NotEqual(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), 1859 m.Int32Constant(0)), 1860 &blocka, &blockb); 1861 m.Bind(&blocka); 1862 m.Return(m.Int32Constant(constant)); 1863 m.Bind(&blockb); 1864 m.Return(m.Int32Constant(0 - constant)); 1865 FOR_UINT32_INPUTS(j) { 1866 int32_t expected = (*i - *j) != 0 ? constant : 0 - constant; 1867 CHECK_EQ(expected, m.Call(*j)); 1868 } 1869 } 1870 } 1871 { 1872 RawMachineAssemblerTester<void> m; 1873 const Operator* shops[] = {m.machine()->Word32Sar(), 1874 m.machine()->Word32Shl(), 1875 m.machine()->Word32Shr()}; 1876 for (size_t n = 0; n < arraysize(shops); n++) { 1877 RawMachineAssemblerTester<int32_t> m( 1878 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1879 RawMachineLabel blocka, blockb; 1880 m.Branch(m.Word32Equal(m.Int32Sub(m.Parameter(0), 1881 m.AddNode(shops[n], m.Parameter(1), 1882 m.Parameter(2))), 1883 m.Int32Constant(0)), 1884 &blocka, &blockb); 1885 m.Bind(&blocka); 1886 m.Return(m.Int32Constant(constant)); 1887 m.Bind(&blockb); 1888 m.Return(m.Int32Constant(0 - constant)); 1889 FOR_UINT32_INPUTS(i) { 1890 FOR_INT32_INPUTS(j) { 1891 FOR_UINT32_SHIFTS(shift) { 1892 int32_t right; 1893 switch (shops[n]->opcode()) { 1894 default: 1895 UNREACHABLE(); 1896 case IrOpcode::kWord32Sar: 1897 right = *j >> shift; 1898 break; 1899 case IrOpcode::kWord32Shl: 1900 right = *j << shift; 1901 break; 1902 case IrOpcode::kWord32Shr: 1903 right = static_cast<uint32_t>(*j) >> shift; 1904 break; 1905 } 1906 int32_t expected = ((*i - right) == 0) ? constant : 0 - constant; 1907 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1908 } 1909 } 1910 } 1911 } 1912 } 1913 } 1914 1915 1916 TEST(RunInt32SubInComparison) { 1917 { 1918 RawMachineAssemblerTester<int32_t> m; 1919 Uint32BinopTester bt(&m); 1920 bt.AddReturn( 1921 m.Word32Equal(m.Int32Sub(bt.param0, bt.param1), m.Int32Constant(0))); 1922 FOR_UINT32_INPUTS(i) { 1923 FOR_UINT32_INPUTS(j) { 1924 uint32_t expected = (*i - *j) == 0; 1925 CHECK_EQ(expected, bt.call(*i, *j)); 1926 } 1927 } 1928 } 1929 { 1930 RawMachineAssemblerTester<int32_t> m; 1931 Uint32BinopTester bt(&m); 1932 bt.AddReturn( 1933 m.Word32Equal(m.Int32Constant(0), m.Int32Sub(bt.param0, bt.param1))); 1934 FOR_UINT32_INPUTS(i) { 1935 FOR_UINT32_INPUTS(j) { 1936 uint32_t expected = (*i - *j) == 0; 1937 CHECK_EQ(expected, bt.call(*i, *j)); 1938 } 1939 } 1940 } 1941 { 1942 FOR_UINT32_INPUTS(i) { 1943 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1944 m.Return(m.Word32Equal(m.Int32Sub(m.Int32Constant(*i), m.Parameter(0)), 1945 m.Int32Constant(0))); 1946 FOR_UINT32_INPUTS(j) { 1947 uint32_t expected = (*i - *j) == 0; 1948 CHECK_EQ(expected, m.Call(*j)); 1949 } 1950 } 1951 } 1952 { 1953 FOR_UINT32_INPUTS(i) { 1954 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 1955 m.Return(m.Word32Equal(m.Int32Sub(m.Parameter(0), m.Int32Constant(*i)), 1956 m.Int32Constant(0))); 1957 FOR_UINT32_INPUTS(j) { 1958 uint32_t expected = (*j - *i) == 0; 1959 CHECK_EQ(expected, m.Call(*j)); 1960 } 1961 } 1962 } 1963 { 1964 RawMachineAssemblerTester<void> m; 1965 const Operator* shops[] = {m.machine()->Word32Sar(), 1966 m.machine()->Word32Shl(), 1967 m.machine()->Word32Shr()}; 1968 for (size_t n = 0; n < arraysize(shops); n++) { 1969 RawMachineAssemblerTester<int32_t> m( 1970 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 1971 m.Return(m.Word32Equal( 1972 m.Int32Sub(m.Parameter(0), 1973 m.AddNode(shops[n], m.Parameter(1), m.Parameter(2))), 1974 m.Int32Constant(0))); 1975 FOR_UINT32_INPUTS(i) { 1976 FOR_INT32_INPUTS(j) { 1977 FOR_UINT32_SHIFTS(shift) { 1978 int32_t right; 1979 switch (shops[n]->opcode()) { 1980 default: 1981 UNREACHABLE(); 1982 case IrOpcode::kWord32Sar: 1983 right = *j >> shift; 1984 break; 1985 case IrOpcode::kWord32Shl: 1986 right = *j << shift; 1987 break; 1988 case IrOpcode::kWord32Shr: 1989 right = static_cast<uint32_t>(*j) >> shift; 1990 break; 1991 } 1992 int32_t expected = (*i - right) == 0; 1993 CHECK_EQ(expected, m.Call(*i, *j, shift)); 1994 } 1995 } 1996 } 1997 } 1998 } 1999 } 2000 2001 2002 TEST(RunInt32MulP) { 2003 { 2004 RawMachineAssemblerTester<int32_t> m; 2005 Int32BinopTester bt(&m); 2006 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1)); 2007 FOR_INT32_INPUTS(i) { 2008 FOR_INT32_INPUTS(j) { 2009 int expected = static_cast<int32_t>(*i * *j); 2010 CHECK_EQ(expected, bt.call(*i, *j)); 2011 } 2012 } 2013 } 2014 { 2015 RawMachineAssemblerTester<int32_t> m; 2016 Uint32BinopTester bt(&m); 2017 bt.AddReturn(m.Int32Mul(bt.param0, bt.param1)); 2018 FOR_UINT32_INPUTS(i) { 2019 FOR_UINT32_INPUTS(j) { 2020 uint32_t expected = *i * *j; 2021 CHECK_EQ(expected, bt.call(*i, *j)); 2022 } 2023 } 2024 } 2025 } 2026 2027 2028 TEST(RunInt32MulHighP) { 2029 RawMachineAssemblerTester<int32_t> m; 2030 Int32BinopTester bt(&m); 2031 bt.AddReturn(m.Int32MulHigh(bt.param0, bt.param1)); 2032 FOR_INT32_INPUTS(i) { 2033 FOR_INT32_INPUTS(j) { 2034 int32_t expected = static_cast<int32_t>( 2035 (static_cast<int64_t>(*i) * static_cast<int64_t>(*j)) >> 32); 2036 CHECK_EQ(expected, bt.call(*i, *j)); 2037 } 2038 } 2039 } 2040 2041 2042 TEST(RunInt32MulImm) { 2043 { 2044 FOR_UINT32_INPUTS(i) { 2045 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2046 m.Return(m.Int32Mul(m.Int32Constant(*i), m.Parameter(0))); 2047 FOR_UINT32_INPUTS(j) { 2048 uint32_t expected = *i * *j; 2049 CHECK_EQ(expected, m.Call(*j)); 2050 } 2051 } 2052 } 2053 { 2054 FOR_UINT32_INPUTS(i) { 2055 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2056 m.Return(m.Int32Mul(m.Parameter(0), m.Int32Constant(*i))); 2057 FOR_UINT32_INPUTS(j) { 2058 uint32_t expected = *j * *i; 2059 CHECK_EQ(expected, m.Call(*j)); 2060 } 2061 } 2062 } 2063 } 2064 2065 2066 TEST(RunInt32MulAndInt32AddP) { 2067 { 2068 FOR_INT32_INPUTS(i) { 2069 FOR_INT32_INPUTS(j) { 2070 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 2071 int32_t p0 = *i; 2072 int32_t p1 = *j; 2073 m.Return(m.Int32Add(m.Int32Constant(p0), 2074 m.Int32Mul(m.Parameter(0), m.Int32Constant(p1)))); 2075 FOR_INT32_INPUTS(k) { 2076 int32_t p2 = *k; 2077 int expected = p0 + static_cast<int32_t>(p1 * p2); 2078 CHECK_EQ(expected, m.Call(p2)); 2079 } 2080 } 2081 } 2082 } 2083 { 2084 RawMachineAssemblerTester<int32_t> m( 2085 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 2086 m.Return( 2087 m.Int32Add(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); 2088 FOR_INT32_INPUTS(i) { 2089 FOR_INT32_INPUTS(j) { 2090 FOR_INT32_INPUTS(k) { 2091 int32_t p0 = *i; 2092 int32_t p1 = *j; 2093 int32_t p2 = *k; 2094 int expected = p0 + static_cast<int32_t>(p1 * p2); 2095 CHECK_EQ(expected, m.Call(p0, p1, p2)); 2096 } 2097 } 2098 } 2099 } 2100 { 2101 RawMachineAssemblerTester<int32_t> m( 2102 MachineType::Int32(), MachineType::Int32(), MachineType::Int32()); 2103 m.Return( 2104 m.Int32Add(m.Int32Mul(m.Parameter(0), m.Parameter(1)), m.Parameter(2))); 2105 FOR_INT32_INPUTS(i) { 2106 FOR_INT32_INPUTS(j) { 2107 FOR_INT32_INPUTS(k) { 2108 int32_t p0 = *i; 2109 int32_t p1 = *j; 2110 int32_t p2 = *k; 2111 int expected = static_cast<int32_t>(p0 * p1) + p2; 2112 CHECK_EQ(expected, m.Call(p0, p1, p2)); 2113 } 2114 } 2115 } 2116 } 2117 { 2118 FOR_INT32_INPUTS(i) { 2119 RawMachineAssemblerTester<int32_t> m; 2120 Int32BinopTester bt(&m); 2121 bt.AddReturn( 2122 m.Int32Add(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1))); 2123 FOR_INT32_INPUTS(j) { 2124 FOR_INT32_INPUTS(k) { 2125 int32_t p0 = *j; 2126 int32_t p1 = *k; 2127 int expected = *i + static_cast<int32_t>(p0 * p1); 2128 CHECK_EQ(expected, bt.call(p0, p1)); 2129 } 2130 } 2131 } 2132 } 2133 } 2134 2135 2136 TEST(RunInt32MulAndInt32SubP) { 2137 { 2138 RawMachineAssemblerTester<int32_t> m( 2139 MachineType::Uint32(), MachineType::Int32(), MachineType::Int32()); 2140 m.Return( 2141 m.Int32Sub(m.Parameter(0), m.Int32Mul(m.Parameter(1), m.Parameter(2)))); 2142 FOR_UINT32_INPUTS(i) { 2143 FOR_INT32_INPUTS(j) { 2144 FOR_INT32_INPUTS(k) { 2145 uint32_t p0 = *i; 2146 int32_t p1 = *j; 2147 int32_t p2 = *k; 2148 // Use uint32_t because signed overflow is UB in C. 2149 int expected = p0 - static_cast<uint32_t>(p1 * p2); 2150 CHECK_EQ(expected, m.Call(p0, p1, p2)); 2151 } 2152 } 2153 } 2154 } 2155 { 2156 FOR_UINT32_INPUTS(i) { 2157 RawMachineAssemblerTester<int32_t> m; 2158 Int32BinopTester bt(&m); 2159 bt.AddReturn( 2160 m.Int32Sub(m.Int32Constant(*i), m.Int32Mul(bt.param0, bt.param1))); 2161 FOR_INT32_INPUTS(j) { 2162 FOR_INT32_INPUTS(k) { 2163 int32_t p0 = *j; 2164 int32_t p1 = *k; 2165 // Use uint32_t because signed overflow is UB in C. 2166 int expected = *i - static_cast<uint32_t>(p0 * p1); 2167 CHECK_EQ(expected, bt.call(p0, p1)); 2168 } 2169 } 2170 } 2171 } 2172 } 2173 2174 2175 TEST(RunUint32MulHighP) { 2176 RawMachineAssemblerTester<int32_t> m; 2177 Int32BinopTester bt(&m); 2178 bt.AddReturn(m.Uint32MulHigh(bt.param0, bt.param1)); 2179 FOR_UINT32_INPUTS(i) { 2180 FOR_UINT32_INPUTS(j) { 2181 int32_t expected = bit_cast<int32_t>(static_cast<uint32_t>( 2182 (static_cast<uint64_t>(*i) * static_cast<uint64_t>(*j)) >> 32)); 2183 CHECK_EQ(expected, bt.call(bit_cast<int32_t>(*i), bit_cast<int32_t>(*j))); 2184 } 2185 } 2186 } 2187 2188 2189 TEST(RunInt32DivP) { 2190 { 2191 RawMachineAssemblerTester<int32_t> m; 2192 Int32BinopTester bt(&m); 2193 bt.AddReturn(m.Int32Div(bt.param0, bt.param1)); 2194 FOR_INT32_INPUTS(i) { 2195 FOR_INT32_INPUTS(j) { 2196 int p0 = *i; 2197 int p1 = *j; 2198 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 2199 int expected = static_cast<int32_t>(p0 / p1); 2200 CHECK_EQ(expected, bt.call(p0, p1)); 2201 } 2202 } 2203 } 2204 } 2205 { 2206 RawMachineAssemblerTester<int32_t> m; 2207 Int32BinopTester bt(&m); 2208 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Div(bt.param0, bt.param1))); 2209 FOR_INT32_INPUTS(i) { 2210 FOR_INT32_INPUTS(j) { 2211 int p0 = *i; 2212 int p1 = *j; 2213 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 2214 int expected = static_cast<int32_t>(p0 + (p0 / p1)); 2215 CHECK_EQ(expected, bt.call(p0, p1)); 2216 } 2217 } 2218 } 2219 } 2220 } 2221 2222 2223 TEST(RunUint32DivP) { 2224 { 2225 RawMachineAssemblerTester<int32_t> m; 2226 Int32BinopTester bt(&m); 2227 bt.AddReturn(m.Uint32Div(bt.param0, bt.param1)); 2228 FOR_UINT32_INPUTS(i) { 2229 FOR_UINT32_INPUTS(j) { 2230 uint32_t p0 = *i; 2231 uint32_t p1 = *j; 2232 if (p1 != 0) { 2233 int32_t expected = bit_cast<int32_t>(p0 / p1); 2234 CHECK_EQ(expected, bt.call(p0, p1)); 2235 } 2236 } 2237 } 2238 } 2239 { 2240 RawMachineAssemblerTester<int32_t> m; 2241 Int32BinopTester bt(&m); 2242 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Div(bt.param0, bt.param1))); 2243 FOR_UINT32_INPUTS(i) { 2244 FOR_UINT32_INPUTS(j) { 2245 uint32_t p0 = *i; 2246 uint32_t p1 = *j; 2247 if (p1 != 0) { 2248 int32_t expected = bit_cast<int32_t>(p0 + (p0 / p1)); 2249 CHECK_EQ(expected, bt.call(p0, p1)); 2250 } 2251 } 2252 } 2253 } 2254 } 2255 2256 2257 TEST(RunInt32ModP) { 2258 { 2259 RawMachineAssemblerTester<int32_t> m; 2260 Int32BinopTester bt(&m); 2261 bt.AddReturn(m.Int32Mod(bt.param0, bt.param1)); 2262 FOR_INT32_INPUTS(i) { 2263 FOR_INT32_INPUTS(j) { 2264 int p0 = *i; 2265 int p1 = *j; 2266 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 2267 int expected = static_cast<int32_t>(p0 % p1); 2268 CHECK_EQ(expected, bt.call(p0, p1)); 2269 } 2270 } 2271 } 2272 } 2273 { 2274 RawMachineAssemblerTester<int32_t> m; 2275 Int32BinopTester bt(&m); 2276 bt.AddReturn(m.Int32Add(bt.param0, m.Int32Mod(bt.param0, bt.param1))); 2277 FOR_INT32_INPUTS(i) { 2278 FOR_INT32_INPUTS(j) { 2279 int p0 = *i; 2280 int p1 = *j; 2281 if (p1 != 0 && (static_cast<uint32_t>(p0) != 0x80000000 || p1 != -1)) { 2282 int expected = static_cast<int32_t>(p0 + (p0 % p1)); 2283 CHECK_EQ(expected, bt.call(p0, p1)); 2284 } 2285 } 2286 } 2287 } 2288 } 2289 2290 2291 TEST(RunUint32ModP) { 2292 { 2293 RawMachineAssemblerTester<int32_t> m; 2294 Uint32BinopTester bt(&m); 2295 bt.AddReturn(m.Uint32Mod(bt.param0, bt.param1)); 2296 FOR_UINT32_INPUTS(i) { 2297 FOR_UINT32_INPUTS(j) { 2298 uint32_t p0 = *i; 2299 uint32_t p1 = *j; 2300 if (p1 != 0) { 2301 uint32_t expected = static_cast<uint32_t>(p0 % p1); 2302 CHECK_EQ(expected, bt.call(p0, p1)); 2303 } 2304 } 2305 } 2306 } 2307 { 2308 RawMachineAssemblerTester<int32_t> m; 2309 Uint32BinopTester bt(&m); 2310 bt.AddReturn(m.Int32Add(bt.param0, m.Uint32Mod(bt.param0, bt.param1))); 2311 FOR_UINT32_INPUTS(i) { 2312 FOR_UINT32_INPUTS(j) { 2313 uint32_t p0 = *i; 2314 uint32_t p1 = *j; 2315 if (p1 != 0) { 2316 uint32_t expected = static_cast<uint32_t>(p0 + (p0 % p1)); 2317 CHECK_EQ(expected, bt.call(p0, p1)); 2318 } 2319 } 2320 } 2321 } 2322 } 2323 2324 2325 TEST(RunWord32AndP) { 2326 { 2327 RawMachineAssemblerTester<int32_t> m; 2328 Int32BinopTester bt(&m); 2329 bt.AddReturn(m.Word32And(bt.param0, bt.param1)); 2330 FOR_UINT32_INPUTS(i) { 2331 FOR_UINT32_INPUTS(j) { 2332 int32_t expected = *i & *j; 2333 CHECK_EQ(expected, bt.call(*i, *j)); 2334 } 2335 } 2336 } 2337 { 2338 RawMachineAssemblerTester<int32_t> m; 2339 Int32BinopTester bt(&m); 2340 bt.AddReturn(m.Word32And(bt.param0, m.Word32Not(bt.param1))); 2341 FOR_UINT32_INPUTS(i) { 2342 FOR_UINT32_INPUTS(j) { 2343 int32_t expected = *i & ~(*j); 2344 CHECK_EQ(expected, bt.call(*i, *j)); 2345 } 2346 } 2347 } 2348 { 2349 RawMachineAssemblerTester<int32_t> m; 2350 Int32BinopTester bt(&m); 2351 bt.AddReturn(m.Word32And(m.Word32Not(bt.param0), bt.param1)); 2352 FOR_UINT32_INPUTS(i) { 2353 FOR_UINT32_INPUTS(j) { 2354 int32_t expected = ~(*i) & *j; 2355 CHECK_EQ(expected, bt.call(*i, *j)); 2356 } 2357 } 2358 } 2359 } 2360 2361 2362 TEST(RunWord32AndAndWord32ShlP) { 2363 { 2364 RawMachineAssemblerTester<int32_t> m; 2365 Uint32BinopTester bt(&m); 2366 bt.AddReturn( 2367 m.Word32Shl(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f)))); 2368 FOR_UINT32_INPUTS(i) { 2369 FOR_UINT32_INPUTS(j) { 2370 uint32_t expected = *i << (*j & 0x1f); 2371 CHECK_EQ(expected, bt.call(*i, *j)); 2372 } 2373 } 2374 } 2375 { 2376 RawMachineAssemblerTester<int32_t> m; 2377 Uint32BinopTester bt(&m); 2378 bt.AddReturn( 2379 m.Word32Shl(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1))); 2380 FOR_UINT32_INPUTS(i) { 2381 FOR_UINT32_INPUTS(j) { 2382 uint32_t expected = *i << (0x1f & *j); 2383 CHECK_EQ(expected, bt.call(*i, *j)); 2384 } 2385 } 2386 } 2387 } 2388 2389 2390 TEST(RunWord32AndAndWord32ShrP) { 2391 { 2392 RawMachineAssemblerTester<int32_t> m; 2393 Uint32BinopTester bt(&m); 2394 bt.AddReturn( 2395 m.Word32Shr(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f)))); 2396 FOR_UINT32_INPUTS(i) { 2397 FOR_UINT32_INPUTS(j) { 2398 uint32_t expected = *i >> (*j & 0x1f); 2399 CHECK_EQ(expected, bt.call(*i, *j)); 2400 } 2401 } 2402 } 2403 { 2404 RawMachineAssemblerTester<int32_t> m; 2405 Uint32BinopTester bt(&m); 2406 bt.AddReturn( 2407 m.Word32Shr(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1))); 2408 FOR_UINT32_INPUTS(i) { 2409 FOR_UINT32_INPUTS(j) { 2410 uint32_t expected = *i >> (0x1f & *j); 2411 CHECK_EQ(expected, bt.call(*i, *j)); 2412 } 2413 } 2414 } 2415 } 2416 2417 2418 TEST(RunWord32AndAndWord32SarP) { 2419 { 2420 RawMachineAssemblerTester<int32_t> m; 2421 Int32BinopTester bt(&m); 2422 bt.AddReturn( 2423 m.Word32Sar(bt.param0, m.Word32And(bt.param1, m.Int32Constant(0x1f)))); 2424 FOR_INT32_INPUTS(i) { 2425 FOR_INT32_INPUTS(j) { 2426 int32_t expected = *i >> (*j & 0x1f); 2427 CHECK_EQ(expected, bt.call(*i, *j)); 2428 } 2429 } 2430 } 2431 { 2432 RawMachineAssemblerTester<int32_t> m; 2433 Int32BinopTester bt(&m); 2434 bt.AddReturn( 2435 m.Word32Sar(bt.param0, m.Word32And(m.Int32Constant(0x1f), bt.param1))); 2436 FOR_INT32_INPUTS(i) { 2437 FOR_INT32_INPUTS(j) { 2438 int32_t expected = *i >> (0x1f & *j); 2439 CHECK_EQ(expected, bt.call(*i, *j)); 2440 } 2441 } 2442 } 2443 } 2444 2445 2446 TEST(RunWord32AndImm) { 2447 { 2448 FOR_UINT32_INPUTS(i) { 2449 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2450 m.Return(m.Word32And(m.Int32Constant(*i), m.Parameter(0))); 2451 FOR_UINT32_INPUTS(j) { 2452 uint32_t expected = *i & *j; 2453 CHECK_EQ(expected, m.Call(*j)); 2454 } 2455 } 2456 } 2457 { 2458 FOR_UINT32_INPUTS(i) { 2459 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2460 m.Return(m.Word32And(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); 2461 FOR_UINT32_INPUTS(j) { 2462 uint32_t expected = *i & ~(*j); 2463 CHECK_EQ(expected, m.Call(*j)); 2464 } 2465 } 2466 } 2467 } 2468 2469 2470 TEST(RunWord32AndInBranch) { 2471 static const int constant = 987654321; 2472 { 2473 RawMachineAssemblerTester<int32_t> m; 2474 Int32BinopTester bt(&m); 2475 RawMachineLabel blocka, blockb; 2476 m.Branch( 2477 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)), 2478 &blocka, &blockb); 2479 m.Bind(&blocka); 2480 bt.AddReturn(m.Int32Constant(constant)); 2481 m.Bind(&blockb); 2482 bt.AddReturn(m.Int32Constant(0 - constant)); 2483 FOR_UINT32_INPUTS(i) { 2484 FOR_UINT32_INPUTS(j) { 2485 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant; 2486 CHECK_EQ(expected, bt.call(*i, *j)); 2487 } 2488 } 2489 } 2490 { 2491 RawMachineAssemblerTester<int32_t> m; 2492 Int32BinopTester bt(&m); 2493 RawMachineLabel blocka, blockb; 2494 m.Branch( 2495 m.Word32NotEqual(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0)), 2496 &blocka, &blockb); 2497 m.Bind(&blocka); 2498 bt.AddReturn(m.Int32Constant(constant)); 2499 m.Bind(&blockb); 2500 bt.AddReturn(m.Int32Constant(0 - constant)); 2501 FOR_UINT32_INPUTS(i) { 2502 FOR_UINT32_INPUTS(j) { 2503 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant; 2504 CHECK_EQ(expected, bt.call(*i, *j)); 2505 } 2506 } 2507 } 2508 { 2509 FOR_UINT32_INPUTS(i) { 2510 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 2511 RawMachineLabel blocka, blockb; 2512 m.Branch(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), 2513 m.Int32Constant(0)), 2514 &blocka, &blockb); 2515 m.Bind(&blocka); 2516 m.Return(m.Int32Constant(constant)); 2517 m.Bind(&blockb); 2518 m.Return(m.Int32Constant(0 - constant)); 2519 FOR_UINT32_INPUTS(j) { 2520 int32_t expected = (*i & *j) == 0 ? constant : 0 - constant; 2521 CHECK_EQ(expected, m.Call(*j)); 2522 } 2523 } 2524 } 2525 { 2526 FOR_UINT32_INPUTS(i) { 2527 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 2528 RawMachineLabel blocka, blockb; 2529 m.Branch( 2530 m.Word32NotEqual(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), 2531 m.Int32Constant(0)), 2532 &blocka, &blockb); 2533 m.Bind(&blocka); 2534 m.Return(m.Int32Constant(constant)); 2535 m.Bind(&blockb); 2536 m.Return(m.Int32Constant(0 - constant)); 2537 FOR_UINT32_INPUTS(j) { 2538 int32_t expected = (*i & *j) != 0 ? constant : 0 - constant; 2539 CHECK_EQ(expected, m.Call(*j)); 2540 } 2541 } 2542 } 2543 { 2544 RawMachineAssemblerTester<void> m; 2545 const Operator* shops[] = {m.machine()->Word32Sar(), 2546 m.machine()->Word32Shl(), 2547 m.machine()->Word32Shr()}; 2548 for (size_t n = 0; n < arraysize(shops); n++) { 2549 RawMachineAssemblerTester<int32_t> m( 2550 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 2551 RawMachineLabel blocka, blockb; 2552 m.Branch(m.Word32Equal(m.Word32And(m.Parameter(0), 2553 m.AddNode(shops[n], m.Parameter(1), 2554 m.Parameter(2))), 2555 m.Int32Constant(0)), 2556 &blocka, &blockb); 2557 m.Bind(&blocka); 2558 m.Return(m.Int32Constant(constant)); 2559 m.Bind(&blockb); 2560 m.Return(m.Int32Constant(0 - constant)); 2561 FOR_UINT32_INPUTS(i) { 2562 FOR_INT32_INPUTS(j) { 2563 FOR_UINT32_SHIFTS(shift) { 2564 int32_t right; 2565 switch (shops[n]->opcode()) { 2566 default: 2567 UNREACHABLE(); 2568 case IrOpcode::kWord32Sar: 2569 right = *j >> shift; 2570 break; 2571 case IrOpcode::kWord32Shl: 2572 right = *j << shift; 2573 break; 2574 case IrOpcode::kWord32Shr: 2575 right = static_cast<uint32_t>(*j) >> shift; 2576 break; 2577 } 2578 int32_t expected = ((*i & right) == 0) ? constant : 0 - constant; 2579 CHECK_EQ(expected, m.Call(*i, *j, shift)); 2580 } 2581 } 2582 } 2583 } 2584 } 2585 } 2586 2587 2588 TEST(RunWord32AndInComparison) { 2589 { 2590 RawMachineAssemblerTester<int32_t> m; 2591 Uint32BinopTester bt(&m); 2592 bt.AddReturn( 2593 m.Word32Equal(m.Word32And(bt.param0, bt.param1), m.Int32Constant(0))); 2594 FOR_UINT32_INPUTS(i) { 2595 FOR_UINT32_INPUTS(j) { 2596 uint32_t expected = (*i & *j) == 0; 2597 CHECK_EQ(expected, bt.call(*i, *j)); 2598 } 2599 } 2600 } 2601 { 2602 RawMachineAssemblerTester<int32_t> m; 2603 Uint32BinopTester bt(&m); 2604 bt.AddReturn( 2605 m.Word32Equal(m.Int32Constant(0), m.Word32And(bt.param0, bt.param1))); 2606 FOR_UINT32_INPUTS(i) { 2607 FOR_UINT32_INPUTS(j) { 2608 uint32_t expected = (*i & *j) == 0; 2609 CHECK_EQ(expected, bt.call(*i, *j)); 2610 } 2611 } 2612 } 2613 { 2614 FOR_UINT32_INPUTS(i) { 2615 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2616 m.Return(m.Word32Equal(m.Word32And(m.Int32Constant(*i), m.Parameter(0)), 2617 m.Int32Constant(0))); 2618 FOR_UINT32_INPUTS(j) { 2619 uint32_t expected = (*i & *j) == 0; 2620 CHECK_EQ(expected, m.Call(*j)); 2621 } 2622 } 2623 } 2624 { 2625 FOR_UINT32_INPUTS(i) { 2626 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2627 m.Return(m.Word32Equal(m.Word32And(m.Parameter(0), m.Int32Constant(*i)), 2628 m.Int32Constant(0))); 2629 FOR_UINT32_INPUTS(j) { 2630 uint32_t expected = (*j & *i) == 0; 2631 CHECK_EQ(expected, m.Call(*j)); 2632 } 2633 } 2634 } 2635 } 2636 2637 2638 TEST(RunWord32OrP) { 2639 { 2640 RawMachineAssemblerTester<int32_t> m; 2641 Uint32BinopTester bt(&m); 2642 bt.AddReturn(m.Word32Or(bt.param0, bt.param1)); 2643 FOR_UINT32_INPUTS(i) { 2644 FOR_UINT32_INPUTS(j) { 2645 uint32_t expected = *i | *j; 2646 CHECK_EQ(expected, bt.call(*i, *j)); 2647 } 2648 } 2649 } 2650 { 2651 RawMachineAssemblerTester<int32_t> m; 2652 Uint32BinopTester bt(&m); 2653 bt.AddReturn(m.Word32Or(bt.param0, m.Word32Not(bt.param1))); 2654 FOR_UINT32_INPUTS(i) { 2655 FOR_UINT32_INPUTS(j) { 2656 uint32_t expected = *i | ~(*j); 2657 CHECK_EQ(expected, bt.call(*i, *j)); 2658 } 2659 } 2660 } 2661 { 2662 RawMachineAssemblerTester<int32_t> m; 2663 Uint32BinopTester bt(&m); 2664 bt.AddReturn(m.Word32Or(m.Word32Not(bt.param0), bt.param1)); 2665 FOR_UINT32_INPUTS(i) { 2666 FOR_UINT32_INPUTS(j) { 2667 uint32_t expected = ~(*i) | *j; 2668 CHECK_EQ(expected, bt.call(*i, *j)); 2669 } 2670 } 2671 } 2672 } 2673 2674 2675 TEST(RunWord32OrImm) { 2676 { 2677 FOR_UINT32_INPUTS(i) { 2678 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2679 m.Return(m.Word32Or(m.Int32Constant(*i), m.Parameter(0))); 2680 FOR_UINT32_INPUTS(j) { 2681 uint32_t expected = *i | *j; 2682 CHECK_EQ(expected, m.Call(*j)); 2683 } 2684 } 2685 } 2686 { 2687 FOR_UINT32_INPUTS(i) { 2688 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2689 m.Return(m.Word32Or(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); 2690 FOR_UINT32_INPUTS(j) { 2691 uint32_t expected = *i | ~(*j); 2692 CHECK_EQ(expected, m.Call(*j)); 2693 } 2694 } 2695 } 2696 } 2697 2698 2699 TEST(RunWord32OrInBranch) { 2700 static const int constant = 987654321; 2701 { 2702 RawMachineAssemblerTester<int32_t> m; 2703 Int32BinopTester bt(&m); 2704 RawMachineLabel blocka, blockb; 2705 m.Branch( 2706 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)), 2707 &blocka, &blockb); 2708 m.Bind(&blocka); 2709 bt.AddReturn(m.Int32Constant(constant)); 2710 m.Bind(&blockb); 2711 bt.AddReturn(m.Int32Constant(0 - constant)); 2712 FOR_INT32_INPUTS(i) { 2713 FOR_INT32_INPUTS(j) { 2714 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant; 2715 CHECK_EQ(expected, bt.call(*i, *j)); 2716 } 2717 } 2718 } 2719 { 2720 RawMachineAssemblerTester<int32_t> m; 2721 Int32BinopTester bt(&m); 2722 RawMachineLabel blocka, blockb; 2723 m.Branch( 2724 m.Word32NotEqual(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0)), 2725 &blocka, &blockb); 2726 m.Bind(&blocka); 2727 bt.AddReturn(m.Int32Constant(constant)); 2728 m.Bind(&blockb); 2729 bt.AddReturn(m.Int32Constant(0 - constant)); 2730 FOR_INT32_INPUTS(i) { 2731 FOR_INT32_INPUTS(j) { 2732 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant; 2733 CHECK_EQ(expected, bt.call(*i, *j)); 2734 } 2735 } 2736 } 2737 { 2738 FOR_INT32_INPUTS(i) { 2739 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 2740 RawMachineLabel blocka, blockb; 2741 m.Branch(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), 2742 m.Int32Constant(0)), 2743 &blocka, &blockb); 2744 m.Bind(&blocka); 2745 m.Return(m.Int32Constant(constant)); 2746 m.Bind(&blockb); 2747 m.Return(m.Int32Constant(0 - constant)); 2748 FOR_INT32_INPUTS(j) { 2749 int32_t expected = (*i | *j) == 0 ? constant : 0 - constant; 2750 CHECK_EQ(expected, m.Call(*j)); 2751 } 2752 } 2753 } 2754 { 2755 FOR_INT32_INPUTS(i) { 2756 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 2757 RawMachineLabel blocka, blockb; 2758 m.Branch(m.Word32NotEqual(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), 2759 m.Int32Constant(0)), 2760 &blocka, &blockb); 2761 m.Bind(&blocka); 2762 m.Return(m.Int32Constant(constant)); 2763 m.Bind(&blockb); 2764 m.Return(m.Int32Constant(0 - constant)); 2765 FOR_INT32_INPUTS(j) { 2766 int32_t expected = (*i | *j) != 0 ? constant : 0 - constant; 2767 CHECK_EQ(expected, m.Call(*j)); 2768 } 2769 } 2770 } 2771 { 2772 RawMachineAssemblerTester<void> m; 2773 const Operator* shops[] = {m.machine()->Word32Sar(), 2774 m.machine()->Word32Shl(), 2775 m.machine()->Word32Shr()}; 2776 for (size_t n = 0; n < arraysize(shops); n++) { 2777 RawMachineAssemblerTester<int32_t> m( 2778 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 2779 RawMachineLabel blocka, blockb; 2780 m.Branch(m.Word32Equal(m.Word32Or(m.Parameter(0), 2781 m.AddNode(shops[n], m.Parameter(1), 2782 m.Parameter(2))), 2783 m.Int32Constant(0)), 2784 &blocka, &blockb); 2785 m.Bind(&blocka); 2786 m.Return(m.Int32Constant(constant)); 2787 m.Bind(&blockb); 2788 m.Return(m.Int32Constant(0 - constant)); 2789 FOR_UINT32_INPUTS(i) { 2790 FOR_INT32_INPUTS(j) { 2791 FOR_UINT32_SHIFTS(shift) { 2792 int32_t right; 2793 switch (shops[n]->opcode()) { 2794 default: 2795 UNREACHABLE(); 2796 case IrOpcode::kWord32Sar: 2797 right = *j >> shift; 2798 break; 2799 case IrOpcode::kWord32Shl: 2800 right = *j << shift; 2801 break; 2802 case IrOpcode::kWord32Shr: 2803 right = static_cast<uint32_t>(*j) >> shift; 2804 break; 2805 } 2806 int32_t expected = ((*i | right) == 0) ? constant : 0 - constant; 2807 CHECK_EQ(expected, m.Call(*i, *j, shift)); 2808 } 2809 } 2810 } 2811 } 2812 } 2813 } 2814 2815 2816 TEST(RunWord32OrInComparison) { 2817 { 2818 RawMachineAssemblerTester<int32_t> m; 2819 Int32BinopTester bt(&m); 2820 bt.AddReturn( 2821 m.Word32Equal(m.Word32Or(bt.param0, bt.param1), m.Int32Constant(0))); 2822 FOR_UINT32_INPUTS(i) { 2823 FOR_UINT32_INPUTS(j) { 2824 int32_t expected = (*i | *j) == 0; 2825 CHECK_EQ(expected, bt.call(*i, *j)); 2826 } 2827 } 2828 } 2829 { 2830 RawMachineAssemblerTester<int32_t> m; 2831 Int32BinopTester bt(&m); 2832 bt.AddReturn( 2833 m.Word32Equal(m.Int32Constant(0), m.Word32Or(bt.param0, bt.param1))); 2834 FOR_UINT32_INPUTS(i) { 2835 FOR_UINT32_INPUTS(j) { 2836 int32_t expected = (*i | *j) == 0; 2837 CHECK_EQ(expected, bt.call(*i, *j)); 2838 } 2839 } 2840 } 2841 { 2842 FOR_UINT32_INPUTS(i) { 2843 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2844 m.Return(m.Word32Equal(m.Word32Or(m.Int32Constant(*i), m.Parameter(0)), 2845 m.Int32Constant(0))); 2846 FOR_UINT32_INPUTS(j) { 2847 uint32_t expected = (*i | *j) == 0; 2848 CHECK_EQ(expected, m.Call(*j)); 2849 } 2850 } 2851 } 2852 { 2853 FOR_UINT32_INPUTS(i) { 2854 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2855 m.Return(m.Word32Equal(m.Word32Or(m.Parameter(0), m.Int32Constant(*i)), 2856 m.Int32Constant(0))); 2857 FOR_UINT32_INPUTS(j) { 2858 uint32_t expected = (*j | *i) == 0; 2859 CHECK_EQ(expected, m.Call(*j)); 2860 } 2861 } 2862 } 2863 } 2864 2865 2866 TEST(RunWord32XorP) { 2867 { 2868 FOR_UINT32_INPUTS(i) { 2869 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2870 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0))); 2871 FOR_UINT32_INPUTS(j) { 2872 uint32_t expected = *i ^ *j; 2873 CHECK_EQ(expected, m.Call(*j)); 2874 } 2875 } 2876 } 2877 { 2878 RawMachineAssemblerTester<int32_t> m; 2879 Uint32BinopTester bt(&m); 2880 bt.AddReturn(m.Word32Xor(bt.param0, bt.param1)); 2881 FOR_UINT32_INPUTS(i) { 2882 FOR_UINT32_INPUTS(j) { 2883 uint32_t expected = *i ^ *j; 2884 CHECK_EQ(expected, bt.call(*i, *j)); 2885 } 2886 } 2887 } 2888 { 2889 RawMachineAssemblerTester<int32_t> m; 2890 Int32BinopTester bt(&m); 2891 bt.AddReturn(m.Word32Xor(bt.param0, m.Word32Not(bt.param1))); 2892 FOR_INT32_INPUTS(i) { 2893 FOR_INT32_INPUTS(j) { 2894 int32_t expected = *i ^ ~(*j); 2895 CHECK_EQ(expected, bt.call(*i, *j)); 2896 } 2897 } 2898 } 2899 { 2900 RawMachineAssemblerTester<int32_t> m; 2901 Int32BinopTester bt(&m); 2902 bt.AddReturn(m.Word32Xor(m.Word32Not(bt.param0), bt.param1)); 2903 FOR_INT32_INPUTS(i) { 2904 FOR_INT32_INPUTS(j) { 2905 int32_t expected = ~(*i) ^ *j; 2906 CHECK_EQ(expected, bt.call(*i, *j)); 2907 } 2908 } 2909 } 2910 { 2911 FOR_UINT32_INPUTS(i) { 2912 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2913 m.Return(m.Word32Xor(m.Int32Constant(*i), m.Word32Not(m.Parameter(0)))); 2914 FOR_UINT32_INPUTS(j) { 2915 uint32_t expected = *i ^ ~(*j); 2916 CHECK_EQ(expected, m.Call(*j)); 2917 } 2918 } 2919 } 2920 } 2921 2922 2923 TEST(RunWord32XorInBranch) { 2924 static const uint32_t constant = 987654321; 2925 { 2926 RawMachineAssemblerTester<int32_t> m; 2927 Uint32BinopTester bt(&m); 2928 RawMachineLabel blocka, blockb; 2929 m.Branch( 2930 m.Word32Equal(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)), 2931 &blocka, &blockb); 2932 m.Bind(&blocka); 2933 bt.AddReturn(m.Int32Constant(constant)); 2934 m.Bind(&blockb); 2935 bt.AddReturn(m.Int32Constant(0 - constant)); 2936 FOR_UINT32_INPUTS(i) { 2937 FOR_UINT32_INPUTS(j) { 2938 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant; 2939 CHECK_EQ(expected, bt.call(*i, *j)); 2940 } 2941 } 2942 } 2943 { 2944 RawMachineAssemblerTester<int32_t> m; 2945 Uint32BinopTester bt(&m); 2946 RawMachineLabel blocka, blockb; 2947 m.Branch( 2948 m.Word32NotEqual(m.Word32Xor(bt.param0, bt.param1), m.Int32Constant(0)), 2949 &blocka, &blockb); 2950 m.Bind(&blocka); 2951 bt.AddReturn(m.Int32Constant(constant)); 2952 m.Bind(&blockb); 2953 bt.AddReturn(m.Int32Constant(0 - constant)); 2954 FOR_UINT32_INPUTS(i) { 2955 FOR_UINT32_INPUTS(j) { 2956 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant; 2957 CHECK_EQ(expected, bt.call(*i, *j)); 2958 } 2959 } 2960 } 2961 { 2962 FOR_UINT32_INPUTS(i) { 2963 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2964 RawMachineLabel blocka, blockb; 2965 m.Branch(m.Word32Equal(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)), 2966 m.Int32Constant(0)), 2967 &blocka, &blockb); 2968 m.Bind(&blocka); 2969 m.Return(m.Int32Constant(constant)); 2970 m.Bind(&blockb); 2971 m.Return(m.Int32Constant(0 - constant)); 2972 FOR_UINT32_INPUTS(j) { 2973 uint32_t expected = (*i ^ *j) == 0 ? constant : 0 - constant; 2974 CHECK_EQ(expected, m.Call(*j)); 2975 } 2976 } 2977 } 2978 { 2979 FOR_UINT32_INPUTS(i) { 2980 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 2981 RawMachineLabel blocka, blockb; 2982 m.Branch( 2983 m.Word32NotEqual(m.Word32Xor(m.Int32Constant(*i), m.Parameter(0)), 2984 m.Int32Constant(0)), 2985 &blocka, &blockb); 2986 m.Bind(&blocka); 2987 m.Return(m.Int32Constant(constant)); 2988 m.Bind(&blockb); 2989 m.Return(m.Int32Constant(0 - constant)); 2990 FOR_UINT32_INPUTS(j) { 2991 uint32_t expected = (*i ^ *j) != 0 ? constant : 0 - constant; 2992 CHECK_EQ(expected, m.Call(*j)); 2993 } 2994 } 2995 } 2996 { 2997 RawMachineAssemblerTester<void> m; 2998 const Operator* shops[] = {m.machine()->Word32Sar(), 2999 m.machine()->Word32Shl(), 3000 m.machine()->Word32Shr()}; 3001 for (size_t n = 0; n < arraysize(shops); n++) { 3002 RawMachineAssemblerTester<int32_t> m( 3003 MachineType::Uint32(), MachineType::Int32(), MachineType::Uint32()); 3004 RawMachineLabel blocka, blockb; 3005 m.Branch(m.Word32Equal(m.Word32Xor(m.Parameter(0), 3006 m.AddNode(shops[n], m.Parameter(1), 3007 m.Parameter(2))), 3008 m.Int32Constant(0)), 3009 &blocka, &blockb); 3010 m.Bind(&blocka); 3011 m.Return(m.Int32Constant(constant)); 3012 m.Bind(&blockb); 3013 m.Return(m.Int32Constant(0 - constant)); 3014 FOR_UINT32_INPUTS(i) { 3015 FOR_INT32_INPUTS(j) { 3016 FOR_UINT32_SHIFTS(shift) { 3017 int32_t right; 3018 switch (shops[n]->opcode()) { 3019 default: 3020 UNREACHABLE(); 3021 case IrOpcode::kWord32Sar: 3022 right = *j >> shift; 3023 break; 3024 case IrOpcode::kWord32Shl: 3025 right = *j << shift; 3026 break; 3027 case IrOpcode::kWord32Shr: 3028 right = static_cast<uint32_t>(*j) >> shift; 3029 break; 3030 } 3031 int32_t expected = ((*i ^ right) == 0) ? constant : 0 - constant; 3032 CHECK_EQ(expected, m.Call(*i, *j, shift)); 3033 } 3034 } 3035 } 3036 } 3037 } 3038 } 3039 3040 3041 TEST(RunWord32ShlP) { 3042 { 3043 FOR_UINT32_SHIFTS(shift) { 3044 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3045 m.Return(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift))); 3046 FOR_UINT32_INPUTS(j) { 3047 uint32_t expected = *j << shift; 3048 CHECK_EQ(expected, m.Call(*j)); 3049 } 3050 } 3051 } 3052 { 3053 RawMachineAssemblerTester<int32_t> m; 3054 Uint32BinopTester bt(&m); 3055 bt.AddReturn(m.Word32Shl(bt.param0, bt.param1)); 3056 FOR_UINT32_INPUTS(i) { 3057 FOR_UINT32_SHIFTS(shift) { 3058 uint32_t expected = *i << shift; 3059 CHECK_EQ(expected, bt.call(*i, shift)); 3060 } 3061 } 3062 } 3063 } 3064 3065 3066 TEST(RunWord32ShlInComparison) { 3067 { 3068 RawMachineAssemblerTester<int32_t> m; 3069 Uint32BinopTester bt(&m); 3070 bt.AddReturn( 3071 m.Word32Equal(m.Word32Shl(bt.param0, bt.param1), m.Int32Constant(0))); 3072 FOR_UINT32_INPUTS(i) { 3073 FOR_UINT32_SHIFTS(shift) { 3074 uint32_t expected = 0 == (*i << shift); 3075 CHECK_EQ(expected, bt.call(*i, shift)); 3076 } 3077 } 3078 } 3079 { 3080 RawMachineAssemblerTester<int32_t> m; 3081 Uint32BinopTester bt(&m); 3082 bt.AddReturn( 3083 m.Word32Equal(m.Int32Constant(0), m.Word32Shl(bt.param0, bt.param1))); 3084 FOR_UINT32_INPUTS(i) { 3085 FOR_UINT32_SHIFTS(shift) { 3086 uint32_t expected = 0 == (*i << shift); 3087 CHECK_EQ(expected, bt.call(*i, shift)); 3088 } 3089 } 3090 } 3091 { 3092 FOR_UINT32_SHIFTS(shift) { 3093 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3094 m.Return( 3095 m.Word32Equal(m.Int32Constant(0), 3096 m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)))); 3097 FOR_UINT32_INPUTS(i) { 3098 uint32_t expected = 0 == (*i << shift); 3099 CHECK_EQ(expected, m.Call(*i)); 3100 } 3101 } 3102 } 3103 { 3104 FOR_UINT32_SHIFTS(shift) { 3105 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3106 m.Return( 3107 m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Int32Constant(shift)), 3108 m.Int32Constant(0))); 3109 FOR_UINT32_INPUTS(i) { 3110 uint32_t expected = 0 == (*i << shift); 3111 CHECK_EQ(expected, m.Call(*i)); 3112 } 3113 } 3114 } 3115 } 3116 3117 3118 TEST(RunWord32ShrP) { 3119 { 3120 FOR_UINT32_SHIFTS(shift) { 3121 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3122 m.Return(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift))); 3123 FOR_UINT32_INPUTS(j) { 3124 uint32_t expected = *j >> shift; 3125 CHECK_EQ(expected, m.Call(*j)); 3126 } 3127 } 3128 } 3129 { 3130 RawMachineAssemblerTester<int32_t> m; 3131 Uint32BinopTester bt(&m); 3132 bt.AddReturn(m.Word32Shr(bt.param0, bt.param1)); 3133 FOR_UINT32_INPUTS(i) { 3134 FOR_UINT32_SHIFTS(shift) { 3135 uint32_t expected = *i >> shift; 3136 CHECK_EQ(expected, bt.call(*i, shift)); 3137 } 3138 } 3139 CHECK_EQ(0x00010000u, bt.call(0x80000000, 15)); 3140 } 3141 } 3142 3143 3144 TEST(RunWord32ShrInComparison) { 3145 { 3146 RawMachineAssemblerTester<int32_t> m; 3147 Uint32BinopTester bt(&m); 3148 bt.AddReturn( 3149 m.Word32Equal(m.Word32Shr(bt.param0, bt.param1), m.Int32Constant(0))); 3150 FOR_UINT32_INPUTS(i) { 3151 FOR_UINT32_SHIFTS(shift) { 3152 uint32_t expected = 0 == (*i >> shift); 3153 CHECK_EQ(expected, bt.call(*i, shift)); 3154 } 3155 } 3156 } 3157 { 3158 RawMachineAssemblerTester<int32_t> m; 3159 Uint32BinopTester bt(&m); 3160 bt.AddReturn( 3161 m.Word32Equal(m.Int32Constant(0), m.Word32Shr(bt.param0, bt.param1))); 3162 FOR_UINT32_INPUTS(i) { 3163 FOR_UINT32_SHIFTS(shift) { 3164 uint32_t expected = 0 == (*i >> shift); 3165 CHECK_EQ(expected, bt.call(*i, shift)); 3166 } 3167 } 3168 } 3169 { 3170 FOR_UINT32_SHIFTS(shift) { 3171 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3172 m.Return( 3173 m.Word32Equal(m.Int32Constant(0), 3174 m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)))); 3175 FOR_UINT32_INPUTS(i) { 3176 uint32_t expected = 0 == (*i >> shift); 3177 CHECK_EQ(expected, m.Call(*i)); 3178 } 3179 } 3180 } 3181 { 3182 FOR_UINT32_SHIFTS(shift) { 3183 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3184 m.Return( 3185 m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Int32Constant(shift)), 3186 m.Int32Constant(0))); 3187 FOR_UINT32_INPUTS(i) { 3188 uint32_t expected = 0 == (*i >> shift); 3189 CHECK_EQ(expected, m.Call(*i)); 3190 } 3191 } 3192 } 3193 } 3194 3195 3196 TEST(RunWord32SarP) { 3197 { 3198 FOR_INT32_SHIFTS(shift) { 3199 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 3200 m.Return(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift))); 3201 FOR_INT32_INPUTS(j) { 3202 int32_t expected = *j >> shift; 3203 CHECK_EQ(expected, m.Call(*j)); 3204 } 3205 } 3206 } 3207 { 3208 RawMachineAssemblerTester<int32_t> m; 3209 Int32BinopTester bt(&m); 3210 bt.AddReturn(m.Word32Sar(bt.param0, bt.param1)); 3211 FOR_INT32_INPUTS(i) { 3212 FOR_INT32_SHIFTS(shift) { 3213 int32_t expected = *i >> shift; 3214 CHECK_EQ(expected, bt.call(*i, shift)); 3215 } 3216 } 3217 CHECK_EQ(bit_cast<int32_t>(0xFFFF0000), bt.call(0x80000000, 15)); 3218 } 3219 } 3220 3221 3222 TEST(RunWord32SarInComparison) { 3223 { 3224 RawMachineAssemblerTester<int32_t> m; 3225 Int32BinopTester bt(&m); 3226 bt.AddReturn( 3227 m.Word32Equal(m.Word32Sar(bt.param0, bt.param1), m.Int32Constant(0))); 3228 FOR_INT32_INPUTS(i) { 3229 FOR_INT32_SHIFTS(shift) { 3230 int32_t expected = 0 == (*i >> shift); 3231 CHECK_EQ(expected, bt.call(*i, shift)); 3232 } 3233 } 3234 } 3235 { 3236 RawMachineAssemblerTester<int32_t> m; 3237 Int32BinopTester bt(&m); 3238 bt.AddReturn( 3239 m.Word32Equal(m.Int32Constant(0), m.Word32Sar(bt.param0, bt.param1))); 3240 FOR_INT32_INPUTS(i) { 3241 FOR_INT32_SHIFTS(shift) { 3242 int32_t expected = 0 == (*i >> shift); 3243 CHECK_EQ(expected, bt.call(*i, shift)); 3244 } 3245 } 3246 } 3247 { 3248 FOR_INT32_SHIFTS(shift) { 3249 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 3250 m.Return( 3251 m.Word32Equal(m.Int32Constant(0), 3252 m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)))); 3253 FOR_INT32_INPUTS(i) { 3254 int32_t expected = 0 == (*i >> shift); 3255 CHECK_EQ(expected, m.Call(*i)); 3256 } 3257 } 3258 } 3259 { 3260 FOR_INT32_SHIFTS(shift) { 3261 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 3262 m.Return( 3263 m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Int32Constant(shift)), 3264 m.Int32Constant(0))); 3265 FOR_INT32_INPUTS(i) { 3266 int32_t expected = 0 == (*i >> shift); 3267 CHECK_EQ(expected, m.Call(*i)); 3268 } 3269 } 3270 } 3271 } 3272 3273 3274 TEST(RunWord32RorP) { 3275 { 3276 FOR_UINT32_SHIFTS(shift) { 3277 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 3278 m.Return(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift))); 3279 FOR_UINT32_INPUTS(j) { 3280 int32_t expected = bits::RotateRight32(*j, shift); 3281 CHECK_EQ(expected, m.Call(*j)); 3282 } 3283 } 3284 } 3285 { 3286 RawMachineAssemblerTester<int32_t> m; 3287 Uint32BinopTester bt(&m); 3288 bt.AddReturn(m.Word32Ror(bt.param0, bt.param1)); 3289 FOR_UINT32_INPUTS(i) { 3290 FOR_UINT32_SHIFTS(shift) { 3291 uint32_t expected = bits::RotateRight32(*i, shift); 3292 CHECK_EQ(expected, bt.call(*i, shift)); 3293 } 3294 } 3295 } 3296 } 3297 3298 3299 TEST(RunWord32RorInComparison) { 3300 { 3301 RawMachineAssemblerTester<int32_t> m; 3302 Uint32BinopTester bt(&m); 3303 bt.AddReturn( 3304 m.Word32Equal(m.Word32Ror(bt.param0, bt.param1), m.Int32Constant(0))); 3305 FOR_UINT32_INPUTS(i) { 3306 FOR_UINT32_SHIFTS(shift) { 3307 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 3308 CHECK_EQ(expected, bt.call(*i, shift)); 3309 } 3310 } 3311 } 3312 { 3313 RawMachineAssemblerTester<int32_t> m; 3314 Uint32BinopTester bt(&m); 3315 bt.AddReturn( 3316 m.Word32Equal(m.Int32Constant(0), m.Word32Ror(bt.param0, bt.param1))); 3317 FOR_UINT32_INPUTS(i) { 3318 FOR_UINT32_SHIFTS(shift) { 3319 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 3320 CHECK_EQ(expected, bt.call(*i, shift)); 3321 } 3322 } 3323 } 3324 { 3325 FOR_UINT32_SHIFTS(shift) { 3326 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3327 m.Return( 3328 m.Word32Equal(m.Int32Constant(0), 3329 m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)))); 3330 FOR_UINT32_INPUTS(i) { 3331 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 3332 CHECK_EQ(expected, m.Call(*i)); 3333 } 3334 } 3335 } 3336 { 3337 FOR_UINT32_SHIFTS(shift) { 3338 RawMachineAssemblerTester<uint32_t> m(MachineType::Uint32()); 3339 m.Return( 3340 m.Word32Equal(m.Word32Ror(m.Parameter(0), m.Int32Constant(shift)), 3341 m.Int32Constant(0))); 3342 FOR_UINT32_INPUTS(i) { 3343 uint32_t expected = 0 == bits::RotateRight32(*i, shift); 3344 CHECK_EQ(expected, m.Call(*i)); 3345 } 3346 } 3347 } 3348 } 3349 3350 3351 TEST(RunWord32NotP) { 3352 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 3353 m.Return(m.Word32Not(m.Parameter(0))); 3354 FOR_INT32_INPUTS(i) { 3355 int expected = ~(*i); 3356 CHECK_EQ(expected, m.Call(*i)); 3357 } 3358 } 3359 3360 3361 TEST(RunInt32NegP) { 3362 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 3363 m.Return(m.Int32Neg(m.Parameter(0))); 3364 FOR_INT32_INPUTS(i) { 3365 int expected = -*i; 3366 CHECK_EQ(expected, m.Call(*i)); 3367 } 3368 } 3369 3370 3371 TEST(RunWord32EqualAndWord32SarP) { 3372 { 3373 RawMachineAssemblerTester<int32_t> m( 3374 MachineType::Int32(), MachineType::Int32(), MachineType::Uint32()); 3375 m.Return(m.Word32Equal(m.Parameter(0), 3376 m.Word32Sar(m.Parameter(1), m.Parameter(2)))); 3377 FOR_INT32_INPUTS(i) { 3378 FOR_INT32_INPUTS(j) { 3379 FOR_UINT32_SHIFTS(shift) { 3380 int32_t expected = (*i == (*j >> shift)); 3381 CHECK_EQ(expected, m.Call(*i, *j, shift)); 3382 } 3383 } 3384 } 3385 } 3386 { 3387 RawMachineAssemblerTester<int32_t> m( 3388 MachineType::Int32(), MachineType::Uint32(), MachineType::Int32()); 3389 m.Return(m.Word32Equal(m.Word32Sar(m.Parameter(0), m.Parameter(1)), 3390 m.Parameter(2))); 3391 FOR_INT32_INPUTS(i) { 3392 FOR_UINT32_SHIFTS(shift) { 3393 FOR_INT32_INPUTS(k) { 3394 int32_t expected = ((*i >> shift) == *k); 3395 CHECK_EQ(expected, m.Call(*i, shift, *k)); 3396 } 3397 } 3398 } 3399 } 3400 } 3401 3402 3403 TEST(RunWord32EqualAndWord32ShlP) { 3404 { 3405 RawMachineAssemblerTester<int32_t> m( 3406 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 3407 m.Return(m.Word32Equal(m.Parameter(0), 3408 m.Word32Shl(m.Parameter(1), m.Parameter(2)))); 3409 FOR_UINT32_INPUTS(i) { 3410 FOR_UINT32_INPUTS(j) { 3411 FOR_UINT32_SHIFTS(shift) { 3412 int32_t expected = (*i == (*j << shift)); 3413 CHECK_EQ(expected, m.Call(*i, *j, shift)); 3414 } 3415 } 3416 } 3417 } 3418 { 3419 RawMachineAssemblerTester<int32_t> m( 3420 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 3421 m.Return(m.Word32Equal(m.Word32Shl(m.Parameter(0), m.Parameter(1)), 3422 m.Parameter(2))); 3423 FOR_UINT32_INPUTS(i) { 3424 FOR_UINT32_SHIFTS(shift) { 3425 FOR_UINT32_INPUTS(k) { 3426 int32_t expected = ((*i << shift) == *k); 3427 CHECK_EQ(expected, m.Call(*i, shift, *k)); 3428 } 3429 } 3430 } 3431 } 3432 } 3433 3434 3435 TEST(RunWord32EqualAndWord32ShrP) { 3436 { 3437 RawMachineAssemblerTester<int32_t> m( 3438 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 3439 m.Return(m.Word32Equal(m.Parameter(0), 3440 m.Word32Shr(m.Parameter(1), m.Parameter(2)))); 3441 FOR_UINT32_INPUTS(i) { 3442 FOR_UINT32_INPUTS(j) { 3443 FOR_UINT32_SHIFTS(shift) { 3444 int32_t expected = (*i == (*j >> shift)); 3445 CHECK_EQ(expected, m.Call(*i, *j, shift)); 3446 } 3447 } 3448 } 3449 } 3450 { 3451 RawMachineAssemblerTester<int32_t> m( 3452 MachineType::Uint32(), MachineType::Uint32(), MachineType::Uint32()); 3453 m.Return(m.Word32Equal(m.Word32Shr(m.Parameter(0), m.Parameter(1)), 3454 m.Parameter(2))); 3455 FOR_UINT32_INPUTS(i) { 3456 FOR_UINT32_SHIFTS(shift) { 3457 FOR_UINT32_INPUTS(k) { 3458 int32_t expected = ((*i >> shift) == *k); 3459 CHECK_EQ(expected, m.Call(*i, shift, *k)); 3460 } 3461 } 3462 } 3463 } 3464 } 3465 3466 3467 TEST(RunDeadNodes) { 3468 for (int i = 0; true; i++) { 3469 RawMachineAssemblerTester<int32_t> m(i == 5 ? MachineType::Int32() 3470 : MachineType::None()); 3471 int constant = 0x55 + i; 3472 switch (i) { 3473 case 0: 3474 m.Int32Constant(44); 3475 break; 3476 case 1: 3477 m.StringConstant("unused"); 3478 break; 3479 case 2: 3480 m.NumberConstant(11.1); 3481 break; 3482 case 3: 3483 m.PointerConstant(&constant); 3484 break; 3485 case 4: 3486 m.LoadFromPointer(&constant, MachineType::Int32()); 3487 break; 3488 case 5: 3489 m.Parameter(0); 3490 break; 3491 default: 3492 return; 3493 } 3494 m.Return(m.Int32Constant(constant)); 3495 if (i != 5) { 3496 CHECK_EQ(constant, m.Call()); 3497 } else { 3498 CHECK_EQ(constant, m.Call(0)); 3499 } 3500 } 3501 } 3502 3503 3504 TEST(RunDeadInt32Binops) { 3505 RawMachineAssemblerTester<int32_t> m; 3506 3507 const Operator* kOps[] = { 3508 m.machine()->Word32And(), m.machine()->Word32Or(), 3509 m.machine()->Word32Xor(), m.machine()->Word32Shl(), 3510 m.machine()->Word32Shr(), m.machine()->Word32Sar(), 3511 m.machine()->Word32Ror(), m.machine()->Word32Equal(), 3512 m.machine()->Int32Add(), m.machine()->Int32Sub(), 3513 m.machine()->Int32Mul(), m.machine()->Int32MulHigh(), 3514 m.machine()->Int32Div(), m.machine()->Uint32Div(), 3515 m.machine()->Int32Mod(), m.machine()->Uint32Mod(), 3516 m.machine()->Uint32MulHigh(), m.machine()->Int32LessThan(), 3517 m.machine()->Int32LessThanOrEqual(), m.machine()->Uint32LessThan(), 3518 m.machine()->Uint32LessThanOrEqual()}; 3519 3520 for (size_t i = 0; i < arraysize(kOps); ++i) { 3521 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 3522 MachineType::Int32()); 3523 int32_t constant = static_cast<int32_t>(0x55555 + i); 3524 m.AddNode(kOps[i], m.Parameter(0), m.Parameter(1)); 3525 m.Return(m.Int32Constant(constant)); 3526 3527 CHECK_EQ(constant, m.Call(1, 1)); 3528 } 3529 } 3530 3531 3532 template <typename Type> 3533 static void RunLoadImmIndex(MachineType rep) { 3534 const int kNumElems = 3; 3535 Type buffer[kNumElems]; 3536 3537 // initialize the buffer with raw data. 3538 byte* raw = reinterpret_cast<byte*>(buffer); 3539 for (size_t i = 0; i < sizeof(buffer); i++) { 3540 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); 3541 } 3542 3543 // Test with various large and small offsets. 3544 for (int offset = -1; offset <= 200000; offset *= -5) { 3545 for (int i = 0; i < kNumElems; i++) { 3546 RawMachineAssemblerTester<Type> m; 3547 Node* base = m.PointerConstant(buffer - offset); 3548 Node* index = m.Int32Constant((offset + i) * sizeof(buffer[0])); 3549 m.Return(m.Load(rep, base, index)); 3550 3551 Type expected = buffer[i]; 3552 Type actual = m.Call(); 3553 CHECK(expected == actual); 3554 } 3555 } 3556 } 3557 3558 3559 TEST(RunLoadImmIndex) { 3560 RunLoadImmIndex<int8_t>(MachineType::Int8()); 3561 RunLoadImmIndex<uint8_t>(MachineType::Uint8()); 3562 RunLoadImmIndex<int16_t>(MachineType::Int16()); 3563 RunLoadImmIndex<uint16_t>(MachineType::Uint16()); 3564 RunLoadImmIndex<int32_t>(MachineType::Int32()); 3565 RunLoadImmIndex<uint32_t>(MachineType::Uint32()); 3566 RunLoadImmIndex<int32_t*>(MachineType::AnyTagged()); 3567 3568 // TODO(titzer): test kRepBit loads 3569 // TODO(titzer): test MachineType::Float64() loads 3570 // TODO(titzer): test various indexing modes. 3571 } 3572 3573 3574 template <typename CType> 3575 static void RunLoadStore(MachineType rep) { 3576 const int kNumElems = 4; 3577 CType buffer[kNumElems]; 3578 3579 for (int32_t x = 0; x < kNumElems; x++) { 3580 int32_t y = kNumElems - x - 1; 3581 // initialize the buffer with raw data. 3582 byte* raw = reinterpret_cast<byte*>(buffer); 3583 for (size_t i = 0; i < sizeof(buffer); i++) { 3584 raw[i] = static_cast<byte>((i + sizeof(buffer)) ^ 0xAA); 3585 } 3586 3587 RawMachineAssemblerTester<int32_t> m; 3588 int32_t OK = 0x29000 + x; 3589 Node* base = m.PointerConstant(buffer); 3590 Node* index0 = m.IntPtrConstant(x * sizeof(buffer[0])); 3591 Node* load = m.Load(rep, base, index0); 3592 Node* index1 = m.IntPtrConstant(y * sizeof(buffer[0])); 3593 m.Store(rep.representation(), base, index1, load, kNoWriteBarrier); 3594 m.Return(m.Int32Constant(OK)); 3595 3596 CHECK(buffer[x] != buffer[y]); 3597 CHECK_EQ(OK, m.Call()); 3598 CHECK(buffer[x] == buffer[y]); 3599 } 3600 } 3601 3602 3603 TEST(RunLoadStore) { 3604 RunLoadStore<int8_t>(MachineType::Int8()); 3605 RunLoadStore<uint8_t>(MachineType::Uint8()); 3606 RunLoadStore<int16_t>(MachineType::Int16()); 3607 RunLoadStore<uint16_t>(MachineType::Uint16()); 3608 RunLoadStore<int32_t>(MachineType::Int32()); 3609 RunLoadStore<uint32_t>(MachineType::Uint32()); 3610 RunLoadStore<void*>(MachineType::AnyTagged()); 3611 RunLoadStore<float>(MachineType::Float32()); 3612 RunLoadStore<double>(MachineType::Float64()); 3613 } 3614 3615 3616 TEST(RunFloat32Add) { 3617 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), 3618 MachineType::Float32()); 3619 m.Return(m.Float32Add(m.Parameter(0), m.Parameter(1))); 3620 3621 FOR_FLOAT32_INPUTS(i) { 3622 FOR_FLOAT32_INPUTS(j) { 3623 volatile float expected = *i + *j; 3624 CheckFloatEq(expected, m.Call(*i, *j)); 3625 } 3626 } 3627 } 3628 3629 3630 TEST(RunFloat32Sub) { 3631 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), 3632 MachineType::Float32()); 3633 m.Return(m.Float32Sub(m.Parameter(0), m.Parameter(1))); 3634 3635 FOR_FLOAT32_INPUTS(i) { 3636 FOR_FLOAT32_INPUTS(j) { 3637 volatile float expected = *i - *j; 3638 CheckFloatEq(expected, m.Call(*i, *j)); 3639 } 3640 } 3641 } 3642 3643 3644 TEST(RunFloat32Mul) { 3645 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), 3646 MachineType::Float32()); 3647 m.Return(m.Float32Mul(m.Parameter(0), m.Parameter(1))); 3648 3649 FOR_FLOAT32_INPUTS(i) { 3650 FOR_FLOAT32_INPUTS(j) { 3651 volatile float expected = *i * *j; 3652 CheckFloatEq(expected, m.Call(*i, *j)); 3653 } 3654 } 3655 } 3656 3657 3658 TEST(RunFloat32Div) { 3659 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32(), 3660 MachineType::Float32()); 3661 m.Return(m.Float32Div(m.Parameter(0), m.Parameter(1))); 3662 3663 FOR_FLOAT32_INPUTS(i) { 3664 FOR_FLOAT32_INPUTS(j) { 3665 volatile float expected = *i / *j; 3666 CheckFloatEq(expected, m.Call(*i, *j)); 3667 } 3668 } 3669 } 3670 3671 3672 TEST(RunFloat64Add) { 3673 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 3674 MachineType::Float64()); 3675 m.Return(m.Float64Add(m.Parameter(0), m.Parameter(1))); 3676 3677 FOR_FLOAT64_INPUTS(i) { 3678 FOR_FLOAT64_INPUTS(j) { 3679 volatile double expected = *i + *j; 3680 CheckDoubleEq(expected, m.Call(*i, *j)); 3681 } 3682 } 3683 } 3684 3685 3686 TEST(RunFloat64Sub) { 3687 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 3688 MachineType::Float64()); 3689 m.Return(m.Float64Sub(m.Parameter(0), m.Parameter(1))); 3690 3691 FOR_FLOAT64_INPUTS(i) { 3692 FOR_FLOAT64_INPUTS(j) { 3693 volatile double expected = *i - *j; 3694 CheckDoubleEq(expected, m.Call(*i, *j)); 3695 } 3696 } 3697 } 3698 3699 3700 TEST(RunFloat64Mul) { 3701 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 3702 MachineType::Float64()); 3703 m.Return(m.Float64Mul(m.Parameter(0), m.Parameter(1))); 3704 3705 FOR_FLOAT64_INPUTS(i) { 3706 FOR_FLOAT64_INPUTS(j) { 3707 volatile double expected = *i * *j; 3708 CheckDoubleEq(expected, m.Call(*i, *j)); 3709 } 3710 } 3711 } 3712 3713 3714 TEST(RunFloat64Div) { 3715 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 3716 MachineType::Float64()); 3717 m.Return(m.Float64Div(m.Parameter(0), m.Parameter(1))); 3718 3719 FOR_FLOAT64_INPUTS(i) { 3720 FOR_FLOAT64_INPUTS(j) { 3721 volatile double expected = *i / *j; 3722 CheckDoubleEq(expected, m.Call(*i, *j)); 3723 } 3724 } 3725 } 3726 3727 3728 TEST(RunFloat64Mod) { 3729 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 3730 MachineType::Float64()); 3731 m.Return(m.Float64Mod(m.Parameter(0), m.Parameter(1))); 3732 3733 FOR_FLOAT64_INPUTS(i) { 3734 FOR_FLOAT64_INPUTS(j) { CheckDoubleEq(modulo(*i, *j), m.Call(*i, *j)); } 3735 } 3736 } 3737 3738 3739 TEST(RunDeadFloat32Binops) { 3740 RawMachineAssemblerTester<int32_t> m; 3741 3742 const Operator* ops[] = {m.machine()->Float32Add(), m.machine()->Float32Sub(), 3743 m.machine()->Float32Mul(), m.machine()->Float32Div(), 3744 NULL}; 3745 3746 for (int i = 0; ops[i] != NULL; i++) { 3747 RawMachineAssemblerTester<int32_t> m; 3748 int constant = 0x53355 + i; 3749 m.AddNode(ops[i], m.Float32Constant(0.1f), m.Float32Constant(1.11f)); 3750 m.Return(m.Int32Constant(constant)); 3751 CHECK_EQ(constant, m.Call()); 3752 } 3753 } 3754 3755 3756 TEST(RunDeadFloat64Binops) { 3757 RawMachineAssemblerTester<int32_t> m; 3758 3759 const Operator* ops[] = {m.machine()->Float64Add(), m.machine()->Float64Sub(), 3760 m.machine()->Float64Mul(), m.machine()->Float64Div(), 3761 m.machine()->Float64Mod(), NULL}; 3762 3763 for (int i = 0; ops[i] != NULL; i++) { 3764 RawMachineAssemblerTester<int32_t> m; 3765 int constant = 0x53355 + i; 3766 m.AddNode(ops[i], m.Float64Constant(0.1), m.Float64Constant(1.11)); 3767 m.Return(m.Int32Constant(constant)); 3768 CHECK_EQ(constant, m.Call()); 3769 } 3770 } 3771 3772 3773 TEST(RunFloat32AddP) { 3774 RawMachineAssemblerTester<int32_t> m; 3775 Float32BinopTester bt(&m); 3776 3777 bt.AddReturn(m.Float32Add(bt.param0, bt.param1)); 3778 3779 FOR_FLOAT32_INPUTS(pl) { 3780 FOR_FLOAT32_INPUTS(pr) { 3781 float expected = *pl + *pr; 3782 CheckFloatEq(expected, bt.call(*pl, *pr)); 3783 } 3784 } 3785 } 3786 3787 3788 TEST(RunFloat64AddP) { 3789 RawMachineAssemblerTester<int32_t> m; 3790 Float64BinopTester bt(&m); 3791 3792 bt.AddReturn(m.Float64Add(bt.param0, bt.param1)); 3793 3794 FOR_FLOAT64_INPUTS(pl) { 3795 FOR_FLOAT64_INPUTS(pr) { 3796 double expected = *pl + *pr; 3797 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3798 } 3799 } 3800 } 3801 3802 3803 TEST(RunFloa32MaxP) { 3804 RawMachineAssemblerTester<int32_t> m; 3805 Float32BinopTester bt(&m); 3806 if (!m.machine()->Float32Max().IsSupported()) return; 3807 3808 bt.AddReturn(m.Float32Max(bt.param0, bt.param1)); 3809 3810 FOR_FLOAT32_INPUTS(pl) { 3811 FOR_FLOAT32_INPUTS(pr) { 3812 double expected = *pl > *pr ? *pl : *pr; 3813 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3814 } 3815 } 3816 } 3817 3818 3819 TEST(RunFloat64MaxP) { 3820 RawMachineAssemblerTester<int32_t> m; 3821 Float64BinopTester bt(&m); 3822 if (!m.machine()->Float64Max().IsSupported()) return; 3823 3824 bt.AddReturn(m.Float64Max(bt.param0, bt.param1)); 3825 3826 FOR_FLOAT64_INPUTS(pl) { 3827 FOR_FLOAT64_INPUTS(pr) { 3828 double expected = *pl > *pr ? *pl : *pr; 3829 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3830 } 3831 } 3832 } 3833 3834 3835 TEST(RunFloat32MinP) { 3836 RawMachineAssemblerTester<int32_t> m; 3837 Float32BinopTester bt(&m); 3838 if (!m.machine()->Float32Min().IsSupported()) return; 3839 3840 bt.AddReturn(m.Float32Min(bt.param0, bt.param1)); 3841 3842 FOR_FLOAT32_INPUTS(pl) { 3843 FOR_FLOAT32_INPUTS(pr) { 3844 double expected = *pl < *pr ? *pl : *pr; 3845 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3846 } 3847 } 3848 } 3849 3850 3851 TEST(RunFloat64MinP) { 3852 RawMachineAssemblerTester<int32_t> m; 3853 Float64BinopTester bt(&m); 3854 if (!m.machine()->Float64Min().IsSupported()) return; 3855 3856 bt.AddReturn(m.Float64Min(bt.param0, bt.param1)); 3857 3858 FOR_FLOAT64_INPUTS(pl) { 3859 FOR_FLOAT64_INPUTS(pr) { 3860 double expected = *pl < *pr ? *pl : *pr; 3861 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3862 } 3863 } 3864 } 3865 3866 3867 TEST(RunFloat32SubP) { 3868 RawMachineAssemblerTester<int32_t> m; 3869 Float32BinopTester bt(&m); 3870 3871 bt.AddReturn(m.Float32Sub(bt.param0, bt.param1)); 3872 3873 FOR_FLOAT32_INPUTS(pl) { 3874 FOR_FLOAT32_INPUTS(pr) { 3875 float expected = *pl - *pr; 3876 CheckFloatEq(expected, bt.call(*pl, *pr)); 3877 } 3878 } 3879 } 3880 3881 3882 TEST(RunFloat32SubImm1) { 3883 FOR_FLOAT32_INPUTS(i) { 3884 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 3885 m.Return(m.Float32Sub(m.Float32Constant(*i), m.Parameter(0))); 3886 3887 FOR_FLOAT32_INPUTS(j) { 3888 volatile float expected = *i - *j; 3889 CheckFloatEq(expected, m.Call(*j)); 3890 } 3891 } 3892 } 3893 3894 3895 TEST(RunFloat32SubImm2) { 3896 FOR_FLOAT32_INPUTS(i) { 3897 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 3898 m.Return(m.Float32Sub(m.Parameter(0), m.Float32Constant(*i))); 3899 3900 FOR_FLOAT32_INPUTS(j) { 3901 volatile float expected = *j - *i; 3902 CheckFloatEq(expected, m.Call(*j)); 3903 } 3904 } 3905 } 3906 3907 3908 TEST(RunFloat64SubImm1) { 3909 FOR_FLOAT64_INPUTS(i) { 3910 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 3911 m.Return(m.Float64Sub(m.Float64Constant(*i), m.Parameter(0))); 3912 3913 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i - *j, m.Call(*j)); } 3914 } 3915 } 3916 3917 3918 TEST(RunFloat64SubImm2) { 3919 FOR_FLOAT64_INPUTS(i) { 3920 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 3921 m.Return(m.Float64Sub(m.Parameter(0), m.Float64Constant(*i))); 3922 3923 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j - *i, m.Call(*j)); } 3924 } 3925 } 3926 3927 3928 TEST(RunFloat64SubP) { 3929 RawMachineAssemblerTester<int32_t> m; 3930 Float64BinopTester bt(&m); 3931 3932 bt.AddReturn(m.Float64Sub(bt.param0, bt.param1)); 3933 3934 FOR_FLOAT64_INPUTS(pl) { 3935 FOR_FLOAT64_INPUTS(pr) { 3936 double expected = *pl - *pr; 3937 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3938 } 3939 } 3940 } 3941 3942 3943 TEST(RunFloat32MulP) { 3944 RawMachineAssemblerTester<int32_t> m; 3945 Float32BinopTester bt(&m); 3946 3947 bt.AddReturn(m.Float32Mul(bt.param0, bt.param1)); 3948 3949 FOR_FLOAT32_INPUTS(pl) { 3950 FOR_FLOAT32_INPUTS(pr) { 3951 float expected = *pl * *pr; 3952 CheckFloatEq(expected, bt.call(*pl, *pr)); 3953 } 3954 } 3955 } 3956 3957 3958 TEST(RunFloat64MulP) { 3959 RawMachineAssemblerTester<int32_t> m; 3960 Float64BinopTester bt(&m); 3961 3962 bt.AddReturn(m.Float64Mul(bt.param0, bt.param1)); 3963 3964 FOR_FLOAT64_INPUTS(pl) { 3965 FOR_FLOAT64_INPUTS(pr) { 3966 double expected = *pl * *pr; 3967 CheckDoubleEq(expected, bt.call(*pl, *pr)); 3968 } 3969 } 3970 } 3971 3972 3973 TEST(RunFloat64MulAndFloat64Add1) { 3974 BufferedRawMachineAssemblerTester<double> m( 3975 MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); 3976 m.Return(m.Float64Add(m.Float64Mul(m.Parameter(0), m.Parameter(1)), 3977 m.Parameter(2))); 3978 3979 FOR_FLOAT64_INPUTS(i) { 3980 FOR_FLOAT64_INPUTS(j) { 3981 FOR_FLOAT64_INPUTS(k) { 3982 CheckDoubleEq((*i * *j) + *k, m.Call(*i, *j, *k)); 3983 } 3984 } 3985 } 3986 } 3987 3988 3989 TEST(RunFloat64MulAndFloat64Add2) { 3990 BufferedRawMachineAssemblerTester<double> m( 3991 MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); 3992 m.Return(m.Float64Add(m.Parameter(0), 3993 m.Float64Mul(m.Parameter(1), m.Parameter(2)))); 3994 3995 FOR_FLOAT64_INPUTS(i) { 3996 FOR_FLOAT64_INPUTS(j) { 3997 FOR_FLOAT64_INPUTS(k) { 3998 CheckDoubleEq(*i + (*j * *k), m.Call(*i, *j, *k)); 3999 } 4000 } 4001 } 4002 } 4003 4004 4005 TEST(RunFloat64MulAndFloat64Sub1) { 4006 BufferedRawMachineAssemblerTester<double> m( 4007 MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); 4008 m.Return(m.Float64Sub(m.Float64Mul(m.Parameter(0), m.Parameter(1)), 4009 m.Parameter(2))); 4010 4011 FOR_FLOAT64_INPUTS(i) { 4012 FOR_FLOAT64_INPUTS(j) { 4013 FOR_FLOAT64_INPUTS(k) { 4014 CheckDoubleEq((*i * *j) - *k, m.Call(*i, *j, *k)); 4015 } 4016 } 4017 } 4018 } 4019 4020 4021 TEST(RunFloat64MulAndFloat64Sub2) { 4022 BufferedRawMachineAssemblerTester<double> m( 4023 MachineType::Float64(), MachineType::Float64(), MachineType::Float64()); 4024 m.Return(m.Float64Sub(m.Parameter(0), 4025 m.Float64Mul(m.Parameter(1), m.Parameter(2)))); 4026 4027 FOR_FLOAT64_INPUTS(i) { 4028 FOR_FLOAT64_INPUTS(j) { 4029 FOR_FLOAT64_INPUTS(k) { 4030 CheckDoubleEq(*i - (*j * *k), m.Call(*i, *j, *k)); 4031 } 4032 } 4033 } 4034 } 4035 4036 4037 TEST(RunFloat64MulImm1) { 4038 FOR_FLOAT64_INPUTS(i) { 4039 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 4040 m.Return(m.Float64Mul(m.Float64Constant(*i), m.Parameter(0))); 4041 4042 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*i * *j, m.Call(*j)); } 4043 } 4044 } 4045 4046 4047 TEST(RunFloat64MulImm2) { 4048 FOR_FLOAT64_INPUTS(i) { 4049 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 4050 m.Return(m.Float64Mul(m.Parameter(0), m.Float64Constant(*i))); 4051 4052 FOR_FLOAT64_INPUTS(j) { CheckFloatEq(*j * *i, m.Call(*j)); } 4053 } 4054 } 4055 4056 4057 TEST(RunFloat32DivP) { 4058 RawMachineAssemblerTester<int32_t> m; 4059 Float32BinopTester bt(&m); 4060 4061 bt.AddReturn(m.Float32Div(bt.param0, bt.param1)); 4062 4063 FOR_FLOAT32_INPUTS(pl) { 4064 FOR_FLOAT32_INPUTS(pr) { 4065 float expected = *pl / *pr; 4066 CheckFloatEq(expected, bt.call(*pl, *pr)); 4067 } 4068 } 4069 } 4070 4071 4072 TEST(RunFloat64DivP) { 4073 RawMachineAssemblerTester<int32_t> m; 4074 Float64BinopTester bt(&m); 4075 4076 bt.AddReturn(m.Float64Div(bt.param0, bt.param1)); 4077 4078 FOR_FLOAT64_INPUTS(pl) { 4079 FOR_FLOAT64_INPUTS(pr) { 4080 double expected = *pl / *pr; 4081 CheckDoubleEq(expected, bt.call(*pl, *pr)); 4082 } 4083 } 4084 } 4085 4086 4087 TEST(RunFloat64ModP) { 4088 RawMachineAssemblerTester<int32_t> m; 4089 Float64BinopTester bt(&m); 4090 4091 bt.AddReturn(m.Float64Mod(bt.param0, bt.param1)); 4092 4093 FOR_FLOAT64_INPUTS(i) { 4094 FOR_FLOAT64_INPUTS(j) { 4095 double expected = modulo(*i, *j); 4096 double found = bt.call(*i, *j); 4097 CheckDoubleEq(expected, found); 4098 } 4099 } 4100 } 4101 4102 4103 TEST(RunChangeInt32ToFloat64_A) { 4104 int32_t magic = 0x986234; 4105 BufferedRawMachineAssemblerTester<double> m; 4106 m.Return(m.ChangeInt32ToFloat64(m.Int32Constant(magic))); 4107 CheckDoubleEq(static_cast<double>(magic), m.Call()); 4108 } 4109 4110 4111 TEST(RunChangeInt32ToFloat64_B) { 4112 BufferedRawMachineAssemblerTester<double> m(MachineType::Int32()); 4113 m.Return(m.ChangeInt32ToFloat64(m.Parameter(0))); 4114 4115 FOR_INT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); } 4116 } 4117 4118 4119 TEST(RunChangeUint32ToFloat64) { 4120 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint32()); 4121 m.Return(m.ChangeUint32ToFloat64(m.Parameter(0))); 4122 4123 FOR_UINT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); } 4124 } 4125 4126 4127 TEST(RunChangeFloat64ToInt32_A) { 4128 BufferedRawMachineAssemblerTester<int32_t> m; 4129 double magic = 11.1; 4130 m.Return(m.ChangeFloat64ToInt32(m.Float64Constant(magic))); 4131 CHECK_EQ(static_cast<int32_t>(magic), m.Call()); 4132 } 4133 4134 4135 TEST(RunChangeFloat64ToInt32_B) { 4136 BufferedRawMachineAssemblerTester<int32_t> m(MachineType::Float64()); 4137 m.Return(m.ChangeFloat64ToInt32(m.Parameter(0))); 4138 4139 // Note we don't check fractional inputs, or inputs outside the range of 4140 // int32, because these Convert operators really should be Change operators. 4141 FOR_INT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); } 4142 4143 for (int32_t n = 1; n < 31; ++n) { 4144 CHECK_EQ(1 << n, m.Call(static_cast<double>(1 << n))); 4145 } 4146 4147 for (int32_t n = 1; n < 31; ++n) { 4148 CHECK_EQ(3 << n, m.Call(static_cast<double>(3 << n))); 4149 } 4150 } 4151 4152 4153 TEST(RunChangeFloat64ToUint32) { 4154 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64()); 4155 m.Return(m.ChangeFloat64ToUint32(m.Parameter(0))); 4156 4157 { 4158 FOR_UINT32_INPUTS(i) { CHECK_EQ(*i, m.Call(static_cast<double>(*i))); } 4159 } 4160 4161 // Check various powers of 2. 4162 for (int32_t n = 1; n < 31; ++n) { 4163 { CHECK_EQ(1u << n, m.Call(static_cast<double>(1u << n))); } 4164 4165 { CHECK_EQ(3u << n, m.Call(static_cast<double>(3u << n))); } 4166 } 4167 // Note we don't check fractional inputs, because these Convert operators 4168 // really should be Change operators. 4169 } 4170 4171 4172 TEST(RunTruncateFloat64ToFloat32) { 4173 BufferedRawMachineAssemblerTester<float> m(MachineType::Float64()); 4174 4175 m.Return(m.TruncateFloat64ToFloat32(m.Parameter(0))); 4176 4177 FOR_FLOAT64_INPUTS(i) { CheckFloatEq(DoubleToFloat32(*i), m.Call(*i)); } 4178 } 4179 4180 4181 TEST(RunDeadChangeFloat64ToInt32) { 4182 RawMachineAssemblerTester<int32_t> m; 4183 const int magic = 0x88abcda4; 4184 m.ChangeFloat64ToInt32(m.Float64Constant(999.78)); 4185 m.Return(m.Int32Constant(magic)); 4186 CHECK_EQ(magic, m.Call()); 4187 } 4188 4189 4190 TEST(RunDeadChangeInt32ToFloat64) { 4191 RawMachineAssemblerTester<int32_t> m; 4192 const int magic = 0x8834abcd; 4193 m.ChangeInt32ToFloat64(m.Int32Constant(magic - 6888)); 4194 m.Return(m.Int32Constant(magic)); 4195 CHECK_EQ(magic, m.Call()); 4196 } 4197 4198 4199 TEST(RunLoopPhiInduction2) { 4200 RawMachineAssemblerTester<int32_t> m; 4201 4202 int false_val = 0x10777; 4203 4204 // x = false_val; while(false) { x++; } return x; 4205 RawMachineLabel header, body, end; 4206 Node* false_node = m.Int32Constant(false_val); 4207 m.Goto(&header); 4208 m.Bind(&header); 4209 Node* phi = m.Phi(MachineRepresentation::kWord32, false_node, false_node); 4210 m.Branch(m.Int32Constant(0), &body, &end); 4211 m.Bind(&body); 4212 Node* add = m.Int32Add(phi, m.Int32Constant(1)); 4213 phi->ReplaceInput(1, add); 4214 m.Goto(&header); 4215 m.Bind(&end); 4216 m.Return(phi); 4217 4218 CHECK_EQ(false_val, m.Call()); 4219 } 4220 4221 4222 TEST(RunFloatDiamond) { 4223 RawMachineAssemblerTester<int32_t> m; 4224 4225 const int magic = 99645; 4226 float buffer = 0.1f; 4227 float constant = 99.99f; 4228 4229 RawMachineLabel blocka, blockb, end; 4230 Node* k1 = m.Float32Constant(constant); 4231 Node* k2 = m.Float32Constant(0 - constant); 4232 m.Branch(m.Int32Constant(0), &blocka, &blockb); 4233 m.Bind(&blocka); 4234 m.Goto(&end); 4235 m.Bind(&blockb); 4236 m.Goto(&end); 4237 m.Bind(&end); 4238 Node* phi = m.Phi(MachineRepresentation::kFloat32, k2, k1); 4239 m.Store(MachineRepresentation::kFloat32, m.PointerConstant(&buffer), 4240 m.IntPtrConstant(0), phi, kNoWriteBarrier); 4241 m.Return(m.Int32Constant(magic)); 4242 4243 CHECK_EQ(magic, m.Call()); 4244 CHECK(constant == buffer); 4245 } 4246 4247 4248 TEST(RunDoubleDiamond) { 4249 RawMachineAssemblerTester<int32_t> m; 4250 4251 const int magic = 99645; 4252 double buffer = 0.1; 4253 double constant = 99.99; 4254 4255 RawMachineLabel blocka, blockb, end; 4256 Node* k1 = m.Float64Constant(constant); 4257 Node* k2 = m.Float64Constant(0 - constant); 4258 m.Branch(m.Int32Constant(0), &blocka, &blockb); 4259 m.Bind(&blocka); 4260 m.Goto(&end); 4261 m.Bind(&blockb); 4262 m.Goto(&end); 4263 m.Bind(&end); 4264 Node* phi = m.Phi(MachineRepresentation::kFloat64, k2, k1); 4265 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer), 4266 m.Int32Constant(0), phi, kNoWriteBarrier); 4267 m.Return(m.Int32Constant(magic)); 4268 4269 CHECK_EQ(magic, m.Call()); 4270 CHECK_EQ(constant, buffer); 4271 } 4272 4273 4274 TEST(RunRefDiamond) { 4275 RawMachineAssemblerTester<int32_t> m; 4276 4277 const int magic = 99644; 4278 Handle<String> rexpected = 4279 CcTest::i_isolate()->factory()->InternalizeUtf8String("A"); 4280 String* buffer; 4281 4282 RawMachineLabel blocka, blockb, end; 4283 Node* k1 = m.StringConstant("A"); 4284 Node* k2 = m.StringConstant("B"); 4285 m.Branch(m.Int32Constant(0), &blocka, &blockb); 4286 m.Bind(&blocka); 4287 m.Goto(&end); 4288 m.Bind(&blockb); 4289 m.Goto(&end); 4290 m.Bind(&end); 4291 Node* phi = m.Phi(MachineRepresentation::kTagged, k2, k1); 4292 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&buffer), 4293 m.Int32Constant(0), phi, kNoWriteBarrier); 4294 m.Return(m.Int32Constant(magic)); 4295 4296 CHECK_EQ(magic, m.Call()); 4297 CHECK(rexpected->SameValue(buffer)); 4298 } 4299 4300 4301 TEST(RunDoubleRefDiamond) { 4302 RawMachineAssemblerTester<int32_t> m; 4303 4304 const int magic = 99648; 4305 double dbuffer = 0.1; 4306 double dconstant = 99.99; 4307 Handle<String> rexpected = 4308 CcTest::i_isolate()->factory()->InternalizeUtf8String("AX"); 4309 String* rbuffer; 4310 4311 RawMachineLabel blocka, blockb, end; 4312 Node* d1 = m.Float64Constant(dconstant); 4313 Node* d2 = m.Float64Constant(0 - dconstant); 4314 Node* r1 = m.StringConstant("AX"); 4315 Node* r2 = m.StringConstant("BX"); 4316 m.Branch(m.Int32Constant(0), &blocka, &blockb); 4317 m.Bind(&blocka); 4318 m.Goto(&end); 4319 m.Bind(&blockb); 4320 m.Goto(&end); 4321 m.Bind(&end); 4322 Node* dphi = m.Phi(MachineRepresentation::kFloat64, d2, d1); 4323 Node* rphi = m.Phi(MachineRepresentation::kTagged, r2, r1); 4324 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer), 4325 m.Int32Constant(0), dphi, kNoWriteBarrier); 4326 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer), 4327 m.Int32Constant(0), rphi, kNoWriteBarrier); 4328 m.Return(m.Int32Constant(magic)); 4329 4330 CHECK_EQ(magic, m.Call()); 4331 CHECK_EQ(dconstant, dbuffer); 4332 CHECK(rexpected->SameValue(rbuffer)); 4333 } 4334 4335 4336 TEST(RunDoubleRefDoubleDiamond) { 4337 RawMachineAssemblerTester<int32_t> m; 4338 4339 const int magic = 99649; 4340 double dbuffer = 0.1; 4341 double dconstant = 99.997; 4342 Handle<String> rexpected = 4343 CcTest::i_isolate()->factory()->InternalizeUtf8String("AD"); 4344 String* rbuffer; 4345 4346 RawMachineLabel blocka, blockb, mid, blockd, blocke, end; 4347 Node* d1 = m.Float64Constant(dconstant); 4348 Node* d2 = m.Float64Constant(0 - dconstant); 4349 Node* r1 = m.StringConstant("AD"); 4350 Node* r2 = m.StringConstant("BD"); 4351 m.Branch(m.Int32Constant(0), &blocka, &blockb); 4352 m.Bind(&blocka); 4353 m.Goto(&mid); 4354 m.Bind(&blockb); 4355 m.Goto(&mid); 4356 m.Bind(&mid); 4357 Node* dphi1 = m.Phi(MachineRepresentation::kFloat64, d2, d1); 4358 Node* rphi1 = m.Phi(MachineRepresentation::kTagged, r2, r1); 4359 m.Branch(m.Int32Constant(0), &blockd, &blocke); 4360 4361 m.Bind(&blockd); 4362 m.Goto(&end); 4363 m.Bind(&blocke); 4364 m.Goto(&end); 4365 m.Bind(&end); 4366 Node* dphi2 = m.Phi(MachineRepresentation::kFloat64, d1, dphi1); 4367 Node* rphi2 = m.Phi(MachineRepresentation::kTagged, r1, rphi1); 4368 4369 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&dbuffer), 4370 m.Int32Constant(0), dphi2, kNoWriteBarrier); 4371 m.Store(MachineRepresentation::kTagged, m.PointerConstant(&rbuffer), 4372 m.Int32Constant(0), rphi2, kNoWriteBarrier); 4373 m.Return(m.Int32Constant(magic)); 4374 4375 CHECK_EQ(magic, m.Call()); 4376 CHECK_EQ(dconstant, dbuffer); 4377 CHECK(rexpected->SameValue(rbuffer)); 4378 } 4379 4380 4381 TEST(RunDoubleLoopPhi) { 4382 RawMachineAssemblerTester<int32_t> m; 4383 RawMachineLabel header, body, end; 4384 4385 int magic = 99773; 4386 double buffer = 0.99; 4387 double dconstant = 777.1; 4388 4389 Node* zero = m.Int32Constant(0); 4390 Node* dk = m.Float64Constant(dconstant); 4391 4392 m.Goto(&header); 4393 m.Bind(&header); 4394 Node* phi = m.Phi(MachineRepresentation::kFloat64, dk, dk); 4395 phi->ReplaceInput(1, phi); 4396 m.Branch(zero, &body, &end); 4397 m.Bind(&body); 4398 m.Goto(&header); 4399 m.Bind(&end); 4400 m.Store(MachineRepresentation::kFloat64, m.PointerConstant(&buffer), 4401 m.Int32Constant(0), phi, kNoWriteBarrier); 4402 m.Return(m.Int32Constant(magic)); 4403 4404 CHECK_EQ(magic, m.Call()); 4405 } 4406 4407 4408 TEST(RunCountToTenAccRaw) { 4409 RawMachineAssemblerTester<int32_t> m; 4410 4411 Node* zero = m.Int32Constant(0); 4412 Node* ten = m.Int32Constant(10); 4413 Node* one = m.Int32Constant(1); 4414 4415 RawMachineLabel header, body, body_cont, end; 4416 4417 m.Goto(&header); 4418 4419 m.Bind(&header); 4420 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero); 4421 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero); 4422 m.Goto(&body); 4423 4424 m.Bind(&body); 4425 Node* next_i = m.Int32Add(i, one); 4426 Node* next_j = m.Int32Add(j, one); 4427 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont); 4428 4429 m.Bind(&body_cont); 4430 i->ReplaceInput(1, next_i); 4431 j->ReplaceInput(1, next_j); 4432 m.Goto(&header); 4433 4434 m.Bind(&end); 4435 m.Return(ten); 4436 4437 CHECK_EQ(10, m.Call()); 4438 } 4439 4440 4441 TEST(RunCountToTenAccRaw2) { 4442 RawMachineAssemblerTester<int32_t> m; 4443 4444 Node* zero = m.Int32Constant(0); 4445 Node* ten = m.Int32Constant(10); 4446 Node* one = m.Int32Constant(1); 4447 4448 RawMachineLabel header, body, body_cont, end; 4449 4450 m.Goto(&header); 4451 4452 m.Bind(&header); 4453 Node* i = m.Phi(MachineRepresentation::kWord32, zero, zero); 4454 Node* j = m.Phi(MachineRepresentation::kWord32, zero, zero); 4455 Node* k = m.Phi(MachineRepresentation::kWord32, zero, zero); 4456 m.Goto(&body); 4457 4458 m.Bind(&body); 4459 Node* next_i = m.Int32Add(i, one); 4460 Node* next_j = m.Int32Add(j, one); 4461 Node* next_k = m.Int32Add(j, one); 4462 m.Branch(m.Word32Equal(next_i, ten), &end, &body_cont); 4463 4464 m.Bind(&body_cont); 4465 i->ReplaceInput(1, next_i); 4466 j->ReplaceInput(1, next_j); 4467 k->ReplaceInput(1, next_k); 4468 m.Goto(&header); 4469 4470 m.Bind(&end); 4471 m.Return(ten); 4472 4473 CHECK_EQ(10, m.Call()); 4474 } 4475 4476 4477 TEST(RunAddTree) { 4478 RawMachineAssemblerTester<int32_t> m; 4479 int32_t inputs[] = {11, 12, 13, 14, 15, 16, 17, 18}; 4480 4481 Node* base = m.PointerConstant(inputs); 4482 Node* n0 = 4483 m.Load(MachineType::Int32(), base, m.Int32Constant(0 * sizeof(int32_t))); 4484 Node* n1 = 4485 m.Load(MachineType::Int32(), base, m.Int32Constant(1 * sizeof(int32_t))); 4486 Node* n2 = 4487 m.Load(MachineType::Int32(), base, m.Int32Constant(2 * sizeof(int32_t))); 4488 Node* n3 = 4489 m.Load(MachineType::Int32(), base, m.Int32Constant(3 * sizeof(int32_t))); 4490 Node* n4 = 4491 m.Load(MachineType::Int32(), base, m.Int32Constant(4 * sizeof(int32_t))); 4492 Node* n5 = 4493 m.Load(MachineType::Int32(), base, m.Int32Constant(5 * sizeof(int32_t))); 4494 Node* n6 = 4495 m.Load(MachineType::Int32(), base, m.Int32Constant(6 * sizeof(int32_t))); 4496 Node* n7 = 4497 m.Load(MachineType::Int32(), base, m.Int32Constant(7 * sizeof(int32_t))); 4498 4499 Node* i1 = m.Int32Add(n0, n1); 4500 Node* i2 = m.Int32Add(n2, n3); 4501 Node* i3 = m.Int32Add(n4, n5); 4502 Node* i4 = m.Int32Add(n6, n7); 4503 4504 Node* i5 = m.Int32Add(i1, i2); 4505 Node* i6 = m.Int32Add(i3, i4); 4506 4507 Node* i7 = m.Int32Add(i5, i6); 4508 4509 m.Return(i7); 4510 4511 CHECK_EQ(116, m.Call()); 4512 } 4513 4514 4515 static const int kFloat64CompareHelperTestCases = 15; 4516 static const int kFloat64CompareHelperNodeType = 4; 4517 4518 static int Float64CompareHelper(RawMachineAssemblerTester<int32_t>* m, 4519 int test_case, int node_type, double x, 4520 double y) { 4521 static double buffer[2]; 4522 buffer[0] = x; 4523 buffer[1] = y; 4524 CHECK(0 <= test_case && test_case < kFloat64CompareHelperTestCases); 4525 CHECK(0 <= node_type && node_type < kFloat64CompareHelperNodeType); 4526 CHECK(x < y); 4527 bool load_a = node_type / 2 == 1; 4528 bool load_b = node_type % 2 == 1; 4529 Node* a = 4530 load_a ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[0])) 4531 : m->Float64Constant(x); 4532 Node* b = 4533 load_b ? m->Load(MachineType::Float64(), m->PointerConstant(&buffer[1])) 4534 : m->Float64Constant(y); 4535 Node* cmp = NULL; 4536 bool expected = false; 4537 switch (test_case) { 4538 // Equal tests. 4539 case 0: 4540 cmp = m->Float64Equal(a, b); 4541 expected = false; 4542 break; 4543 case 1: 4544 cmp = m->Float64Equal(a, a); 4545 expected = true; 4546 break; 4547 // LessThan tests. 4548 case 2: 4549 cmp = m->Float64LessThan(a, b); 4550 expected = true; 4551 break; 4552 case 3: 4553 cmp = m->Float64LessThan(b, a); 4554 expected = false; 4555 break; 4556 case 4: 4557 cmp = m->Float64LessThan(a, a); 4558 expected = false; 4559 break; 4560 // LessThanOrEqual tests. 4561 case 5: 4562 cmp = m->Float64LessThanOrEqual(a, b); 4563 expected = true; 4564 break; 4565 case 6: 4566 cmp = m->Float64LessThanOrEqual(b, a); 4567 expected = false; 4568 break; 4569 case 7: 4570 cmp = m->Float64LessThanOrEqual(a, a); 4571 expected = true; 4572 break; 4573 // NotEqual tests. 4574 case 8: 4575 cmp = m->Float64NotEqual(a, b); 4576 expected = true; 4577 break; 4578 case 9: 4579 cmp = m->Float64NotEqual(b, a); 4580 expected = true; 4581 break; 4582 case 10: 4583 cmp = m->Float64NotEqual(a, a); 4584 expected = false; 4585 break; 4586 // GreaterThan tests. 4587 case 11: 4588 cmp = m->Float64GreaterThan(a, a); 4589 expected = false; 4590 break; 4591 case 12: 4592 cmp = m->Float64GreaterThan(a, b); 4593 expected = false; 4594 break; 4595 // GreaterThanOrEqual tests. 4596 case 13: 4597 cmp = m->Float64GreaterThanOrEqual(a, a); 4598 expected = true; 4599 break; 4600 case 14: 4601 cmp = m->Float64GreaterThanOrEqual(b, a); 4602 expected = true; 4603 break; 4604 default: 4605 UNREACHABLE(); 4606 } 4607 m->Return(cmp); 4608 return expected; 4609 } 4610 4611 4612 TEST(RunFloat64Compare) { 4613 double inf = V8_INFINITY; 4614 // All pairs (a1, a2) are of the form a1 < a2. 4615 double inputs[] = {0.0, 1.0, -1.0, 0.22, -1.22, 0.22, 4616 -inf, 0.22, 0.22, inf, -inf, inf}; 4617 4618 for (int test = 0; test < kFloat64CompareHelperTestCases; test++) { 4619 for (int node_type = 0; node_type < kFloat64CompareHelperNodeType; 4620 node_type++) { 4621 for (size_t input = 0; input < arraysize(inputs); input += 2) { 4622 RawMachineAssemblerTester<int32_t> m; 4623 int expected = Float64CompareHelper(&m, test, node_type, inputs[input], 4624 inputs[input + 1]); 4625 CHECK_EQ(expected, m.Call()); 4626 } 4627 } 4628 } 4629 } 4630 4631 4632 TEST(RunFloat64UnorderedCompare) { 4633 RawMachineAssemblerTester<int32_t> m; 4634 4635 const Operator* operators[] = {m.machine()->Float64Equal(), 4636 m.machine()->Float64LessThan(), 4637 m.machine()->Float64LessThanOrEqual()}; 4638 4639 double nan = std::numeric_limits<double>::quiet_NaN(); 4640 4641 FOR_FLOAT64_INPUTS(i) { 4642 for (size_t o = 0; o < arraysize(operators); ++o) { 4643 for (int j = 0; j < 2; j++) { 4644 RawMachineAssemblerTester<int32_t> m; 4645 Node* a = m.Float64Constant(*i); 4646 Node* b = m.Float64Constant(nan); 4647 if (j == 1) std::swap(a, b); 4648 m.Return(m.AddNode(operators[o], a, b)); 4649 CHECK_EQ(0, m.Call()); 4650 } 4651 } 4652 } 4653 } 4654 4655 4656 TEST(RunFloat64Equal) { 4657 double input_a = 0.0; 4658 double input_b = 0.0; 4659 4660 RawMachineAssemblerTester<int32_t> m; 4661 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64()); 4662 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64()); 4663 m.Return(m.Float64Equal(a, b)); 4664 4665 CompareWrapper cmp(IrOpcode::kFloat64Equal); 4666 FOR_FLOAT64_INPUTS(pl) { 4667 FOR_FLOAT64_INPUTS(pr) { 4668 input_a = *pl; 4669 input_b = *pr; 4670 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0; 4671 CHECK_EQ(expected, m.Call()); 4672 } 4673 } 4674 } 4675 4676 4677 TEST(RunFloat64LessThan) { 4678 double input_a = 0.0; 4679 double input_b = 0.0; 4680 4681 RawMachineAssemblerTester<int32_t> m; 4682 Node* a = m.LoadFromPointer(&input_a, MachineType::Float64()); 4683 Node* b = m.LoadFromPointer(&input_b, MachineType::Float64()); 4684 m.Return(m.Float64LessThan(a, b)); 4685 4686 CompareWrapper cmp(IrOpcode::kFloat64LessThan); 4687 FOR_FLOAT64_INPUTS(pl) { 4688 FOR_FLOAT64_INPUTS(pr) { 4689 input_a = *pl; 4690 input_b = *pr; 4691 int32_t expected = cmp.Float64Compare(input_a, input_b) ? 1 : 0; 4692 CHECK_EQ(expected, m.Call()); 4693 } 4694 } 4695 } 4696 4697 4698 template <typename IntType> 4699 static void LoadStoreTruncation(MachineType kRepresentation) { 4700 IntType input; 4701 4702 RawMachineAssemblerTester<int32_t> m; 4703 Node* a = m.LoadFromPointer(&input, kRepresentation); 4704 Node* ap1 = m.Int32Add(a, m.Int32Constant(1)); 4705 m.StoreToPointer(&input, kRepresentation.representation(), ap1); 4706 m.Return(ap1); 4707 4708 const IntType max = std::numeric_limits<IntType>::max(); 4709 const IntType min = std::numeric_limits<IntType>::min(); 4710 4711 // Test upper bound. 4712 input = max; 4713 CHECK_EQ(max + 1, m.Call()); 4714 CHECK_EQ(min, input); 4715 4716 // Test lower bound. 4717 input = min; 4718 CHECK_EQ(static_cast<IntType>(max + 2), m.Call()); 4719 CHECK_EQ(min + 1, input); 4720 4721 // Test all one byte values that are not one byte bounds. 4722 for (int i = -127; i < 127; i++) { 4723 input = i; 4724 int expected = i >= 0 ? i + 1 : max + (i - min) + 2; 4725 CHECK_EQ(static_cast<IntType>(expected), m.Call()); 4726 CHECK_EQ(static_cast<IntType>(i + 1), input); 4727 } 4728 } 4729 4730 4731 TEST(RunLoadStoreTruncation) { 4732 LoadStoreTruncation<int8_t>(MachineType::Int8()); 4733 LoadStoreTruncation<int16_t>(MachineType::Int16()); 4734 } 4735 4736 4737 static void IntPtrCompare(intptr_t left, intptr_t right) { 4738 for (int test = 0; test < 7; test++) { 4739 RawMachineAssemblerTester<bool> m(MachineType::Pointer(), 4740 MachineType::Pointer()); 4741 Node* p0 = m.Parameter(0); 4742 Node* p1 = m.Parameter(1); 4743 Node* res = NULL; 4744 bool expected = false; 4745 switch (test) { 4746 case 0: 4747 res = m.IntPtrLessThan(p0, p1); 4748 expected = true; 4749 break; 4750 case 1: 4751 res = m.IntPtrLessThanOrEqual(p0, p1); 4752 expected = true; 4753 break; 4754 case 2: 4755 res = m.IntPtrEqual(p0, p1); 4756 expected = false; 4757 break; 4758 case 3: 4759 res = m.IntPtrGreaterThanOrEqual(p0, p1); 4760 expected = false; 4761 break; 4762 case 4: 4763 res = m.IntPtrGreaterThan(p0, p1); 4764 expected = false; 4765 break; 4766 case 5: 4767 res = m.IntPtrEqual(p0, p0); 4768 expected = true; 4769 break; 4770 case 6: 4771 res = m.IntPtrNotEqual(p0, p1); 4772 expected = true; 4773 break; 4774 default: 4775 UNREACHABLE(); 4776 break; 4777 } 4778 m.Return(res); 4779 CHECK_EQ(expected, m.Call(reinterpret_cast<int32_t*>(left), 4780 reinterpret_cast<int32_t*>(right))); 4781 } 4782 } 4783 4784 4785 TEST(RunIntPtrCompare) { 4786 intptr_t min = std::numeric_limits<intptr_t>::min(); 4787 intptr_t max = std::numeric_limits<intptr_t>::max(); 4788 // An ascending chain of intptr_t 4789 intptr_t inputs[] = {min, min / 2, -1, 0, 1, max / 2, max}; 4790 for (size_t i = 0; i < arraysize(inputs) - 1; i++) { 4791 IntPtrCompare(inputs[i], inputs[i + 1]); 4792 } 4793 } 4794 4795 4796 TEST(RunTestIntPtrArithmetic) { 4797 static const int kInputSize = 10; 4798 int32_t inputs[kInputSize]; 4799 int32_t outputs[kInputSize]; 4800 for (int i = 0; i < kInputSize; i++) { 4801 inputs[i] = i; 4802 outputs[i] = -1; 4803 } 4804 RawMachineAssemblerTester<int32_t*> m; 4805 Node* input = m.PointerConstant(&inputs[0]); 4806 Node* output = m.PointerConstant(&outputs[kInputSize - 1]); 4807 Node* elem_size = m.IntPtrConstant(sizeof(inputs[0])); 4808 for (int i = 0; i < kInputSize; i++) { 4809 m.Store(MachineRepresentation::kWord32, output, 4810 m.Load(MachineType::Int32(), input), kNoWriteBarrier); 4811 input = m.IntPtrAdd(input, elem_size); 4812 output = m.IntPtrSub(output, elem_size); 4813 } 4814 m.Return(input); 4815 CHECK_EQ(&inputs[kInputSize], m.Call()); 4816 for (int i = 0; i < kInputSize; i++) { 4817 CHECK_EQ(i, inputs[i]); 4818 CHECK_EQ(kInputSize - i - 1, outputs[i]); 4819 } 4820 } 4821 4822 4823 TEST(RunSpillLotsOfThings) { 4824 static const int kInputSize = 1000; 4825 RawMachineAssemblerTester<int32_t> m; 4826 Node* accs[kInputSize]; 4827 int32_t outputs[kInputSize]; 4828 Node* one = m.Int32Constant(1); 4829 Node* acc = one; 4830 for (int i = 0; i < kInputSize; i++) { 4831 acc = m.Int32Add(acc, one); 4832 accs[i] = acc; 4833 } 4834 for (int i = 0; i < kInputSize; i++) { 4835 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]); 4836 } 4837 m.Return(one); 4838 m.Call(); 4839 for (int i = 0; i < kInputSize; i++) { 4840 CHECK_EQ(outputs[i], i + 2); 4841 } 4842 } 4843 4844 4845 TEST(RunSpillConstantsAndParameters) { 4846 static const int kInputSize = 1000; 4847 static const int32_t kBase = 987; 4848 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 4849 MachineType::Int32()); 4850 int32_t outputs[kInputSize]; 4851 Node* csts[kInputSize]; 4852 Node* accs[kInputSize]; 4853 Node* acc = m.Int32Constant(0); 4854 for (int i = 0; i < kInputSize; i++) { 4855 csts[i] = m.Int32Constant(static_cast<int32_t>(kBase + i)); 4856 } 4857 for (int i = 0; i < kInputSize; i++) { 4858 acc = m.Int32Add(acc, csts[i]); 4859 accs[i] = acc; 4860 } 4861 for (int i = 0; i < kInputSize; i++) { 4862 m.StoreToPointer(&outputs[i], MachineRepresentation::kWord32, accs[i]); 4863 } 4864 m.Return(m.Int32Add(acc, m.Int32Add(m.Parameter(0), m.Parameter(1)))); 4865 FOR_INT32_INPUTS(i) { 4866 FOR_INT32_INPUTS(j) { 4867 int32_t expected = *i + *j; 4868 for (int k = 0; k < kInputSize; k++) { 4869 expected += kBase + k; 4870 } 4871 CHECK_EQ(expected, m.Call(*i, *j)); 4872 expected = 0; 4873 for (int k = 0; k < kInputSize; k++) { 4874 expected += kBase + k; 4875 CHECK_EQ(expected, outputs[k]); 4876 } 4877 } 4878 } 4879 } 4880 4881 4882 TEST(RunNewSpaceConstantsInPhi) { 4883 RawMachineAssemblerTester<Object*> m(MachineType::Int32()); 4884 4885 Isolate* isolate = CcTest::i_isolate(); 4886 Handle<HeapNumber> true_val = isolate->factory()->NewHeapNumber(11.2); 4887 Handle<HeapNumber> false_val = isolate->factory()->NewHeapNumber(11.3); 4888 Node* true_node = m.HeapConstant(true_val); 4889 Node* false_node = m.HeapConstant(false_val); 4890 4891 RawMachineLabel blocka, blockb, end; 4892 m.Branch(m.Parameter(0), &blocka, &blockb); 4893 m.Bind(&blocka); 4894 m.Goto(&end); 4895 m.Bind(&blockb); 4896 m.Goto(&end); 4897 4898 m.Bind(&end); 4899 Node* phi = m.Phi(MachineRepresentation::kTagged, true_node, false_node); 4900 m.Return(phi); 4901 4902 CHECK_EQ(*false_val, m.Call(0)); 4903 CHECK_EQ(*true_val, m.Call(1)); 4904 } 4905 4906 4907 TEST(RunInt32AddWithOverflowP) { 4908 int32_t actual_val = -1; 4909 RawMachineAssemblerTester<int32_t> m; 4910 Int32BinopTester bt(&m); 4911 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); 4912 Node* val = m.Projection(0, add); 4913 Node* ovf = m.Projection(1, add); 4914 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 4915 bt.AddReturn(ovf); 4916 FOR_INT32_INPUTS(i) { 4917 FOR_INT32_INPUTS(j) { 4918 int32_t expected_val; 4919 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 4920 CHECK_EQ(expected_ovf, bt.call(*i, *j)); 4921 CHECK_EQ(expected_val, actual_val); 4922 } 4923 } 4924 } 4925 4926 4927 TEST(RunInt32AddWithOverflowImm) { 4928 int32_t actual_val = -1, expected_val = 0; 4929 FOR_INT32_INPUTS(i) { 4930 { 4931 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 4932 Node* add = m.Int32AddWithOverflow(m.Int32Constant(*i), m.Parameter(0)); 4933 Node* val = m.Projection(0, add); 4934 Node* ovf = m.Projection(1, add); 4935 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 4936 m.Return(ovf); 4937 FOR_INT32_INPUTS(j) { 4938 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 4939 CHECK_EQ(expected_ovf, m.Call(*j)); 4940 CHECK_EQ(expected_val, actual_val); 4941 } 4942 } 4943 { 4944 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 4945 Node* add = m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(*i)); 4946 Node* val = m.Projection(0, add); 4947 Node* ovf = m.Projection(1, add); 4948 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 4949 m.Return(ovf); 4950 FOR_INT32_INPUTS(j) { 4951 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 4952 CHECK_EQ(expected_ovf, m.Call(*j)); 4953 CHECK_EQ(expected_val, actual_val); 4954 } 4955 } 4956 FOR_INT32_INPUTS(j) { 4957 RawMachineAssemblerTester<int32_t> m; 4958 Node* add = 4959 m.Int32AddWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); 4960 Node* val = m.Projection(0, add); 4961 Node* ovf = m.Projection(1, add); 4962 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 4963 m.Return(ovf); 4964 int expected_ovf = bits::SignedAddOverflow32(*i, *j, &expected_val); 4965 CHECK_EQ(expected_ovf, m.Call()); 4966 CHECK_EQ(expected_val, actual_val); 4967 } 4968 } 4969 } 4970 4971 4972 TEST(RunInt32AddWithOverflowInBranchP) { 4973 int constant = 911777; 4974 RawMachineLabel blocka, blockb; 4975 RawMachineAssemblerTester<int32_t> m; 4976 Int32BinopTester bt(&m); 4977 Node* add = m.Int32AddWithOverflow(bt.param0, bt.param1); 4978 Node* ovf = m.Projection(1, add); 4979 m.Branch(ovf, &blocka, &blockb); 4980 m.Bind(&blocka); 4981 bt.AddReturn(m.Int32Constant(constant)); 4982 m.Bind(&blockb); 4983 Node* val = m.Projection(0, add); 4984 bt.AddReturn(val); 4985 FOR_INT32_INPUTS(i) { 4986 FOR_INT32_INPUTS(j) { 4987 int32_t expected; 4988 if (bits::SignedAddOverflow32(*i, *j, &expected)) expected = constant; 4989 CHECK_EQ(expected, bt.call(*i, *j)); 4990 } 4991 } 4992 } 4993 4994 4995 TEST(RunInt32SubWithOverflowP) { 4996 int32_t actual_val = -1; 4997 RawMachineAssemblerTester<int32_t> m; 4998 Int32BinopTester bt(&m); 4999 Node* add = m.Int32SubWithOverflow(bt.param0, bt.param1); 5000 Node* val = m.Projection(0, add); 5001 Node* ovf = m.Projection(1, add); 5002 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 5003 bt.AddReturn(ovf); 5004 FOR_INT32_INPUTS(i) { 5005 FOR_INT32_INPUTS(j) { 5006 int32_t expected_val; 5007 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); 5008 CHECK_EQ(expected_ovf, bt.call(*i, *j)); 5009 CHECK_EQ(expected_val, actual_val); 5010 } 5011 } 5012 } 5013 5014 5015 TEST(RunInt32SubWithOverflowImm) { 5016 int32_t actual_val = -1, expected_val = 0; 5017 FOR_INT32_INPUTS(i) { 5018 { 5019 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 5020 Node* add = m.Int32SubWithOverflow(m.Int32Constant(*i), m.Parameter(0)); 5021 Node* val = m.Projection(0, add); 5022 Node* ovf = m.Projection(1, add); 5023 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 5024 m.Return(ovf); 5025 FOR_INT32_INPUTS(j) { 5026 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); 5027 CHECK_EQ(expected_ovf, m.Call(*j)); 5028 CHECK_EQ(expected_val, actual_val); 5029 } 5030 } 5031 { 5032 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 5033 Node* add = m.Int32SubWithOverflow(m.Parameter(0), m.Int32Constant(*i)); 5034 Node* val = m.Projection(0, add); 5035 Node* ovf = m.Projection(1, add); 5036 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 5037 m.Return(ovf); 5038 FOR_INT32_INPUTS(j) { 5039 int expected_ovf = bits::SignedSubOverflow32(*j, *i, &expected_val); 5040 CHECK_EQ(expected_ovf, m.Call(*j)); 5041 CHECK_EQ(expected_val, actual_val); 5042 } 5043 } 5044 FOR_INT32_INPUTS(j) { 5045 RawMachineAssemblerTester<int32_t> m; 5046 Node* add = 5047 m.Int32SubWithOverflow(m.Int32Constant(*i), m.Int32Constant(*j)); 5048 Node* val = m.Projection(0, add); 5049 Node* ovf = m.Projection(1, add); 5050 m.StoreToPointer(&actual_val, MachineRepresentation::kWord32, val); 5051 m.Return(ovf); 5052 int expected_ovf = bits::SignedSubOverflow32(*i, *j, &expected_val); 5053 CHECK_EQ(expected_ovf, m.Call()); 5054 CHECK_EQ(expected_val, actual_val); 5055 } 5056 } 5057 } 5058 5059 5060 TEST(RunInt32SubWithOverflowInBranchP) { 5061 int constant = 911999; 5062 RawMachineLabel blocka, blockb; 5063 RawMachineAssemblerTester<int32_t> m; 5064 Int32BinopTester bt(&m); 5065 Node* sub = m.Int32SubWithOverflow(bt.param0, bt.param1); 5066 Node* ovf = m.Projection(1, sub); 5067 m.Branch(ovf, &blocka, &blockb); 5068 m.Bind(&blocka); 5069 bt.AddReturn(m.Int32Constant(constant)); 5070 m.Bind(&blockb); 5071 Node* val = m.Projection(0, sub); 5072 bt.AddReturn(val); 5073 FOR_INT32_INPUTS(i) { 5074 FOR_INT32_INPUTS(j) { 5075 int32_t expected; 5076 if (bits::SignedSubOverflow32(*i, *j, &expected)) expected = constant; 5077 CHECK_EQ(expected, bt.call(*i, *j)); 5078 } 5079 } 5080 } 5081 5082 5083 TEST(RunWord64EqualInBranchP) { 5084 int64_t input; 5085 RawMachineLabel blocka, blockb; 5086 RawMachineAssemblerTester<int64_t> m; 5087 if (!m.machine()->Is64()) return; 5088 Node* value = m.LoadFromPointer(&input, MachineType::Int64()); 5089 m.Branch(m.Word64Equal(value, m.Int64Constant(0)), &blocka, &blockb); 5090 m.Bind(&blocka); 5091 m.Return(m.Int32Constant(1)); 5092 m.Bind(&blockb); 5093 m.Return(m.Int32Constant(2)); 5094 input = V8_INT64_C(0); 5095 CHECK_EQ(1, m.Call()); 5096 input = V8_INT64_C(1); 5097 CHECK_EQ(2, m.Call()); 5098 input = V8_INT64_C(0x100000000); 5099 CHECK_EQ(2, m.Call()); 5100 } 5101 5102 5103 TEST(RunChangeInt32ToInt64P) { 5104 if (kPointerSize < 8) return; 5105 int64_t actual = -1; 5106 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 5107 m.StoreToPointer(&actual, MachineRepresentation::kWord64, 5108 m.ChangeInt32ToInt64(m.Parameter(0))); 5109 m.Return(m.Int32Constant(0)); 5110 FOR_INT32_INPUTS(i) { 5111 int64_t expected = *i; 5112 CHECK_EQ(0, m.Call(*i)); 5113 CHECK_EQ(expected, actual); 5114 } 5115 } 5116 5117 5118 TEST(RunChangeUint32ToUint64P) { 5119 if (kPointerSize < 8) return; 5120 int64_t actual = -1; 5121 RawMachineAssemblerTester<int32_t> m(MachineType::Uint32()); 5122 m.StoreToPointer(&actual, MachineRepresentation::kWord64, 5123 m.ChangeUint32ToUint64(m.Parameter(0))); 5124 m.Return(m.Int32Constant(0)); 5125 FOR_UINT32_INPUTS(i) { 5126 int64_t expected = static_cast<uint64_t>(*i); 5127 CHECK_EQ(0, m.Call(*i)); 5128 CHECK_EQ(expected, actual); 5129 } 5130 } 5131 5132 5133 TEST(RunTruncateInt64ToInt32P) { 5134 if (kPointerSize < 8) return; 5135 int64_t expected = -1; 5136 RawMachineAssemblerTester<int32_t> m; 5137 m.Return(m.TruncateInt64ToInt32( 5138 m.LoadFromPointer(&expected, MachineType::Int64()))); 5139 FOR_UINT32_INPUTS(i) { 5140 FOR_UINT32_INPUTS(j) { 5141 expected = (static_cast<uint64_t>(*j) << 32) | *i; 5142 CHECK_EQ(static_cast<int32_t>(expected), m.Call()); 5143 } 5144 } 5145 } 5146 5147 5148 TEST(RunTruncateFloat64ToInt32P) { 5149 struct { 5150 double from; 5151 double raw; 5152 } kValues[] = {{0, 0}, 5153 {0.5, 0}, 5154 {-0.5, 0}, 5155 {1.5, 1}, 5156 {-1.5, -1}, 5157 {5.5, 5}, 5158 {-5.0, -5}, 5159 {std::numeric_limits<double>::quiet_NaN(), 0}, 5160 {std::numeric_limits<double>::infinity(), 0}, 5161 {-std::numeric_limits<double>::quiet_NaN(), 0}, 5162 {-std::numeric_limits<double>::infinity(), 0}, 5163 {4.94065645841e-324, 0}, 5164 {-4.94065645841e-324, 0}, 5165 {0.9999999999999999, 0}, 5166 {-0.9999999999999999, 0}, 5167 {4294967296.0, 0}, 5168 {-4294967296.0, 0}, 5169 {9223372036854775000.0, 4294966272.0}, 5170 {-9223372036854775000.0, -4294966272.0}, 5171 {4.5036e+15, 372629504}, 5172 {-4.5036e+15, -372629504}, 5173 {287524199.5377777, 0x11234567}, 5174 {-287524199.5377777, -0x11234567}, 5175 {2300193596.302222, 2300193596.0}, 5176 {-2300193596.302222, -2300193596.0}, 5177 {4600387192.604444, 305419896}, 5178 {-4600387192.604444, -305419896}, 5179 {4823855600872397.0, 1737075661}, 5180 {-4823855600872397.0, -1737075661}, 5181 {4503603922337791.0, -1}, 5182 {-4503603922337791.0, 1}, 5183 {4503601774854143.0, 2147483647}, 5184 {-4503601774854143.0, -2147483647}, 5185 {9007207844675582.0, -2}, 5186 {-9007207844675582.0, 2}, 5187 {2.4178527921507624e+24, -536870912}, 5188 {-2.4178527921507624e+24, 536870912}, 5189 {2.417853945072267e+24, -536870912}, 5190 {-2.417853945072267e+24, 536870912}, 5191 {4.8357055843015248e+24, -1073741824}, 5192 {-4.8357055843015248e+24, 1073741824}, 5193 {4.8357078901445341e+24, -1073741824}, 5194 {-4.8357078901445341e+24, 1073741824}, 5195 {2147483647.0, 2147483647.0}, 5196 {-2147483648.0, -2147483648.0}, 5197 {9.6714111686030497e+24, -2147483648.0}, 5198 {-9.6714111686030497e+24, -2147483648.0}, 5199 {9.6714157802890681e+24, -2147483648.0}, 5200 {-9.6714157802890681e+24, -2147483648.0}, 5201 {1.9342813113834065e+25, 2147483648.0}, 5202 {-1.9342813113834065e+25, 2147483648.0}, 5203 {3.868562622766813e+25, 0}, 5204 {-3.868562622766813e+25, 0}, 5205 {1.7976931348623157e+308, 0}, 5206 {-1.7976931348623157e+308, 0}}; 5207 double input = -1.0; 5208 RawMachineAssemblerTester<int32_t> m; 5209 m.Return(m.TruncateFloat64ToInt32( 5210 TruncationMode::kJavaScript, 5211 m.LoadFromPointer(&input, MachineType::Float64()))); 5212 for (size_t i = 0; i < arraysize(kValues); ++i) { 5213 input = kValues[i].from; 5214 uint64_t expected = static_cast<int64_t>(kValues[i].raw); 5215 CHECK_EQ(static_cast<int>(expected), m.Call()); 5216 } 5217 } 5218 5219 5220 TEST(RunChangeFloat32ToFloat64) { 5221 BufferedRawMachineAssemblerTester<double> m(MachineType::Float32()); 5222 5223 m.Return(m.ChangeFloat32ToFloat64(m.Parameter(0))); 5224 5225 FOR_FLOAT32_INPUTS(i) { CheckDoubleEq(static_cast<double>(*i), m.Call(*i)); } 5226 } 5227 5228 5229 TEST(RunFloat32Constant) { 5230 FOR_FLOAT32_INPUTS(i) { 5231 BufferedRawMachineAssemblerTester<float> m; 5232 m.Return(m.Float32Constant(*i)); 5233 CheckFloatEq(*i, m.Call()); 5234 } 5235 } 5236 5237 5238 TEST(RunFloat64ExtractLowWord32) { 5239 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64()); 5240 m.Return(m.Float64ExtractLowWord32(m.Parameter(0))); 5241 FOR_FLOAT64_INPUTS(i) { 5242 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i)); 5243 CHECK_EQ(expected, m.Call(*i)); 5244 } 5245 } 5246 5247 5248 TEST(RunFloat64ExtractHighWord32) { 5249 BufferedRawMachineAssemblerTester<uint32_t> m(MachineType::Float64()); 5250 m.Return(m.Float64ExtractHighWord32(m.Parameter(0))); 5251 FOR_FLOAT64_INPUTS(i) { 5252 uint32_t expected = static_cast<uint32_t>(bit_cast<uint64_t>(*i) >> 32); 5253 CHECK_EQ(expected, m.Call(*i)); 5254 } 5255 } 5256 5257 5258 TEST(RunFloat64InsertLowWord32) { 5259 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 5260 MachineType::Int32()); 5261 m.Return(m.Float64InsertLowWord32(m.Parameter(0), m.Parameter(1))); 5262 FOR_FLOAT64_INPUTS(i) { 5263 FOR_INT32_INPUTS(j) { 5264 double expected = bit_cast<double>( 5265 (bit_cast<uint64_t>(*i) & ~(V8_UINT64_C(0xFFFFFFFF))) | 5266 (static_cast<uint64_t>(bit_cast<uint32_t>(*j)))); 5267 CheckDoubleEq(expected, m.Call(*i, *j)); 5268 } 5269 } 5270 } 5271 5272 5273 TEST(RunFloat64InsertHighWord32) { 5274 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64(), 5275 MachineType::Uint32()); 5276 m.Return(m.Float64InsertHighWord32(m.Parameter(0), m.Parameter(1))); 5277 FOR_FLOAT64_INPUTS(i) { 5278 FOR_UINT32_INPUTS(j) { 5279 uint64_t expected = (bit_cast<uint64_t>(*i) & 0xFFFFFFFF) | 5280 (static_cast<uint64_t>(*j) << 32); 5281 5282 CheckDoubleEq(bit_cast<double>(expected), m.Call(*i, *j)); 5283 } 5284 } 5285 } 5286 5287 5288 TEST(RunFloat32Abs) { 5289 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 5290 m.Return(m.Float32Abs(m.Parameter(0))); 5291 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(std::abs(*i), m.Call(*i)); } 5292 } 5293 5294 5295 TEST(RunFloat64Abs) { 5296 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5297 m.Return(m.Float64Abs(m.Parameter(0))); 5298 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(std::abs(*i), m.Call(*i)); } 5299 } 5300 5301 5302 static double two_30 = 1 << 30; // 2^30 is a smi boundary. 5303 static double two_52 = two_30 * (1 << 22); // 2^52 is a precision boundary. 5304 static double kValues[] = {0.1, 5305 0.2, 5306 0.49999999999999994, 5307 0.5, 5308 0.7, 5309 1.0 - std::numeric_limits<double>::epsilon(), 5310 -0.1, 5311 -0.49999999999999994, 5312 -0.5, 5313 -0.7, 5314 1.1, 5315 1.0 + std::numeric_limits<double>::epsilon(), 5316 1.5, 5317 1.7, 5318 -1, 5319 -1 + std::numeric_limits<double>::epsilon(), 5320 -1 - std::numeric_limits<double>::epsilon(), 5321 -1.1, 5322 -1.5, 5323 -1.7, 5324 std::numeric_limits<double>::min(), 5325 -std::numeric_limits<double>::min(), 5326 std::numeric_limits<double>::max(), 5327 -std::numeric_limits<double>::max(), 5328 std::numeric_limits<double>::infinity(), 5329 -std::numeric_limits<double>::infinity(), 5330 two_30, 5331 two_30 + 0.1, 5332 two_30 + 0.5, 5333 two_30 + 0.7, 5334 two_30 - 1, 5335 two_30 - 1 + 0.1, 5336 two_30 - 1 + 0.5, 5337 two_30 - 1 + 0.7, 5338 -two_30, 5339 -two_30 + 0.1, 5340 -two_30 + 0.5, 5341 -two_30 + 0.7, 5342 -two_30 + 1, 5343 -two_30 + 1 + 0.1, 5344 -two_30 + 1 + 0.5, 5345 -two_30 + 1 + 0.7, 5346 two_52, 5347 two_52 + 0.1, 5348 two_52 + 0.5, 5349 two_52 + 0.5, 5350 two_52 + 0.7, 5351 two_52 + 0.7, 5352 two_52 - 1, 5353 two_52 - 1 + 0.1, 5354 two_52 - 1 + 0.5, 5355 two_52 - 1 + 0.7, 5356 -two_52, 5357 -two_52 + 0.1, 5358 -two_52 + 0.5, 5359 -two_52 + 0.7, 5360 -two_52 + 1, 5361 -two_52 + 1 + 0.1, 5362 -two_52 + 1 + 0.5, 5363 -two_52 + 1 + 0.7, 5364 two_30, 5365 two_30 - 0.1, 5366 two_30 - 0.5, 5367 two_30 - 0.7, 5368 two_30 - 1, 5369 two_30 - 1 - 0.1, 5370 two_30 - 1 - 0.5, 5371 two_30 - 1 - 0.7, 5372 -two_30, 5373 -two_30 - 0.1, 5374 -two_30 - 0.5, 5375 -two_30 - 0.7, 5376 -two_30 + 1, 5377 -two_30 + 1 - 0.1, 5378 -two_30 + 1 - 0.5, 5379 -two_30 + 1 - 0.7, 5380 two_52, 5381 two_52 - 0.1, 5382 two_52 - 0.5, 5383 two_52 - 0.5, 5384 two_52 - 0.7, 5385 two_52 - 0.7, 5386 two_52 - 1, 5387 two_52 - 1 - 0.1, 5388 two_52 - 1 - 0.5, 5389 two_52 - 1 - 0.7, 5390 -two_52, 5391 -two_52 - 0.1, 5392 -two_52 - 0.5, 5393 -two_52 - 0.7, 5394 -two_52 + 1, 5395 -two_52 + 1 - 0.1, 5396 -two_52 + 1 - 0.5, 5397 -two_52 + 1 - 0.7}; 5398 5399 5400 TEST(RunFloat32RoundDown) { 5401 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 5402 if (!m.machine()->Float32RoundDown().IsSupported()) return; 5403 5404 m.Return(m.Float32RoundDown(m.Parameter(0))); 5405 5406 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(floorf(*i), m.Call(*i)); } 5407 } 5408 5409 5410 TEST(RunFloat64RoundDown1) { 5411 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5412 if (!m.machine()->Float64RoundDown().IsSupported()) return; 5413 5414 m.Return(m.Float64RoundDown(m.Parameter(0))); 5415 5416 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(floor(*i), m.Call(*i)); } 5417 } 5418 5419 5420 TEST(RunFloat64RoundDown2) { 5421 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5422 if (!m.machine()->Float64RoundDown().IsSupported()) return; 5423 m.Return(m.Float64Sub(m.Float64Constant(-0.0), 5424 m.Float64RoundDown(m.Float64Sub(m.Float64Constant(-0.0), 5425 m.Parameter(0))))); 5426 5427 for (size_t i = 0; i < arraysize(kValues); ++i) { 5428 CHECK_EQ(ceil(kValues[i]), m.Call(kValues[i])); 5429 } 5430 } 5431 5432 5433 TEST(RunFloat32RoundUp) { 5434 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 5435 if (!m.machine()->Float32RoundUp().IsSupported()) return; 5436 m.Return(m.Float32RoundUp(m.Parameter(0))); 5437 5438 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(ceilf(*i), m.Call(*i)); } 5439 } 5440 5441 5442 TEST(RunFloat64RoundUp) { 5443 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5444 if (!m.machine()->Float64RoundUp().IsSupported()) return; 5445 m.Return(m.Float64RoundUp(m.Parameter(0))); 5446 5447 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(ceil(*i), m.Call(*i)); } 5448 } 5449 5450 5451 TEST(RunFloat32RoundTiesEven) { 5452 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 5453 if (!m.machine()->Float32RoundTiesEven().IsSupported()) return; 5454 m.Return(m.Float32RoundTiesEven(m.Parameter(0))); 5455 5456 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(nearbyint(*i), m.Call(*i)); } 5457 } 5458 5459 5460 TEST(RunFloat64RoundTiesEven) { 5461 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5462 if (!m.machine()->Float64RoundTiesEven().IsSupported()) return; 5463 m.Return(m.Float64RoundTiesEven(m.Parameter(0))); 5464 5465 FOR_FLOAT64_INPUTS(i) { CheckDoubleEq(nearbyint(*i), m.Call(*i)); } 5466 } 5467 5468 5469 TEST(RunFloat32RoundTruncate) { 5470 BufferedRawMachineAssemblerTester<float> m(MachineType::Float32()); 5471 if (!m.machine()->Float32RoundTruncate().IsSupported()) return; 5472 5473 m.Return(m.Float32RoundTruncate(m.Parameter(0))); 5474 5475 FOR_FLOAT32_INPUTS(i) { CheckFloatEq(truncf(*i), m.Call(*i)); } 5476 } 5477 5478 5479 TEST(RunFloat64RoundTruncate) { 5480 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5481 if (!m.machine()->Float64RoundTruncate().IsSupported()) return; 5482 m.Return(m.Float64RoundTruncate(m.Parameter(0))); 5483 for (size_t i = 0; i < arraysize(kValues); ++i) { 5484 CHECK_EQ(trunc(kValues[i]), m.Call(kValues[i])); 5485 } 5486 } 5487 5488 5489 TEST(RunFloat64RoundTiesAway) { 5490 BufferedRawMachineAssemblerTester<double> m(MachineType::Float64()); 5491 if (!m.machine()->Float64RoundTiesAway().IsSupported()) return; 5492 m.Return(m.Float64RoundTiesAway(m.Parameter(0))); 5493 for (size_t i = 0; i < arraysize(kValues); ++i) { 5494 CHECK_EQ(round(kValues[i]), m.Call(kValues[i])); 5495 } 5496 } 5497 5498 5499 #if !USE_SIMULATOR 5500 5501 namespace { 5502 5503 int32_t const kMagicFoo0 = 0xdeadbeef; 5504 5505 5506 int32_t foo0() { return kMagicFoo0; } 5507 5508 5509 int32_t foo1(int32_t x) { return x; } 5510 5511 5512 int32_t foo2(int32_t x, int32_t y) { return x - y; } 5513 5514 5515 int32_t foo8(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f, 5516 int32_t g, int32_t h) { 5517 return a + b + c + d + e + f + g + h; 5518 } 5519 5520 } // namespace 5521 5522 5523 TEST(RunCallCFunction0) { 5524 auto* foo0_ptr = &foo0; 5525 RawMachineAssemblerTester<int32_t> m; 5526 Node* function = m.LoadFromPointer(&foo0_ptr, MachineType::Pointer()); 5527 m.Return(m.CallCFunction0(MachineType::Int32(), function)); 5528 CHECK_EQ(kMagicFoo0, m.Call()); 5529 } 5530 5531 5532 TEST(RunCallCFunction1) { 5533 auto* foo1_ptr = &foo1; 5534 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 5535 Node* function = m.LoadFromPointer(&foo1_ptr, MachineType::Pointer()); 5536 m.Return(m.CallCFunction1(MachineType::Int32(), MachineType::Int32(), 5537 function, m.Parameter(0))); 5538 FOR_INT32_INPUTS(i) { 5539 int32_t const expected = *i; 5540 CHECK_EQ(expected, m.Call(expected)); 5541 } 5542 } 5543 5544 5545 TEST(RunCallCFunction2) { 5546 auto* foo2_ptr = &foo2; 5547 RawMachineAssemblerTester<int32_t> m(MachineType::Int32(), 5548 MachineType::Int32()); 5549 Node* function = m.LoadFromPointer(&foo2_ptr, MachineType::Pointer()); 5550 m.Return(m.CallCFunction2(MachineType::Int32(), MachineType::Int32(), 5551 MachineType::Int32(), function, m.Parameter(0), 5552 m.Parameter(1))); 5553 FOR_INT32_INPUTS(i) { 5554 int32_t const x = *i; 5555 FOR_INT32_INPUTS(j) { 5556 int32_t const y = *j; 5557 CHECK_EQ(x - y, m.Call(x, y)); 5558 } 5559 } 5560 } 5561 5562 5563 TEST(RunCallCFunction8) { 5564 auto* foo8_ptr = &foo8; 5565 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 5566 Node* function = m.LoadFromPointer(&foo8_ptr, MachineType::Pointer()); 5567 Node* param = m.Parameter(0); 5568 m.Return(m.CallCFunction8( 5569 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 5570 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 5571 MachineType::Int32(), MachineType::Int32(), MachineType::Int32(), 5572 function, param, param, param, param, param, param, param, param)); 5573 FOR_INT32_INPUTS(i) { 5574 int32_t const x = *i; 5575 CHECK_EQ(x * 8, m.Call(x)); 5576 } 5577 } 5578 #endif // USE_SIMULATOR 5579 5580 #if V8_TARGET_ARCH_64_BIT 5581 // TODO(titzer): run int64 tests on all platforms when supported. 5582 TEST(RunCheckedLoadInt64) { 5583 int64_t buffer[] = {0x66bbccddeeff0011LL, 0x1122334455667788LL}; 5584 RawMachineAssemblerTester<int64_t> m(MachineType::Int32()); 5585 Node* base = m.PointerConstant(buffer); 5586 Node* index = m.Parameter(0); 5587 Node* length = m.Int32Constant(16); 5588 Node* load = m.AddNode(m.machine()->CheckedLoad(MachineType::Int64()), base, 5589 index, length); 5590 m.Return(load); 5591 5592 CHECK_EQ(buffer[0], m.Call(0)); 5593 CHECK_EQ(buffer[1], m.Call(8)); 5594 CHECK_EQ(0, m.Call(16)); 5595 } 5596 5597 5598 TEST(RunCheckedStoreInt64) { 5599 const int64_t write = 0x5566778899aabbLL; 5600 const int64_t before = 0x33bbccddeeff0011LL; 5601 int64_t buffer[] = {before, before}; 5602 RawMachineAssemblerTester<int32_t> m(MachineType::Int32()); 5603 Node* base = m.PointerConstant(buffer); 5604 Node* index = m.Parameter(0); 5605 Node* length = m.Int32Constant(16); 5606 Node* value = m.Int64Constant(write); 5607 Node* store = 5608 m.AddNode(m.machine()->CheckedStore(MachineRepresentation::kWord64), base, 5609 index, length, value); 5610 USE(store); 5611 m.Return(m.Int32Constant(11)); 5612 5613 CHECK_EQ(11, m.Call(16)); 5614 CHECK_EQ(before, buffer[0]); 5615 CHECK_EQ(before, buffer[1]); 5616 5617 CHECK_EQ(11, m.Call(0)); 5618 CHECK_EQ(write, buffer[0]); 5619 CHECK_EQ(before, buffer[1]); 5620 5621 CHECK_EQ(11, m.Call(8)); 5622 CHECK_EQ(write, buffer[0]); 5623 CHECK_EQ(write, buffer[1]); 5624 } 5625 5626 5627 TEST(RunBitcastInt64ToFloat64) { 5628 int64_t input = 1; 5629 double output = 0.0; 5630 RawMachineAssemblerTester<int32_t> m; 5631 m.StoreToPointer( 5632 &output, MachineRepresentation::kFloat64, 5633 m.BitcastInt64ToFloat64(m.LoadFromPointer(&input, MachineType::Int64()))); 5634 m.Return(m.Int32Constant(11)); 5635 FOR_INT64_INPUTS(i) { 5636 input = *i; 5637 CHECK_EQ(11, m.Call()); 5638 double expected = bit_cast<double>(input); 5639 CHECK_EQ(bit_cast<int64_t>(expected), bit_cast<int64_t>(output)); 5640 } 5641 } 5642 5643 5644 TEST(RunBitcastFloat64ToInt64) { 5645 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); 5646 5647 m.Return(m.BitcastFloat64ToInt64(m.Parameter(0))); 5648 FOR_FLOAT64_INPUTS(i) { CHECK_EQ(bit_cast<int64_t>(*i), m.Call(*i)); } 5649 } 5650 5651 5652 TEST(RunTryTruncateFloat32ToInt64WithoutCheck) { 5653 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32()); 5654 m.Return(m.TryTruncateFloat32ToInt64(m.Parameter(0))); 5655 5656 FOR_INT64_INPUTS(i) { 5657 float input = static_cast<float>(*i); 5658 if (input < static_cast<float>(INT64_MAX) && 5659 input >= static_cast<float>(INT64_MIN)) { 5660 CHECK_EQ(static_cast<int64_t>(input), m.Call(input)); 5661 } 5662 } 5663 } 5664 5665 5666 TEST(RunTryTruncateFloat32ToInt64WithCheck) { 5667 int64_t success = 0; 5668 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float32()); 5669 Node* trunc = m.TryTruncateFloat32ToInt64(m.Parameter(0)); 5670 Node* val = m.Projection(0, trunc); 5671 Node* check = m.Projection(1, trunc); 5672 m.StoreToPointer(&success, MachineRepresentation::kWord64, check); 5673 m.Return(val); 5674 5675 FOR_FLOAT32_INPUTS(i) { 5676 if (*i < static_cast<float>(INT64_MAX) && 5677 *i >= static_cast<float>(INT64_MIN)) { 5678 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i)); 5679 CHECK_NE(0, success); 5680 } else { 5681 m.Call(*i); 5682 CHECK_EQ(0, success); 5683 } 5684 } 5685 } 5686 5687 5688 TEST(RunTryTruncateFloat64ToInt64WithoutCheck) { 5689 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); 5690 m.Return(m.TryTruncateFloat64ToInt64(m.Parameter(0))); 5691 5692 FOR_INT64_INPUTS(i) { 5693 double input = static_cast<double>(*i); 5694 CHECK_EQ(static_cast<int64_t>(input), m.Call(input)); 5695 } 5696 } 5697 5698 5699 TEST(RunTryTruncateFloat64ToInt64WithCheck) { 5700 int64_t success = 0; 5701 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); 5702 Node* trunc = m.TryTruncateFloat64ToInt64(m.Parameter(0)); 5703 Node* val = m.Projection(0, trunc); 5704 Node* check = m.Projection(1, trunc); 5705 m.StoreToPointer(&success, MachineRepresentation::kWord64, check); 5706 m.Return(val); 5707 5708 FOR_FLOAT64_INPUTS(i) { 5709 if (*i < static_cast<double>(INT64_MAX) && 5710 *i >= static_cast<double>(INT64_MIN)) { 5711 // Conversions within this range should succeed. 5712 CHECK_EQ(static_cast<int64_t>(*i), m.Call(*i)); 5713 CHECK_NE(0, success); 5714 } else { 5715 m.Call(*i); 5716 CHECK_EQ(0, success); 5717 } 5718 } 5719 } 5720 5721 5722 TEST(RunTryTruncateFloat32ToUint64WithoutCheck) { 5723 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32()); 5724 m.Return(m.TryTruncateFloat32ToUint64(m.Parameter(0))); 5725 5726 FOR_UINT64_INPUTS(i) { 5727 float input = static_cast<float>(*i); 5728 // This condition on 'input' is required because 5729 // static_cast<float>(UINT64_MAX) results in a value outside uint64 range. 5730 if (input < static_cast<float>(UINT64_MAX)) { 5731 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input)); 5732 } 5733 } 5734 } 5735 5736 5737 TEST(RunTryTruncateFloat32ToUint64WithCheck) { 5738 int64_t success = 0; 5739 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float32()); 5740 Node* trunc = m.TryTruncateFloat32ToUint64(m.Parameter(0)); 5741 Node* val = m.Projection(0, trunc); 5742 Node* check = m.Projection(1, trunc); 5743 m.StoreToPointer(&success, MachineRepresentation::kWord64, check); 5744 m.Return(val); 5745 5746 FOR_FLOAT32_INPUTS(i) { 5747 if (*i < static_cast<float>(UINT64_MAX) && *i > -1.0) { 5748 // Conversions within this range should succeed. 5749 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i)); 5750 CHECK_NE(0, success); 5751 } else { 5752 m.Call(*i); 5753 CHECK_EQ(0, success); 5754 } 5755 } 5756 } 5757 5758 5759 TEST(RunTryTruncateFloat64ToUint64WithoutCheck) { 5760 BufferedRawMachineAssemblerTester<uint64_t> m(MachineType::Float64()); 5761 m.Return(m.TruncateFloat64ToUint64(m.Parameter(0))); 5762 5763 FOR_UINT64_INPUTS(j) { 5764 double input = static_cast<double>(*j); 5765 5766 if (input < static_cast<float>(UINT64_MAX)) { 5767 CHECK_EQ(static_cast<uint64_t>(input), m.Call(input)); 5768 } 5769 } 5770 } 5771 5772 5773 TEST(RunTryTruncateFloat64ToUint64WithCheck) { 5774 int64_t success = 0; 5775 BufferedRawMachineAssemblerTester<int64_t> m(MachineType::Float64()); 5776 Node* trunc = m.TryTruncateFloat64ToUint64(m.Parameter(0)); 5777 Node* val = m.Projection(0, trunc); 5778 Node* check = m.Projection(1, trunc); 5779 m.StoreToPointer(&success, MachineRepresentation::kWord64, check); 5780 m.Return(val); 5781 5782 FOR_FLOAT64_INPUTS(i) { 5783 if (*i < 18446744073709551616.0 && *i > -1) { 5784 // Conversions within this range should succeed. 5785 CHECK_EQ(static_cast<uint64_t>(*i), m.Call(*i)); 5786 CHECK_NE(0, success); 5787 } else { 5788 m.Call(*i); 5789 CHECK_EQ(0, success); 5790 } 5791 } 5792 } 5793 5794 5795 TEST(RunRoundInt64ToFloat32) { 5796 BufferedRawMachineAssemblerTester<float> m(MachineType::Int64()); 5797 m.Return(m.RoundInt64ToFloat32(m.Parameter(0))); 5798 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<float>(*i), m.Call(*i)); } 5799 } 5800 5801 5802 TEST(RunRoundInt64ToFloat64) { 5803 BufferedRawMachineAssemblerTester<double> m(MachineType::Int64()); 5804 m.Return(m.RoundInt64ToFloat64(m.Parameter(0))); 5805 FOR_INT64_INPUTS(i) { CHECK_EQ(static_cast<double>(*i), m.Call(*i)); } 5806 } 5807 5808 5809 TEST(RunRoundUint64ToFloat64) { 5810 struct { 5811 uint64_t input; 5812 uint64_t expected; 5813 } values[] = {{0x0, 0x0}, 5814 {0x1, 0x3ff0000000000000}, 5815 {0xffffffff, 0x41efffffffe00000}, 5816 {0x1b09788b, 0x41bb09788b000000}, 5817 {0x4c5fce8, 0x419317f3a0000000}, 5818 {0xcc0de5bf, 0x41e981bcb7e00000}, 5819 {0x2, 0x4000000000000000}, 5820 {0x3, 0x4008000000000000}, 5821 {0x4, 0x4010000000000000}, 5822 {0x5, 0x4014000000000000}, 5823 {0x8, 0x4020000000000000}, 5824 {0x9, 0x4022000000000000}, 5825 {0xffffffffffffffff, 0x43f0000000000000}, 5826 {0xfffffffffffffffe, 0x43f0000000000000}, 5827 {0xfffffffffffffffd, 0x43f0000000000000}, 5828 {0x100000000, 0x41f0000000000000}, 5829 {0xffffffff00000000, 0x43efffffffe00000}, 5830 {0x1b09788b00000000, 0x43bb09788b000000}, 5831 {0x4c5fce800000000, 0x439317f3a0000000}, 5832 {0xcc0de5bf00000000, 0x43e981bcb7e00000}, 5833 {0x200000000, 0x4200000000000000}, 5834 {0x300000000, 0x4208000000000000}, 5835 {0x400000000, 0x4210000000000000}, 5836 {0x500000000, 0x4214000000000000}, 5837 {0x800000000, 0x4220000000000000}, 5838 {0x900000000, 0x4222000000000000}, 5839 {0x273a798e187937a3, 0x43c39d3cc70c3c9c}, 5840 {0xece3af835495a16b, 0x43ed9c75f06a92b4}, 5841 {0xb668ecc11223344, 0x43a6cd1d98224467}, 5842 {0x9e, 0x4063c00000000000}, 5843 {0x43, 0x4050c00000000000}, 5844 {0xaf73, 0x40e5ee6000000000}, 5845 {0x116b, 0x40b16b0000000000}, 5846 {0x658ecc, 0x415963b300000000}, 5847 {0x2b3b4c, 0x41459da600000000}, 5848 {0x88776655, 0x41e10eeccaa00000}, 5849 {0x70000000, 0x41dc000000000000}, 5850 {0x7200000, 0x419c800000000000}, 5851 {0x7fffffff, 0x41dfffffffc00000}, 5852 {0x56123761, 0x41d5848dd8400000}, 5853 {0x7fffff00, 0x41dfffffc0000000}, 5854 {0x761c4761eeeeeeee, 0x43dd8711d87bbbbc}, 5855 {0x80000000eeeeeeee, 0x43e00000001dddde}, 5856 {0x88888888dddddddd, 0x43e11111111bbbbc}, 5857 {0xa0000000dddddddd, 0x43e40000001bbbbc}, 5858 {0xddddddddaaaaaaaa, 0x43ebbbbbbbb55555}, 5859 {0xe0000000aaaaaaaa, 0x43ec000000155555}, 5860 {0xeeeeeeeeeeeeeeee, 0x43edddddddddddde}, 5861 {0xfffffffdeeeeeeee, 0x43efffffffbdddde}, 5862 {0xf0000000dddddddd, 0x43ee0000001bbbbc}, 5863 {0x7fffffdddddddd, 0x435ffffff7777777}, 5864 {0x3fffffaaaaaaaa, 0x434fffffd5555555}, 5865 {0x1fffffaaaaaaaa, 0x433fffffaaaaaaaa}, 5866 {0xfffff, 0x412ffffe00000000}, 5867 {0x7ffff, 0x411ffffc00000000}, 5868 {0x3ffff, 0x410ffff800000000}, 5869 {0x1ffff, 0x40fffff000000000}, 5870 {0xffff, 0x40efffe000000000}, 5871 {0x7fff, 0x40dfffc000000000}, 5872 {0x3fff, 0x40cfff8000000000}, 5873 {0x1fff, 0x40bfff0000000000}, 5874 {0xfff, 0x40affe0000000000}, 5875 {0x7ff, 0x409ffc0000000000}, 5876 {0x3ff, 0x408ff80000000000}, 5877 {0x1ff, 0x407ff00000000000}, 5878 {0x3fffffffffff, 0x42cfffffffffff80}, 5879 {0x1fffffffffff, 0x42bfffffffffff00}, 5880 {0xfffffffffff, 0x42affffffffffe00}, 5881 {0x7ffffffffff, 0x429ffffffffffc00}, 5882 {0x3ffffffffff, 0x428ffffffffff800}, 5883 {0x1ffffffffff, 0x427ffffffffff000}, 5884 {0x8000008000000000, 0x43e0000010000000}, 5885 {0x8000008000000001, 0x43e0000010000000}, 5886 {0x8000000000000400, 0x43e0000000000000}, 5887 {0x8000000000000401, 0x43e0000000000001}}; 5888 5889 BufferedRawMachineAssemblerTester<double> m(MachineType::Uint64()); 5890 m.Return(m.RoundUint64ToFloat64(m.Parameter(0))); 5891 5892 for (size_t i = 0; i < arraysize(values); i++) { 5893 CHECK_EQ(bit_cast<double>(values[i].expected), m.Call(values[i].input)); 5894 } 5895 } 5896 5897 5898 TEST(RunRoundUint64ToFloat32) { 5899 struct { 5900 uint64_t input; 5901 uint32_t expected; 5902 } values[] = {{0x0, 0x0}, 5903 {0x1, 0x3f800000}, 5904 {0xffffffff, 0x4f800000}, 5905 {0x1b09788b, 0x4dd84bc4}, 5906 {0x4c5fce8, 0x4c98bf9d}, 5907 {0xcc0de5bf, 0x4f4c0de6}, 5908 {0x2, 0x40000000}, 5909 {0x3, 0x40400000}, 5910 {0x4, 0x40800000}, 5911 {0x5, 0x40a00000}, 5912 {0x8, 0x41000000}, 5913 {0x9, 0x41100000}, 5914 {0xffffffffffffffff, 0x5f800000}, 5915 {0xfffffffffffffffe, 0x5f800000}, 5916 {0xfffffffffffffffd, 0x5f800000}, 5917 {0x0, 0x0}, 5918 {0x100000000, 0x4f800000}, 5919 {0xffffffff00000000, 0x5f800000}, 5920 {0x1b09788b00000000, 0x5dd84bc4}, 5921 {0x4c5fce800000000, 0x5c98bf9d}, 5922 {0xcc0de5bf00000000, 0x5f4c0de6}, 5923 {0x200000000, 0x50000000}, 5924 {0x300000000, 0x50400000}, 5925 {0x400000000, 0x50800000}, 5926 {0x500000000, 0x50a00000}, 5927 {0x800000000, 0x51000000}, 5928 {0x900000000, 0x51100000}, 5929 {0x273a798e187937a3, 0x5e1ce9e6}, 5930 {0xece3af835495a16b, 0x5f6ce3b0}, 5931 {0xb668ecc11223344, 0x5d3668ed}, 5932 {0x9e, 0x431e0000}, 5933 {0x43, 0x42860000}, 5934 {0xaf73, 0x472f7300}, 5935 {0x116b, 0x458b5800}, 5936 {0x658ecc, 0x4acb1d98}, 5937 {0x2b3b4c, 0x4a2ced30}, 5938 {0x88776655, 0x4f087766}, 5939 {0x70000000, 0x4ee00000}, 5940 {0x7200000, 0x4ce40000}, 5941 {0x7fffffff, 0x4f000000}, 5942 {0x56123761, 0x4eac246f}, 5943 {0x7fffff00, 0x4efffffe}, 5944 {0x761c4761eeeeeeee, 0x5eec388f}, 5945 {0x80000000eeeeeeee, 0x5f000000}, 5946 {0x88888888dddddddd, 0x5f088889}, 5947 {0xa0000000dddddddd, 0x5f200000}, 5948 {0xddddddddaaaaaaaa, 0x5f5dddde}, 5949 {0xe0000000aaaaaaaa, 0x5f600000}, 5950 {0xeeeeeeeeeeeeeeee, 0x5f6eeeef}, 5951 {0xfffffffdeeeeeeee, 0x5f800000}, 5952 {0xf0000000dddddddd, 0x5f700000}, 5953 {0x7fffffdddddddd, 0x5b000000}, 5954 {0x3fffffaaaaaaaa, 0x5a7fffff}, 5955 {0x1fffffaaaaaaaa, 0x59fffffd}, 5956 {0xfffff, 0x497ffff0}, 5957 {0x7ffff, 0x48ffffe0}, 5958 {0x3ffff, 0x487fffc0}, 5959 {0x1ffff, 0x47ffff80}, 5960 {0xffff, 0x477fff00}, 5961 {0x7fff, 0x46fffe00}, 5962 {0x3fff, 0x467ffc00}, 5963 {0x1fff, 0x45fff800}, 5964 {0xfff, 0x457ff000}, 5965 {0x7ff, 0x44ffe000}, 5966 {0x3ff, 0x447fc000}, 5967 {0x1ff, 0x43ff8000}, 5968 {0x3fffffffffff, 0x56800000}, 5969 {0x1fffffffffff, 0x56000000}, 5970 {0xfffffffffff, 0x55800000}, 5971 {0x7ffffffffff, 0x55000000}, 5972 {0x3ffffffffff, 0x54800000}, 5973 {0x1ffffffffff, 0x54000000}, 5974 {0x8000008000000000, 0x5f000000}, 5975 {0x8000008000000001, 0x5f000001}, 5976 {0x8000000000000400, 0x5f000000}, 5977 {0x8000000000000401, 0x5f000000}}; 5978 5979 BufferedRawMachineAssemblerTester<float> m(MachineType::Uint64()); 5980 m.Return(m.RoundUint64ToFloat32(m.Parameter(0))); 5981 5982 for (size_t i = 0; i < arraysize(values); i++) { 5983 CHECK_EQ(bit_cast<float>(values[i].expected), m.Call(values[i].input)); 5984 } 5985 } 5986 5987 5988 #endif 5989 5990 5991 TEST(RunBitcastFloat32ToInt32) { 5992 float input = 32.25; 5993 RawMachineAssemblerTester<int32_t> m; 5994 m.Return(m.BitcastFloat32ToInt32( 5995 m.LoadFromPointer(&input, MachineType::Float32()))); 5996 FOR_FLOAT32_INPUTS(i) { 5997 input = *i; 5998 int32_t expected = bit_cast<int32_t>(input); 5999 CHECK_EQ(expected, m.Call()); 6000 } 6001 } 6002 6003 6004 TEST(RunBitcastInt32ToFloat32) { 6005 int32_t input = 1; 6006 float output = 0.0; 6007 RawMachineAssemblerTester<int32_t> m; 6008 m.StoreToPointer( 6009 &output, MachineRepresentation::kFloat32, 6010 m.BitcastInt32ToFloat32(m.LoadFromPointer(&input, MachineType::Int32()))); 6011 m.Return(m.Int32Constant(11)); 6012 FOR_INT32_INPUTS(i) { 6013 input = *i; 6014 CHECK_EQ(11, m.Call()); 6015 float expected = bit_cast<float>(input); 6016 CHECK_EQ(bit_cast<int32_t>(expected), bit_cast<int32_t>(output)); 6017 } 6018 } 6019 6020 6021 TEST(RunComputedCodeObject) { 6022 GraphBuilderTester<int32_t> a; 6023 a.Return(a.Int32Constant(33)); 6024 a.End(); 6025 Handle<Code> code_a = a.GetCode(); 6026 6027 GraphBuilderTester<int32_t> b; 6028 b.Return(b.Int32Constant(44)); 6029 b.End(); 6030 Handle<Code> code_b = b.GetCode(); 6031 6032 RawMachineAssemblerTester<int32_t> r(MachineType::Int32()); 6033 RawMachineLabel tlabel; 6034 RawMachineLabel flabel; 6035 RawMachineLabel merge; 6036 r.Branch(r.Parameter(0), &tlabel, &flabel); 6037 r.Bind(&tlabel); 6038 Node* fa = r.HeapConstant(code_a); 6039 r.Goto(&merge); 6040 r.Bind(&flabel); 6041 Node* fb = r.HeapConstant(code_b); 6042 r.Goto(&merge); 6043 r.Bind(&merge); 6044 Node* phi = r.Phi(MachineRepresentation::kWord32, fa, fb); 6045 6046 // TODO(titzer): all this descriptor hackery is just to call the above 6047 // functions as code objects instead of direct addresses. 6048 CSignature0<int32_t> sig; 6049 CallDescriptor* c = Linkage::GetSimplifiedCDescriptor(r.zone(), &sig); 6050 LinkageLocation ret[] = {c->GetReturnLocation(0)}; 6051 Signature<LinkageLocation> loc(1, 0, ret); 6052 CallDescriptor* desc = new (r.zone()) CallDescriptor( // -- 6053 CallDescriptor::kCallCodeObject, // kind 6054 MachineType::AnyTagged(), // target_type 6055 c->GetInputLocation(0), // target_loc 6056 &sig, // machine_sig 6057 &loc, // location_sig 6058 0, // stack count 6059 Operator::kNoProperties, // properties 6060 c->CalleeSavedRegisters(), // callee saved 6061 c->CalleeSavedFPRegisters(), // callee saved FP 6062 CallDescriptor::kNoFlags, // flags 6063 "c-call-as-code"); 6064 Node* call = r.AddNode(r.common()->Call(desc), phi); 6065 r.Return(call); 6066 6067 CHECK_EQ(33, r.Call(1)); 6068 CHECK_EQ(44, r.Call(0)); 6069 } 6070 6071 } // namespace compiler 6072 } // namespace internal 6073 } // namespace v8 6074