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