| 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 |