OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 1462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1473 __ movp(rdx, rdi); | 1473 __ movp(rdx, rdi); |
1474 // Run the native code for the Array function called as a normal function. | 1474 // Run the native code for the Array function called as a normal function. |
1475 // tail call a stub | 1475 // tail call a stub |
1476 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); | 1476 __ LoadRoot(rbx, Heap::kUndefinedValueRootIndex); |
1477 ArrayConstructorStub stub(masm->isolate()); | 1477 ArrayConstructorStub stub(masm->isolate()); |
1478 __ TailCallStub(&stub); | 1478 __ TailCallStub(&stub); |
1479 } | 1479 } |
1480 | 1480 |
1481 | 1481 |
1482 // static | 1482 // static |
| 1483 void Builtins::Generate_MathMaxMin(MacroAssembler* masm, MathMaxMinKind kind) { |
| 1484 // ----------- S t a t e ------------- |
| 1485 // -- rax : number of arguments |
| 1486 // -- rsp[0] : return address |
| 1487 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
| 1488 // -- rsp[(argc + 1) * 8] : receiver |
| 1489 // ----------------------------------- |
| 1490 Condition const cc = (kind == MathMaxMinKind::kMin) ? below : above; |
| 1491 Heap::RootListIndex const root_index = |
| 1492 (kind == MathMaxMinKind::kMin) ? Heap::kInfinityValueRootIndex |
| 1493 : Heap::kMinusInfinityValueRootIndex; |
| 1494 XMMRegister const reg = (kind == MathMaxMinKind::kMin) ? xmm1 : xmm0; |
| 1495 |
| 1496 // Load the accumulator with the default return value (either -Infinity or |
| 1497 // +Infinity), with the tagged value in rdx and the double value in xmm0. |
| 1498 __ LoadRoot(rdx, root_index); |
| 1499 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
| 1500 __ Move(rcx, rax); |
| 1501 |
| 1502 Label done_loop, loop; |
| 1503 __ bind(&loop); |
| 1504 { |
| 1505 // Check if all parameters done. |
| 1506 __ testp(rcx, rcx); |
| 1507 __ j(zero, &done_loop); |
| 1508 |
| 1509 // Load the next parameter tagged value into rbx. |
| 1510 __ movp(rbx, Operand(rsp, rcx, times_pointer_size, 0)); |
| 1511 |
| 1512 // Load the double value of the parameter into xmm1, maybe converting the |
| 1513 // parameter to a number first using the ToNumberStub if necessary. |
| 1514 Label convert, convert_smi, convert_number, done_convert; |
| 1515 __ bind(&convert); |
| 1516 __ JumpIfSmi(rbx, &convert_smi); |
| 1517 __ JumpIfRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
| 1518 Heap::kHeapNumberMapRootIndex, &convert_number); |
| 1519 { |
| 1520 // Parameter is not a Number, use the ToNumberStub to convert it. |
| 1521 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1522 __ Integer32ToSmi(rax, rax); |
| 1523 __ Integer32ToSmi(rcx, rcx); |
| 1524 __ Push(rax); |
| 1525 __ Push(rcx); |
| 1526 __ Push(rdx); |
| 1527 __ movp(rax, rbx); |
| 1528 ToNumberStub stub(masm->isolate()); |
| 1529 __ CallStub(&stub); |
| 1530 __ movp(rbx, rax); |
| 1531 __ Pop(rdx); |
| 1532 __ Pop(rcx); |
| 1533 __ Pop(rax); |
| 1534 { |
| 1535 // Restore the double accumulator value (xmm0). |
| 1536 Label restore_smi, done_restore; |
| 1537 __ JumpIfSmi(rdx, &restore_smi, Label::kNear); |
| 1538 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
| 1539 __ jmp(&done_restore, Label::kNear); |
| 1540 __ bind(&restore_smi); |
| 1541 __ SmiToDouble(xmm0, rdx); |
| 1542 __ bind(&done_restore); |
| 1543 } |
| 1544 __ SmiToInteger32(rcx, rcx); |
| 1545 __ SmiToInteger32(rax, rax); |
| 1546 } |
| 1547 __ jmp(&convert); |
| 1548 __ bind(&convert_number); |
| 1549 __ Movsd(xmm1, FieldOperand(rbx, HeapNumber::kValueOffset)); |
| 1550 __ jmp(&done_convert, Label::kNear); |
| 1551 __ bind(&convert_smi); |
| 1552 __ SmiToDouble(xmm1, rbx); |
| 1553 __ bind(&done_convert); |
| 1554 |
| 1555 // Perform the actual comparison with the accumulator value on the left hand |
| 1556 // side (xmm0) and the next parameter value on the right hand side (xmm1). |
| 1557 Label compare_equal, compare_nan, compare_swap, done_compare; |
| 1558 __ Ucomisd(xmm0, xmm1); |
| 1559 __ j(parity_even, &compare_nan, Label::kNear); |
| 1560 __ j(cc, &done_compare, Label::kNear); |
| 1561 __ j(equal, &compare_equal, Label::kNear); |
| 1562 |
| 1563 // Result is on the right hand side. |
| 1564 __ bind(&compare_swap); |
| 1565 __ Movaps(xmm0, xmm1); |
| 1566 __ Move(rdx, rbx); |
| 1567 __ jmp(&done_compare, Label::kNear); |
| 1568 |
| 1569 // At least one side is NaN, which means that the result will be NaN too. |
| 1570 __ bind(&compare_nan); |
| 1571 __ LoadRoot(rdx, Heap::kNanValueRootIndex); |
| 1572 __ Movsd(xmm0, FieldOperand(rdx, HeapNumber::kValueOffset)); |
| 1573 __ jmp(&done_compare, Label::kNear); |
| 1574 |
| 1575 // Left and right hand side are equal, check for -0 vs. +0. |
| 1576 __ bind(&compare_equal); |
| 1577 __ Movmskpd(kScratchRegister, reg); |
| 1578 __ testl(kScratchRegister, Immediate(1)); |
| 1579 __ j(not_zero, &compare_swap); |
| 1580 |
| 1581 __ bind(&done_compare); |
| 1582 __ decp(rcx); |
| 1583 __ jmp(&loop); |
| 1584 } |
| 1585 |
| 1586 __ bind(&done_loop); |
| 1587 __ PopReturnAddressTo(rcx); |
| 1588 __ leap(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize)); |
| 1589 __ PushReturnAddressFrom(rcx); |
| 1590 __ movp(rax, rdx); |
| 1591 __ Ret(); |
| 1592 } |
| 1593 |
| 1594 // static |
1483 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { | 1595 void Builtins::Generate_NumberConstructor(MacroAssembler* masm) { |
1484 // ----------- S t a t e ------------- | 1596 // ----------- S t a t e ------------- |
1485 // -- rax : number of arguments | 1597 // -- rax : number of arguments |
1486 // -- rdi : constructor function | 1598 // -- rdi : constructor function |
1487 // -- rsp[0] : return address | 1599 // -- rsp[0] : return address |
1488 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1600 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1489 // -- rsp[(argc + 1) * 8] : receiver | 1601 // -- rsp[(argc + 1) * 8] : receiver |
1490 // ----------------------------------- | 1602 // ----------------------------------- |
1491 | 1603 |
1492 // 1. Load the first argument into rax and get rid of the rest (including the | 1604 // 1. Load the first argument into rax and get rid of the rest (including the |
(...skipping 1259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2752 __ ret(0); | 2864 __ ret(0); |
2753 } | 2865 } |
2754 | 2866 |
2755 | 2867 |
2756 #undef __ | 2868 #undef __ |
2757 | 2869 |
2758 } // namespace internal | 2870 } // namespace internal |
2759 } // namespace v8 | 2871 } // namespace v8 |
2760 | 2872 |
2761 #endif // V8_TARGET_ARCH_X64 | 2873 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |