OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 FrameScope scope(masm(), StackFrame::MANUAL); \ | 383 FrameScope scope(masm(), StackFrame::MANUAL); \ |
384 __ PrepareCallCFunction(0, 2, kScratchReg); \ | 384 __ PrepareCallCFunction(0, 2, kScratchReg); \ |
385 __ MovToFloatParameters(i.InputDoubleRegister(0), \ | 385 __ MovToFloatParameters(i.InputDoubleRegister(0), \ |
386 i.InputDoubleRegister(1)); \ | 386 i.InputDoubleRegister(1)); \ |
387 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ | 387 __ CallCFunction(ExternalReference::ieee754_##name##_function(isolate()), \ |
388 0, 2); \ | 388 0, 2); \ |
389 /* Move the result in the double result register. */ \ | 389 /* Move the result in the double result register. */ \ |
390 __ MovFromFloatResult(i.OutputDoubleRegister()); \ | 390 __ MovFromFloatResult(i.OutputDoubleRegister()); \ |
391 } while (0) | 391 } while (0) |
392 | 392 |
393 #define ASSEMBLE_FLOAT_MAX() \ | 393 #define ASSEMBLE_DOUBLE_MAX() \ |
394 do { \ | 394 do { \ |
395 DoubleRegister left_reg = i.InputDoubleRegister(0); \ | 395 DoubleRegister left_reg = i.InputDoubleRegister(0); \ |
396 DoubleRegister right_reg = i.InputDoubleRegister(1); \ | 396 DoubleRegister right_reg = i.InputDoubleRegister(1); \ |
397 DoubleRegister result_reg = i.OutputDoubleRegister(); \ | 397 DoubleRegister result_reg = i.OutputDoubleRegister(); \ |
398 Label check_nan_left, check_zero, return_left, return_right, done; \ | 398 Label check_nan_left, check_zero, return_left, return_right, done; \ |
399 __ cdbr(left_reg, right_reg); \ | 399 __ cdbr(left_reg, right_reg); \ |
400 __ bunordered(&check_nan_left, Label::kNear); \ | 400 __ bunordered(&check_nan_left, Label::kNear); \ |
401 __ beq(&check_zero); \ | 401 __ beq(&check_zero); \ |
402 __ bge(&return_left, Label::kNear); \ | 402 __ bge(&return_left, Label::kNear); \ |
403 __ b(&return_right, Label::kNear); \ | 403 __ b(&return_right, Label::kNear); \ |
404 \ | 404 \ |
405 __ bind(&check_zero); \ | 405 __ bind(&check_zero); \ |
406 __ lzdr(kDoubleRegZero); \ | 406 __ lzdr(kDoubleRegZero); \ |
407 __ cdbr(left_reg, kDoubleRegZero); \ | 407 __ cdbr(left_reg, kDoubleRegZero); \ |
408 /* left == right != 0. */ \ | 408 /* left == right != 0. */ \ |
409 __ bne(&return_left, Label::kNear); \ | 409 __ bne(&return_left, Label::kNear); \ |
410 /* At this point, both left and right are either 0 or -0. */ \ | 410 /* At this point, both left and right are either 0 or -0. */ \ |
411 /* N.B. The following works because +0 + -0 == +0 */ \ | 411 /* N.B. The following works because +0 + -0 == +0 */ \ |
412 /* For max we want logical-and of sign bit: (L + R) */ \ | 412 /* For max we want logical-and of sign bit: (L + R) */ \ |
413 __ ldr(result_reg, left_reg); \ | 413 __ ldr(result_reg, left_reg); \ |
414 __ adbr(result_reg, right_reg); \ | 414 __ adbr(result_reg, right_reg); \ |
415 __ b(&done, Label::kNear); \ | 415 __ b(&done, Label::kNear); \ |
416 \ | 416 \ |
417 __ bind(&check_nan_left); \ | 417 __ bind(&check_nan_left); \ |
418 __ cdbr(left_reg, left_reg); \ | 418 __ cdbr(left_reg, left_reg); \ |
419 /* left == NaN. */ \ | 419 /* left == NaN. */ \ |
420 __ bunordered(&return_left, Label::kNear); \ | 420 __ bunordered(&return_left, Label::kNear); \ |
421 \ | 421 \ |
422 __ bind(&return_right); \ | 422 __ bind(&return_right); \ |
423 if (!right_reg.is(result_reg)) { \ | 423 if (!right_reg.is(result_reg)) { \ |
424 __ ldr(result_reg, right_reg); \ | 424 __ ldr(result_reg, right_reg); \ |
425 } \ | 425 } \ |
426 __ b(&done, Label::kNear); \ | 426 __ b(&done, Label::kNear); \ |
427 \ | 427 \ |
428 __ bind(&return_left); \ | 428 __ bind(&return_left); \ |
429 if (!left_reg.is(result_reg)) { \ | 429 if (!left_reg.is(result_reg)) { \ |
430 __ ldr(result_reg, left_reg); \ | 430 __ ldr(result_reg, left_reg); \ |
431 } \ | 431 } \ |
432 __ bind(&done); \ | 432 __ bind(&done); \ |
433 } while (0) \ | |
434 | |
435 #define ASSEMBLE_FLOAT_MIN() \ | |
436 do { \ | |
437 DoubleRegister left_reg = i.InputDoubleRegister(0); \ | |
438 DoubleRegister right_reg = i.InputDoubleRegister(1); \ | |
439 DoubleRegister result_reg = i.OutputDoubleRegister(); \ | |
440 Label check_nan_left, check_zero, return_left, return_right, done; \ | |
441 __ cdbr(left_reg, right_reg); \ | |
442 __ bunordered(&check_nan_left, Label::kNear); \ | |
443 __ beq(&check_zero); \ | |
444 __ ble(&return_left, Label::kNear); \ | |
445 __ b(&return_right, Label::kNear); \ | |
446 \ | |
447 __ bind(&check_zero); \ | |
448 __ lzdr(kDoubleRegZero); \ | |
449 __ cdbr(left_reg, kDoubleRegZero); \ | |
450 /* left == right != 0. */ \ | |
451 __ bne(&return_left, Label::kNear); \ | |
452 /* At this point, both left and right are either 0 or -0. */ \ | |
453 /* N.B. The following works because +0 + -0 == +0 */ \ | |
454 /* For min we want logical-or of sign bit: -(-L + -R) */ \ | |
455 __ lcdbr(left_reg, left_reg); \ | |
456 __ ldr(result_reg, left_reg); \ | |
457 if (left_reg.is(right_reg)) { \ | |
458 __ adbr(result_reg, right_reg); \ | |
459 } else { \ | |
460 __ sdbr(result_reg, right_reg); \ | |
461 } \ | |
462 __ lcdbr(result_reg, result_reg); \ | |
463 __ b(&done, Label::kNear); \ | |
464 \ | |
465 __ bind(&check_nan_left); \ | |
466 __ cdbr(left_reg, left_reg); \ | |
467 /* left == NaN. */ \ | |
468 __ bunordered(&return_left, Label::kNear); \ | |
469 \ | |
470 __ bind(&return_right); \ | |
471 if (!right_reg.is(result_reg)) { \ | |
472 __ ldr(result_reg, right_reg); \ | |
473 } \ | |
474 __ b(&done, Label::kNear); \ | |
475 \ | |
476 __ bind(&return_left); \ | |
477 if (!left_reg.is(result_reg)) { \ | |
478 __ ldr(result_reg, left_reg); \ | |
479 } \ | |
480 __ bind(&done); \ | |
481 } while (0) | 433 } while (0) |
482 | 434 |
| 435 #define ASSEMBLE_DOUBLE_MIN() \ |
| 436 do { \ |
| 437 DoubleRegister left_reg = i.InputDoubleRegister(0); \ |
| 438 DoubleRegister right_reg = i.InputDoubleRegister(1); \ |
| 439 DoubleRegister result_reg = i.OutputDoubleRegister(); \ |
| 440 Label check_nan_left, check_zero, return_left, return_right, done; \ |
| 441 __ cdbr(left_reg, right_reg); \ |
| 442 __ bunordered(&check_nan_left, Label::kNear); \ |
| 443 __ beq(&check_zero); \ |
| 444 __ ble(&return_left, Label::kNear); \ |
| 445 __ b(&return_right, Label::kNear); \ |
| 446 \ |
| 447 __ bind(&check_zero); \ |
| 448 __ lzdr(kDoubleRegZero); \ |
| 449 __ cdbr(left_reg, kDoubleRegZero); \ |
| 450 /* left == right != 0. */ \ |
| 451 __ bne(&return_left, Label::kNear); \ |
| 452 /* At this point, both left and right are either 0 or -0. */ \ |
| 453 /* N.B. The following works because +0 + -0 == +0 */ \ |
| 454 /* For min we want logical-or of sign bit: -(-L + -R) */ \ |
| 455 __ lcdbr(left_reg, left_reg); \ |
| 456 __ ldr(result_reg, left_reg); \ |
| 457 if (left_reg.is(right_reg)) { \ |
| 458 __ adbr(result_reg, right_reg); \ |
| 459 } else { \ |
| 460 __ sdbr(result_reg, right_reg); \ |
| 461 } \ |
| 462 __ lcdbr(result_reg, result_reg); \ |
| 463 __ b(&done, Label::kNear); \ |
| 464 \ |
| 465 __ bind(&check_nan_left); \ |
| 466 __ cdbr(left_reg, left_reg); \ |
| 467 /* left == NaN. */ \ |
| 468 __ bunordered(&return_left, Label::kNear); \ |
| 469 \ |
| 470 __ bind(&return_right); \ |
| 471 if (!right_reg.is(result_reg)) { \ |
| 472 __ ldr(result_reg, right_reg); \ |
| 473 } \ |
| 474 __ b(&done, Label::kNear); \ |
| 475 \ |
| 476 __ bind(&return_left); \ |
| 477 if (!left_reg.is(result_reg)) { \ |
| 478 __ ldr(result_reg, left_reg); \ |
| 479 } \ |
| 480 __ bind(&done); \ |
| 481 } while (0) |
| 482 |
| 483 #define ASSEMBLE_FLOAT_MAX() \ |
| 484 do { \ |
| 485 DoubleRegister left_reg = i.InputDoubleRegister(0); \ |
| 486 DoubleRegister right_reg = i.InputDoubleRegister(1); \ |
| 487 DoubleRegister result_reg = i.OutputDoubleRegister(); \ |
| 488 Label check_nan_left, check_zero, return_left, return_right, done; \ |
| 489 __ cebr(left_reg, right_reg); \ |
| 490 __ bunordered(&check_nan_left, Label::kNear); \ |
| 491 __ beq(&check_zero); \ |
| 492 __ bge(&return_left, Label::kNear); \ |
| 493 __ b(&return_right, Label::kNear); \ |
| 494 \ |
| 495 __ bind(&check_zero); \ |
| 496 __ lzdr(kDoubleRegZero); \ |
| 497 __ cebr(left_reg, kDoubleRegZero); \ |
| 498 /* left == right != 0. */ \ |
| 499 __ bne(&return_left, Label::kNear); \ |
| 500 /* At this point, both left and right are either 0 or -0. */ \ |
| 501 /* N.B. The following works because +0 + -0 == +0 */ \ |
| 502 /* For max we want logical-and of sign bit: (L + R) */ \ |
| 503 __ ldr(result_reg, left_reg); \ |
| 504 __ aebr(result_reg, right_reg); \ |
| 505 __ b(&done, Label::kNear); \ |
| 506 \ |
| 507 __ bind(&check_nan_left); \ |
| 508 __ cebr(left_reg, left_reg); \ |
| 509 /* left == NaN. */ \ |
| 510 __ bunordered(&return_left, Label::kNear); \ |
| 511 \ |
| 512 __ bind(&return_right); \ |
| 513 if (!right_reg.is(result_reg)) { \ |
| 514 __ ldr(result_reg, right_reg); \ |
| 515 } \ |
| 516 __ b(&done, Label::kNear); \ |
| 517 \ |
| 518 __ bind(&return_left); \ |
| 519 if (!left_reg.is(result_reg)) { \ |
| 520 __ ldr(result_reg, left_reg); \ |
| 521 } \ |
| 522 __ bind(&done); \ |
| 523 } while (0) |
| 524 |
| 525 #define ASSEMBLE_FLOAT_MIN() \ |
| 526 do { \ |
| 527 DoubleRegister left_reg = i.InputDoubleRegister(0); \ |
| 528 DoubleRegister right_reg = i.InputDoubleRegister(1); \ |
| 529 DoubleRegister result_reg = i.OutputDoubleRegister(); \ |
| 530 Label check_nan_left, check_zero, return_left, return_right, done; \ |
| 531 __ cebr(left_reg, right_reg); \ |
| 532 __ bunordered(&check_nan_left, Label::kNear); \ |
| 533 __ beq(&check_zero); \ |
| 534 __ ble(&return_left, Label::kNear); \ |
| 535 __ b(&return_right, Label::kNear); \ |
| 536 \ |
| 537 __ bind(&check_zero); \ |
| 538 __ lzdr(kDoubleRegZero); \ |
| 539 __ cebr(left_reg, kDoubleRegZero); \ |
| 540 /* left == right != 0. */ \ |
| 541 __ bne(&return_left, Label::kNear); \ |
| 542 /* At this point, both left and right are either 0 or -0. */ \ |
| 543 /* N.B. The following works because +0 + -0 == +0 */ \ |
| 544 /* For min we want logical-or of sign bit: -(-L + -R) */ \ |
| 545 __ lcebr(left_reg, left_reg); \ |
| 546 __ ldr(result_reg, left_reg); \ |
| 547 if (left_reg.is(right_reg)) { \ |
| 548 __ aebr(result_reg, right_reg); \ |
| 549 } else { \ |
| 550 __ sebr(result_reg, right_reg); \ |
| 551 } \ |
| 552 __ lcebr(result_reg, result_reg); \ |
| 553 __ b(&done, Label::kNear); \ |
| 554 \ |
| 555 __ bind(&check_nan_left); \ |
| 556 __ cebr(left_reg, left_reg); \ |
| 557 /* left == NaN. */ \ |
| 558 __ bunordered(&return_left, Label::kNear); \ |
| 559 \ |
| 560 __ bind(&return_right); \ |
| 561 if (!right_reg.is(result_reg)) { \ |
| 562 __ ldr(result_reg, right_reg); \ |
| 563 } \ |
| 564 __ b(&done, Label::kNear); \ |
| 565 \ |
| 566 __ bind(&return_left); \ |
| 567 if (!left_reg.is(result_reg)) { \ |
| 568 __ ldr(result_reg, left_reg); \ |
| 569 } \ |
| 570 __ bind(&done); \ |
| 571 } while (0) |
483 // Only MRI mode for these instructions available | 572 // Only MRI mode for these instructions available |
484 #define ASSEMBLE_LOAD_FLOAT(asm_instr) \ | 573 #define ASSEMBLE_LOAD_FLOAT(asm_instr) \ |
485 do { \ | 574 do { \ |
486 DoubleRegister result = i.OutputDoubleRegister(); \ | 575 DoubleRegister result = i.OutputDoubleRegister(); \ |
487 AddressingMode mode = kMode_None; \ | 576 AddressingMode mode = kMode_None; \ |
488 MemOperand operand = i.MemoryOperand(&mode); \ | 577 MemOperand operand = i.MemoryOperand(&mode); \ |
489 __ asm_instr(result, operand); \ | 578 __ asm_instr(result, operand); \ |
490 } while (0) | 579 } while (0) |
491 | 580 |
492 #define ASSEMBLE_LOAD_INTEGER(asm_instr) \ | 581 #define ASSEMBLE_LOAD_INTEGER(asm_instr) \ |
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 __ Move(d1, d3); | 1594 __ Move(d1, d3); |
1506 break; | 1595 break; |
1507 } | 1596 } |
1508 case kS390_Neg32: | 1597 case kS390_Neg32: |
1509 __ lcr(i.OutputRegister(), i.InputRegister(0)); | 1598 __ lcr(i.OutputRegister(), i.InputRegister(0)); |
1510 __ LoadW(i.OutputRegister(), i.OutputRegister()); | 1599 __ LoadW(i.OutputRegister(), i.OutputRegister()); |
1511 break; | 1600 break; |
1512 case kS390_Neg64: | 1601 case kS390_Neg64: |
1513 __ lcgr(i.OutputRegister(), i.InputRegister(0)); | 1602 __ lcgr(i.OutputRegister(), i.InputRegister(0)); |
1514 break; | 1603 break; |
1515 case kS390_MaxDouble: | 1604 case kS390_MaxFloat: |
1516 ASSEMBLE_FLOAT_MAX(); | 1605 ASSEMBLE_FLOAT_MAX(); |
1517 break; | 1606 break; |
| 1607 case kS390_MaxDouble: |
| 1608 ASSEMBLE_DOUBLE_MAX(); |
| 1609 break; |
| 1610 case kS390_MinFloat: |
| 1611 ASSEMBLE_FLOAT_MIN(); |
| 1612 break; |
1518 case kS390_MinDouble: | 1613 case kS390_MinDouble: |
1519 ASSEMBLE_FLOAT_MIN(); | 1614 ASSEMBLE_DOUBLE_MIN(); |
1520 break; | 1615 break; |
1521 case kS390_AbsDouble: | 1616 case kS390_AbsDouble: |
1522 __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); | 1617 __ lpdbr(i.OutputDoubleRegister(), i.InputDoubleRegister(0)); |
1523 break; | 1618 break; |
1524 case kS390_SqrtDouble: | 1619 case kS390_SqrtDouble: |
1525 ASSEMBLE_FLOAT_UNOP(sqdbr); | 1620 ASSEMBLE_FLOAT_UNOP(sqdbr); |
1526 break; | 1621 break; |
1527 case kS390_FloorDouble: | 1622 case kS390_FloorDouble: |
1528 __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0), | 1623 __ fidbra(i.OutputDoubleRegister(), i.InputDoubleRegister(0), |
1529 v8::internal::Assembler::FIDBRA_ROUND_TOWARD_NEG_INF); | 1624 v8::internal::Assembler::FIDBRA_ROUND_TOWARD_NEG_INF); |
(...skipping 922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2452 padding_size -= 2; | 2547 padding_size -= 2; |
2453 } | 2548 } |
2454 } | 2549 } |
2455 } | 2550 } |
2456 | 2551 |
2457 #undef __ | 2552 #undef __ |
2458 | 2553 |
2459 } // namespace compiler | 2554 } // namespace compiler |
2460 } // namespace internal | 2555 } // namespace internal |
2461 } // namespace v8 | 2556 } // namespace v8 |
OLD | NEW |