OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <list> | 5 #include <list> |
6 | 6 |
7 #include "test/cctest/compiler/instruction-selector-tester.h" | 7 #include "test/cctest/compiler/instruction-selector-tester.h" |
8 #include "test/cctest/compiler/value-helper.h" | 8 #include "test/cctest/compiler/value-helper.h" |
9 | 9 |
10 using namespace v8::internal; | 10 using namespace v8::internal; |
(...skipping 23 matching lines...) Expand all Loading... |
34 DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq}; | 34 DPI xor_ = {machine.Word32Xor(), kArmEor, kArmEor, kArmTeq}; |
35 push_back(xor_); | 35 push_back(xor_); |
36 DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn}; | 36 DPI add = {machine.Int32Add(), kArmAdd, kArmAdd, kArmCmn}; |
37 push_back(add); | 37 push_back(add); |
38 DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp}; | 38 DPI sub = {machine.Int32Sub(), kArmSub, kArmRsb, kArmCmp}; |
39 push_back(sub); | 39 push_back(sub); |
40 } | 40 } |
41 }; | 41 }; |
42 | 42 |
43 | 43 |
| 44 struct ODPI { |
| 45 Operator* op; |
| 46 ArchOpcode arch_opcode; |
| 47 ArchOpcode reverse_arch_opcode; |
| 48 }; |
| 49 |
| 50 |
| 51 // ARM data processing instructions with overflow. |
| 52 class ODPIs V8_FINAL : public std::list<ODPI>, private HandleAndZoneScope { |
| 53 public: |
| 54 ODPIs() { |
| 55 MachineOperatorBuilder machine(main_zone()); |
| 56 ODPI add = {machine.Int32AddWithOverflow(), kArmAdd, kArmAdd}; |
| 57 push_back(add); |
| 58 ODPI sub = {machine.Int32SubWithOverflow(), kArmSub, kArmRsb}; |
| 59 push_back(sub); |
| 60 } |
| 61 }; |
| 62 |
| 63 |
44 // ARM immediates. | 64 // ARM immediates. |
45 class Immediates V8_FINAL : public std::list<int32_t> { | 65 class Immediates V8_FINAL : public std::list<int32_t> { |
46 public: | 66 public: |
47 Immediates() { | 67 Immediates() { |
48 for (uint32_t imm8 = 0; imm8 < 256; ++imm8) { | 68 for (uint32_t imm8 = 0; imm8 < 256; ++imm8) { |
49 for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) { | 69 for (uint32_t rot4 = 0; rot4 < 32; rot4 += 2) { |
50 int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4)); | 70 int32_t imm = (imm8 >> rot4) | (imm8 << (32 - rot4)); |
51 CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm)); | 71 CHECK(Assembler::ImmediateFitsAddrMode1Instruction(imm)); |
52 push_back(imm); | 72 push_back(imm); |
53 } | 73 } |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 CHECK_EQ(1, m.code.size()); | 238 CHECK_EQ(1, m.code.size()); |
219 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); | 239 CHECK_EQ(dpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
220 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 240 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
221 } | 241 } |
222 } | 242 } |
223 } | 243 } |
224 } | 244 } |
225 } | 245 } |
226 | 246 |
227 | 247 |
228 TEST(InstructionSelectorInt32AddWithOverflowP) { | 248 TEST(InstructionSelectorODPIP) { |
229 { | 249 ODPIs odpis; |
230 InstructionSelectorTester m; | 250 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
231 Node* ovf; | 251 ODPI odpi = *i; |
232 m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), NULL, &ovf); | |
233 m.Return(ovf); | |
234 m.SelectInstructions(); | |
235 CHECK_EQ(1, m.code.size()); | |
236 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
237 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
238 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
239 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
240 CHECK_EQ(2, m.code[0]->InputCount()); | |
241 CHECK_EQ(1, m.code[0]->OutputCount()); | |
242 } | |
243 { | |
244 InstructionSelectorTester m; | |
245 Node* val; | |
246 m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), &val, NULL); | |
247 m.Return(val); | |
248 m.SelectInstructions(); | |
249 CHECK_EQ(1, m.code.size()); | |
250 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
251 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
252 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
253 CHECK_EQ(2, m.code[0]->InputCount()); | |
254 CHECK_EQ(1, m.code[0]->OutputCount()); | |
255 } | |
256 { | |
257 InstructionSelectorTester m; | |
258 Node* val, *ovf; | |
259 m.Int32AddWithOverflow(m.Parameter(0), m.Parameter(1), &val, &ovf); | |
260 m.Return(m.Word32Equal(val, ovf)); | |
261 m.SelectInstructions(); | |
262 CHECK_LE(1, m.code.size()); | |
263 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
264 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | |
265 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
266 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
267 CHECK_EQ(2, m.code[0]->InputCount()); | |
268 CHECK_EQ(2, m.code[0]->OutputCount()); | |
269 } | |
270 } | |
271 | |
272 | |
273 TEST(InstructionSelectorInt32AddWithOverflowImm) { | |
274 Immediates immediates; | |
275 for (Immediates::const_iterator i = immediates.begin(); i != immediates.end(); | |
276 ++i) { | |
277 int32_t imm = *i; | |
278 { | 252 { |
279 InstructionSelectorTester m; | 253 InstructionSelectorTester m; |
280 Node* ovf; | 254 m.Return( |
281 m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), NULL, &ovf); | 255 m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)))); |
282 m.Return(ovf); | |
283 m.SelectInstructions(); | 256 m.SelectInstructions(); |
284 CHECK_EQ(1, m.code.size()); | 257 CHECK_EQ(1, m.code.size()); |
285 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 258 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
286 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | 259 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
287 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 260 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
288 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 261 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
289 CHECK_EQ(2, m.code[0]->InputCount()); | 262 CHECK_EQ(2, m.code[0]->InputCount()); |
290 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
291 CHECK_EQ(1, m.code[0]->OutputCount()); | 263 CHECK_EQ(1, m.code[0]->OutputCount()); |
292 } | 264 } |
293 { | 265 { |
294 InstructionSelectorTester m; | 266 InstructionSelectorTester m; |
295 Node* ovf; | 267 m.Return( |
296 m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), NULL, &ovf); | 268 m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)))); |
297 m.Return(ovf); | |
298 m.SelectInstructions(); | 269 m.SelectInstructions(); |
299 CHECK_EQ(1, m.code.size()); | 270 CHECK_EQ(1, m.code.size()); |
300 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 271 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
301 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | 272 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
| 273 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 274 CHECK_EQ(2, m.code[0]->InputCount()); |
| 275 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 276 } |
| 277 { |
| 278 InstructionSelectorTester m; |
| 279 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Parameter(1)); |
| 280 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 281 m.SelectInstructions(); |
| 282 CHECK_LE(1, m.code.size()); |
| 283 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 284 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
302 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 285 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
303 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 286 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
304 CHECK_EQ(2, m.code[0]->InputCount()); | 287 CHECK_EQ(2, m.code[0]->InputCount()); |
305 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
306 CHECK_EQ(1, m.code[0]->OutputCount()); | |
307 } | |
308 { | |
309 InstructionSelectorTester m; | |
310 Node* val; | |
311 m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), &val, NULL); | |
312 m.Return(val); | |
313 m.SelectInstructions(); | |
314 CHECK_EQ(1, m.code.size()); | |
315 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
316 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
317 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
318 CHECK_EQ(2, m.code[0]->InputCount()); | |
319 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
320 CHECK_EQ(1, m.code[0]->OutputCount()); | |
321 } | |
322 { | |
323 InstructionSelectorTester m; | |
324 Node* val; | |
325 m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), &val, NULL); | |
326 m.Return(val); | |
327 m.SelectInstructions(); | |
328 CHECK_EQ(1, m.code.size()); | |
329 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
330 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
331 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | |
332 CHECK_EQ(2, m.code[0]->InputCount()); | |
333 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
334 CHECK_EQ(1, m.code[0]->OutputCount()); | |
335 } | |
336 { | |
337 InstructionSelectorTester m; | |
338 Node* val, *ovf; | |
339 m.Int32AddWithOverflow(m.Parameter(0), m.Int32Constant(imm), &val, &ovf); | |
340 m.Return(m.Word32Equal(val, ovf)); | |
341 m.SelectInstructions(); | |
342 CHECK_LE(1, m.code.size()); | |
343 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
344 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
345 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
346 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
347 CHECK_EQ(2, m.code[0]->InputCount()); | |
348 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
349 CHECK_EQ(2, m.code[0]->OutputCount()); | |
350 } | |
351 { | |
352 InstructionSelectorTester m; | |
353 Node* val, *ovf; | |
354 m.Int32AddWithOverflow(m.Int32Constant(imm), m.Parameter(0), &val, &ovf); | |
355 m.Return(m.Word32Equal(val, ovf)); | |
356 m.SelectInstructions(); | |
357 CHECK_LE(1, m.code.size()); | |
358 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
359 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); | |
360 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
361 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
362 CHECK_EQ(2, m.code[0]->InputCount()); | |
363 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); | |
364 CHECK_EQ(2, m.code[0]->OutputCount()); | 288 CHECK_EQ(2, m.code[0]->OutputCount()); |
365 } | 289 } |
366 } | 290 } |
367 } | 291 } |
368 | 292 |
369 | 293 |
370 TEST(InstructionSelectorInt32AddWithOverflowAndShiftP) { | 294 TEST(InstructionSelectorODPIImm) { |
371 Shifts shifts; | 295 ODPIs odpis; |
372 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | 296 Immediates immediates; |
373 Shift shift = *i; | 297 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
374 { | 298 ODPI odpi = *i; |
375 InstructionSelectorTester m; | 299 for (Immediates::const_iterator j = immediates.begin(); |
376 Node* ovf; | 300 j != immediates.end(); ++j) { |
377 m.Int32AddWithOverflow( | 301 int32_t imm = *j; |
378 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | 302 { |
379 NULL, &ovf); | 303 InstructionSelectorTester m; |
380 m.Return(ovf); | 304 m.Return(m.Projection( |
381 m.SelectInstructions(); | 305 1, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)))); |
382 CHECK_EQ(1, m.code.size()); | 306 m.SelectInstructions(); |
383 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 307 CHECK_EQ(1, m.code.size()); |
384 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 308 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
385 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 309 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
386 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 310 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
387 CHECK_EQ(3, m.code[0]->InputCount()); | 311 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
388 CHECK_EQ(1, m.code[0]->OutputCount()); | 312 CHECK_EQ(2, m.code[0]->InputCount()); |
389 } | 313 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
390 { | 314 CHECK_EQ(1, m.code[0]->OutputCount()); |
391 InstructionSelectorTester m; | 315 } |
392 Node* ovf; | 316 { |
393 m.Int32AddWithOverflow( | 317 InstructionSelectorTester m; |
394 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), | 318 m.Return(m.Projection( |
395 NULL, &ovf); | 319 1, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)))); |
396 m.Return(ovf); | 320 m.SelectInstructions(); |
397 m.SelectInstructions(); | 321 CHECK_EQ(1, m.code.size()); |
398 CHECK_EQ(1, m.code.size()); | 322 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
399 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 323 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
400 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 324 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
401 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 325 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
402 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 326 CHECK_EQ(2, m.code[0]->InputCount()); |
403 CHECK_EQ(3, m.code[0]->InputCount()); | 327 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
404 CHECK_EQ(1, m.code[0]->OutputCount()); | 328 CHECK_EQ(1, m.code[0]->OutputCount()); |
405 } | 329 } |
406 { | 330 { |
407 InstructionSelectorTester m; | 331 InstructionSelectorTester m; |
408 Node* val; | 332 m.Return(m.Projection( |
409 m.Int32AddWithOverflow( | 333 0, m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)))); |
410 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | 334 m.SelectInstructions(); |
411 &val, NULL); | 335 CHECK_EQ(1, m.code.size()); |
412 m.Return(val); | 336 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
413 m.SelectInstructions(); | 337 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
414 CHECK_EQ(1, m.code.size()); | 338 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
415 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 339 CHECK_EQ(2, m.code[0]->InputCount()); |
416 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 340 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
417 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 341 CHECK_EQ(1, m.code[0]->OutputCount()); |
418 CHECK_EQ(3, m.code[0]->InputCount()); | 342 } |
419 CHECK_EQ(1, m.code[0]->OutputCount()); | 343 { |
420 } | 344 InstructionSelectorTester m; |
421 { | 345 m.Return(m.Projection( |
422 InstructionSelectorTester m; | 346 0, m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)))); |
423 Node* val; | 347 m.SelectInstructions(); |
424 m.Int32AddWithOverflow( | 348 CHECK_EQ(1, m.code.size()); |
425 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), | 349 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
426 &val, NULL); | 350 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
427 m.Return(val); | 351 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
428 m.SelectInstructions(); | 352 CHECK_EQ(2, m.code[0]->InputCount()); |
429 CHECK_EQ(1, m.code.size()); | 353 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
430 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 354 CHECK_EQ(1, m.code[0]->OutputCount()); |
431 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 355 } |
432 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 356 { |
433 CHECK_EQ(3, m.code[0]->InputCount()); | 357 InstructionSelectorTester m; |
434 CHECK_EQ(1, m.code[0]->OutputCount()); | 358 Node* node = m.NewNode(odpi.op, m.Parameter(0), m.Int32Constant(imm)); |
435 } | 359 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
436 { | 360 m.SelectInstructions(); |
437 InstructionSelectorTester m; | 361 CHECK_LE(1, m.code.size()); |
438 Node* val, *ovf; | 362 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
439 m.Int32AddWithOverflow( | 363 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
440 m.Parameter(0), m.NewNode(shift.op, m.Parameter(1), m.Parameter(2)), | 364 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
441 &val, &ovf); | 365 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
442 m.Return(m.Word32Equal(val, ovf)); | 366 CHECK_EQ(2, m.code[0]->InputCount()); |
443 m.SelectInstructions(); | 367 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
444 CHECK_LE(1, m.code.size()); | 368 CHECK_EQ(2, m.code[0]->OutputCount()); |
445 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 369 } |
446 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | 370 { |
447 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 371 InstructionSelectorTester m; |
448 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 372 Node* node = m.NewNode(odpi.op, m.Int32Constant(imm), m.Parameter(0)); |
449 CHECK_EQ(3, m.code[0]->InputCount()); | 373 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
450 CHECK_EQ(2, m.code[0]->OutputCount()); | 374 m.SelectInstructions(); |
451 } | 375 CHECK_LE(1, m.code.size()); |
452 { | 376 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
453 InstructionSelectorTester m; | 377 CHECK_EQ(kMode_Operand2_I, m.code[0]->addressing_mode()); |
454 Node* val, *ovf; | 378 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
455 m.Int32AddWithOverflow( | 379 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
456 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), m.Parameter(2), | 380 CHECK_EQ(2, m.code[0]->InputCount()); |
457 &val, &ovf); | 381 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(1))); |
458 m.Return(m.Word32Equal(val, ovf)); | 382 CHECK_EQ(2, m.code[0]->OutputCount()); |
459 m.SelectInstructions(); | 383 } |
460 CHECK_LE(1, m.code.size()); | |
461 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
462 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); | |
463 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
464 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
465 CHECK_EQ(3, m.code[0]->InputCount()); | |
466 CHECK_EQ(2, m.code[0]->OutputCount()); | |
467 } | 384 } |
468 } | 385 } |
469 } | 386 } |
470 | 387 |
471 | 388 |
472 TEST(InstructionSelectorInt32AddWithOverflowAndShiftImm) { | 389 TEST(InstructionSelectorODPIAndShiftP) { |
| 390 ODPIs odpis; |
473 Shifts shifts; | 391 Shifts shifts; |
474 for (Shifts::const_iterator i = shifts.begin(); i != shifts.end(); ++i) { | 392 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
475 Shift shift = *i; | 393 ODPI odpi = *i; |
476 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { | 394 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { |
477 { | 395 Shift shift = *j; |
478 InstructionSelectorTester m; | 396 { |
479 Node* ovf; | 397 InstructionSelectorTester m; |
480 m.Int32AddWithOverflow( | 398 m.Return(m.Projection( |
481 m.Parameter(0), | 399 1, m.NewNode(odpi.op, m.Parameter(0), |
482 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), NULL, | 400 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); |
483 &ovf); | 401 m.SelectInstructions(); |
484 m.Return(ovf); | 402 CHECK_EQ(1, m.code.size()); |
485 m.SelectInstructions(); | 403 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
486 CHECK_EQ(1, m.code.size()); | 404 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
487 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 405 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
488 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 406 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
489 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 407 CHECK_EQ(3, m.code[0]->InputCount()); |
490 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 408 CHECK_EQ(1, m.code[0]->OutputCount()); |
491 CHECK_EQ(3, m.code[0]->InputCount()); | 409 } |
492 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 410 { |
493 CHECK_EQ(1, m.code[0]->OutputCount()); | 411 InstructionSelectorTester m; |
494 } | 412 m.Return(m.Projection( |
495 { | 413 1, m.NewNode(odpi.op, |
496 InstructionSelectorTester m; | 414 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), |
497 Node* ovf; | 415 m.Parameter(2)))); |
498 m.Int32AddWithOverflow( | 416 m.SelectInstructions(); |
499 m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | 417 CHECK_EQ(1, m.code.size()); |
500 m.Parameter(1), NULL, &ovf); | 418 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
501 m.Return(ovf); | 419 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
502 m.SelectInstructions(); | 420 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
503 CHECK_EQ(1, m.code.size()); | 421 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
504 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 422 CHECK_EQ(3, m.code[0]->InputCount()); |
505 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 423 CHECK_EQ(1, m.code[0]->OutputCount()); |
506 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 424 } |
507 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 425 { |
508 CHECK_EQ(3, m.code[0]->InputCount()); | 426 InstructionSelectorTester m; |
509 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 427 m.Return(m.Projection( |
510 CHECK_EQ(1, m.code[0]->OutputCount()); | 428 0, m.NewNode(odpi.op, m.Parameter(0), |
511 } | 429 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))))); |
512 { | 430 m.SelectInstructions(); |
513 InstructionSelectorTester m; | 431 CHECK_EQ(1, m.code.size()); |
514 Node* val; | 432 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
515 m.Int32AddWithOverflow( | 433 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
516 m.Parameter(0), | 434 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
517 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), &val, | 435 CHECK_EQ(3, m.code[0]->InputCount()); |
518 NULL); | 436 CHECK_EQ(1, m.code[0]->OutputCount()); |
519 m.Return(val); | 437 } |
520 m.SelectInstructions(); | 438 { |
521 CHECK_EQ(1, m.code.size()); | 439 InstructionSelectorTester m; |
522 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 440 m.Return(m.Projection( |
523 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 441 0, m.NewNode(odpi.op, |
524 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 442 m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), |
525 CHECK_EQ(3, m.code[0]->InputCount()); | 443 m.Parameter(2)))); |
526 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 444 m.SelectInstructions(); |
527 CHECK_EQ(1, m.code[0]->OutputCount()); | 445 CHECK_EQ(1, m.code.size()); |
528 } | 446 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
529 { | 447 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
530 InstructionSelectorTester m; | 448 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
531 Node* val; | 449 CHECK_EQ(3, m.code[0]->InputCount()); |
532 m.Int32AddWithOverflow( | 450 CHECK_EQ(1, m.code[0]->OutputCount()); |
533 m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | 451 } |
534 m.Parameter(1), &val, NULL); | 452 { |
535 m.Return(val); | 453 InstructionSelectorTester m; |
536 m.SelectInstructions(); | 454 Node* node = |
537 CHECK_EQ(1, m.code.size()); | 455 m.NewNode(odpi.op, m.Parameter(0), |
538 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 456 m.NewNode(shift.op, m.Parameter(1), m.Parameter(2))); |
539 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 457 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
540 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); | 458 m.SelectInstructions(); |
541 CHECK_EQ(3, m.code[0]->InputCount()); | 459 CHECK_LE(1, m.code.size()); |
542 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 460 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
543 CHECK_EQ(1, m.code[0]->OutputCount()); | 461 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
544 } | 462 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
545 { | 463 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
546 InstructionSelectorTester m; | 464 CHECK_EQ(3, m.code[0]->InputCount()); |
547 Node* val, *ovf; | 465 CHECK_EQ(2, m.code[0]->OutputCount()); |
548 m.Int32AddWithOverflow( | 466 } |
549 m.Parameter(0), | 467 { |
550 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm)), &val, | 468 InstructionSelectorTester m; |
551 &ovf); | 469 Node* node = m.NewNode( |
552 m.Return(m.Word32Equal(val, ovf)); | 470 odpi.op, m.NewNode(shift.op, m.Parameter(0), m.Parameter(1)), |
553 m.SelectInstructions(); | 471 m.Parameter(2)); |
554 CHECK_LE(1, m.code.size()); | 472 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
555 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | 473 m.SelectInstructions(); |
556 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | 474 CHECK_LE(1, m.code.size()); |
557 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | 475 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
558 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | 476 CHECK_EQ(shift.r_mode, m.code[0]->addressing_mode()); |
559 CHECK_EQ(3, m.code[0]->InputCount()); | 477 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
560 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | 478 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
561 CHECK_EQ(2, m.code[0]->OutputCount()); | 479 CHECK_EQ(3, m.code[0]->InputCount()); |
562 } | 480 CHECK_EQ(2, m.code[0]->OutputCount()); |
563 { | 481 } |
564 InstructionSelectorTester m; | 482 } |
565 Node* val, *ovf; | |
566 m.Int32AddWithOverflow( | |
567 m.NewNode(shift.op, m.Parameter(0), m.Int32Constant(imm)), | |
568 m.Parameter(1), &val, &ovf); | |
569 m.Return(m.Word32Equal(val, ovf)); | |
570 m.SelectInstructions(); | |
571 CHECK_LE(1, m.code.size()); | |
572 CHECK_EQ(kArmAdd, m.code[0]->arch_opcode()); | |
573 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); | |
574 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); | |
575 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); | |
576 CHECK_EQ(3, m.code[0]->InputCount()); | |
577 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); | |
578 CHECK_EQ(2, m.code[0]->OutputCount()); | |
579 } | |
580 } | |
581 } | 483 } |
582 } | 484 } |
583 | 485 |
584 | 486 |
| 487 TEST(InstructionSelectorODPIAndShiftImm) { |
| 488 ODPIs odpis; |
| 489 Shifts shifts; |
| 490 for (ODPIs::const_iterator i = odpis.begin(); i != odpis.end(); ++i) { |
| 491 ODPI odpi = *i; |
| 492 for (Shifts::const_iterator j = shifts.begin(); j != shifts.end(); ++j) { |
| 493 Shift shift = *j; |
| 494 for (int32_t imm = shift.i_low; imm <= shift.i_high; ++imm) { |
| 495 { |
| 496 InstructionSelectorTester m; |
| 497 m.Return(m.Projection(1, m.NewNode(odpi.op, m.Parameter(0), |
| 498 m.NewNode(shift.op, m.Parameter(1), |
| 499 m.Int32Constant(imm))))); |
| 500 m.SelectInstructions(); |
| 501 CHECK_EQ(1, m.code.size()); |
| 502 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 503 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 504 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 505 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 506 CHECK_EQ(3, m.code[0]->InputCount()); |
| 507 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 508 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 509 } |
| 510 { |
| 511 InstructionSelectorTester m; |
| 512 m.Return(m.Projection( |
| 513 1, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), |
| 514 m.Int32Constant(imm)), |
| 515 m.Parameter(1)))); |
| 516 m.SelectInstructions(); |
| 517 CHECK_EQ(1, m.code.size()); |
| 518 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 519 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 520 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 521 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 522 CHECK_EQ(3, m.code[0]->InputCount()); |
| 523 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 524 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 525 } |
| 526 { |
| 527 InstructionSelectorTester m; |
| 528 m.Return(m.Projection(0, m.NewNode(odpi.op, m.Parameter(0), |
| 529 m.NewNode(shift.op, m.Parameter(1), |
| 530 m.Int32Constant(imm))))); |
| 531 m.SelectInstructions(); |
| 532 CHECK_EQ(1, m.code.size()); |
| 533 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 534 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 535 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 536 CHECK_EQ(3, m.code[0]->InputCount()); |
| 537 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 538 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 539 } |
| 540 { |
| 541 InstructionSelectorTester m; |
| 542 m.Return(m.Projection( |
| 543 0, m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), |
| 544 m.Int32Constant(imm)), |
| 545 m.Parameter(1)))); |
| 546 m.SelectInstructions(); |
| 547 CHECK_EQ(1, m.code.size()); |
| 548 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 549 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 550 CHECK_EQ(kFlags_none, m.code[0]->flags_mode()); |
| 551 CHECK_EQ(3, m.code[0]->InputCount()); |
| 552 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 553 CHECK_EQ(1, m.code[0]->OutputCount()); |
| 554 } |
| 555 { |
| 556 InstructionSelectorTester m; |
| 557 Node* node = m.NewNode( |
| 558 odpi.op, m.Parameter(0), |
| 559 m.NewNode(shift.op, m.Parameter(1), m.Int32Constant(imm))); |
| 560 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 561 m.SelectInstructions(); |
| 562 CHECK_LE(1, m.code.size()); |
| 563 CHECK_EQ(odpi.arch_opcode, m.code[0]->arch_opcode()); |
| 564 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 565 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 566 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 567 CHECK_EQ(3, m.code[0]->InputCount()); |
| 568 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 569 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 570 } |
| 571 { |
| 572 InstructionSelectorTester m; |
| 573 Node* node = m.NewNode(odpi.op, m.NewNode(shift.op, m.Parameter(0), |
| 574 m.Int32Constant(imm)), |
| 575 m.Parameter(1)); |
| 576 m.Return(m.Word32Equal(m.Projection(0, node), m.Projection(1, node))); |
| 577 m.SelectInstructions(); |
| 578 CHECK_LE(1, m.code.size()); |
| 579 CHECK_EQ(odpi.reverse_arch_opcode, m.code[0]->arch_opcode()); |
| 580 CHECK_EQ(shift.i_mode, m.code[0]->addressing_mode()); |
| 581 CHECK_EQ(kFlags_set, m.code[0]->flags_mode()); |
| 582 CHECK_EQ(kOverflow, m.code[0]->flags_condition()); |
| 583 CHECK_EQ(3, m.code[0]->InputCount()); |
| 584 CHECK_EQ(imm, m.ToInt32(m.code[0]->InputAt(2))); |
| 585 CHECK_EQ(2, m.code[0]->OutputCount()); |
| 586 } |
| 587 } |
| 588 } |
| 589 } |
| 590 } |
| 591 |
| 592 |
585 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) { | 593 TEST(InstructionSelectorWord32AndAndWord32XorWithMinus1P) { |
586 { | 594 { |
587 InstructionSelectorTester m; | 595 InstructionSelectorTester m; |
588 m.Return(m.Word32And(m.Parameter(0), | 596 m.Return(m.Word32And(m.Parameter(0), |
589 m.Word32Xor(m.Int32Constant(-1), m.Parameter(1)))); | 597 m.Word32Xor(m.Int32Constant(-1), m.Parameter(1)))); |
590 m.SelectInstructions(); | 598 m.SelectInstructions(); |
591 CHECK_EQ(1, m.code.size()); | 599 CHECK_EQ(1, m.code.size()); |
592 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); | 600 CHECK_EQ(kArmBic, m.code[0]->arch_opcode()); |
593 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | 601 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
594 } | 602 } |
(...skipping 1143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1738 m.Return(m.Int32Constant(0)); | 1746 m.Return(m.Int32Constant(0)); |
1739 m.SelectInstructions(); | 1747 m.SelectInstructions(); |
1740 CHECK_EQ(1, m.code.size()); | 1748 CHECK_EQ(1, m.code.size()); |
1741 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); | 1749 CHECK_EQ(dpi.test_arch_opcode, m.code[0]->arch_opcode()); |
1742 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); | 1750 CHECK_EQ(kMode_Operand2_R, m.code[0]->addressing_mode()); |
1743 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); | 1751 CHECK_EQ(kFlags_branch, m.code[0]->flags_mode()); |
1744 CHECK_EQ(kEqual, m.code[0]->flags_condition()); | 1752 CHECK_EQ(kEqual, m.code[0]->flags_condition()); |
1745 } | 1753 } |
1746 } | 1754 } |
1747 } | 1755 } |
OLD | NEW |