Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.ad @ 18041:52b4284cb496
Merge with jdk8u20-b26
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Wed, 15 Oct 2014 16:02:50 +0200 |
parents | 89152779163c 0bf37f737702 |
children |
comparison
equal
deleted
inserted
replaced
17606:45d7b2c7029d | 18041:52b4284cb496 |
---|---|
686 | 686 |
687 int Compile::ConstantTable::calculate_table_base_offset() const { | 687 int Compile::ConstantTable::calculate_table_base_offset() const { |
688 return 0; // absolute addressing, no offset | 688 return 0; // absolute addressing, no offset |
689 } | 689 } |
690 | 690 |
691 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } | |
692 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { | |
693 ShouldNotReachHere(); | |
694 } | |
695 | |
691 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { | 696 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { |
692 // Empty encoding | 697 // Empty encoding |
693 } | 698 } |
694 | 699 |
695 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { | 700 uint MachConstantBaseNode::size(PhaseRegAlloc* ra_) const { |
706 //============================================================================= | 711 //============================================================================= |
707 #ifndef PRODUCT | 712 #ifndef PRODUCT |
708 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { | 713 void MachPrologNode::format(PhaseRegAlloc* ra_, outputStream* st) const { |
709 Compile* C = ra_->C; | 714 Compile* C = ra_->C; |
710 | 715 |
711 int framesize = C->frame_slots() << LogBytesPerInt; | 716 int framesize = C->frame_size_in_bytes(); |
717 int bangsize = C->bang_size_in_bytes(); | |
712 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | 718 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); |
713 // Remove wordSize for return addr which is already pushed. | 719 // Remove wordSize for return addr which is already pushed. |
714 framesize -= wordSize; | 720 framesize -= wordSize; |
715 | 721 |
716 if (C->need_stack_bang(framesize)) { | 722 if (C->need_stack_bang(bangsize)) { |
717 framesize -= wordSize; | 723 framesize -= wordSize; |
718 st->print("# stack bang"); | 724 st->print("# stack bang (%d bytes)", bangsize); |
719 st->print("\n\t"); | 725 st->print("\n\t"); |
720 st->print("pushq rbp\t# Save rbp"); | 726 st->print("pushq rbp\t# Save rbp"); |
721 if (framesize) { | 727 if (framesize) { |
722 st->print("\n\t"); | 728 st->print("\n\t"); |
723 st->print("subq rsp, #%d\t# Create frame",framesize); | 729 st->print("subq rsp, #%d\t# Create frame",framesize); |
744 | 750 |
745 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { | 751 void MachPrologNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const { |
746 Compile* C = ra_->C; | 752 Compile* C = ra_->C; |
747 MacroAssembler _masm(&cbuf); | 753 MacroAssembler _masm(&cbuf); |
748 | 754 |
749 int framesize = C->frame_slots() << LogBytesPerInt; | 755 int framesize = C->frame_size_in_bytes(); |
750 | 756 int bangsize = C->bang_size_in_bytes(); |
751 __ verified_entry(framesize, C->need_stack_bang(framesize), false); | 757 |
758 __ verified_entry(framesize, C->need_stack_bang(bangsize)?bangsize:0, false); | |
752 | 759 |
753 C->set_frame_complete(cbuf.insts_size()); | 760 C->set_frame_complete(cbuf.insts_size()); |
754 | 761 |
755 if (C->has_mach_constant_base_node()) { | 762 if (C->has_mach_constant_base_node()) { |
756 // NOTE: We set the table base offset here because users might be | 763 // NOTE: We set the table base offset here because users might be |
779 if (C->max_vector_size() > 16) { | 786 if (C->max_vector_size() > 16) { |
780 st->print("vzeroupper"); | 787 st->print("vzeroupper"); |
781 st->cr(); st->print("\t"); | 788 st->cr(); st->print("\t"); |
782 } | 789 } |
783 | 790 |
784 int framesize = C->frame_slots() << LogBytesPerInt; | 791 int framesize = C->frame_size_in_bytes(); |
785 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | 792 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); |
786 // Remove word for return adr already pushed | 793 // Remove word for return adr already pushed |
787 // and RBP | 794 // and RBP |
788 framesize -= 2*wordSize; | 795 framesize -= 2*wordSize; |
789 | 796 |
815 // wide vectors to avoid AVX <-> SSE transition penalty during call. | 822 // wide vectors to avoid AVX <-> SSE transition penalty during call. |
816 MacroAssembler _masm(&cbuf); | 823 MacroAssembler _masm(&cbuf); |
817 __ vzeroupper(); | 824 __ vzeroupper(); |
818 } | 825 } |
819 | 826 |
820 int framesize = C->frame_slots() << LogBytesPerInt; | 827 int framesize = C->frame_size_in_bytes(); |
821 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); | 828 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned"); |
822 // Remove word for return adr already pushed | 829 // Remove word for return adr already pushed |
823 // and RBP | 830 // and RBP |
824 framesize -= 2*wordSize; | 831 framesize -= 2*wordSize; |
825 | 832 |
1432 uint MachUEPNode::size(PhaseRegAlloc* ra_) const | 1439 uint MachUEPNode::size(PhaseRegAlloc* ra_) const |
1433 { | 1440 { |
1434 return MachNode::size(ra_); // too many variables; just compute it | 1441 return MachNode::size(ra_); // too many variables; just compute it |
1435 // the hard way | 1442 // the hard way |
1436 } | 1443 } |
1437 | 1444 |
1438 | 1445 |
1439 //============================================================================= | 1446 //============================================================================= |
1440 uint size_exception_handler() | |
1441 { | |
1442 // NativeCall instruction size is the same as NativeJump. | |
1443 // Note that this value is also credited (in output.cpp) to | |
1444 // the size of the code section. | |
1445 return NativeJump::instruction_size; | |
1446 } | |
1447 | |
1448 // Emit exception handler code. | |
1449 int emit_exception_handler(CodeBuffer& cbuf) | |
1450 { | |
1451 | |
1452 // Note that the code buffer's insts_mark is always relative to insts. | |
1453 // That's why we must use the macroassembler to generate a handler. | |
1454 MacroAssembler _masm(&cbuf); | |
1455 address base = | |
1456 __ start_a_stub(size_exception_handler()); | |
1457 if (base == NULL) return 0; // CodeBuffer::expand failed | |
1458 int offset = __ offset(); | |
1459 __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point())); | |
1460 assert(__ offset() - offset <= (int) size_exception_handler(), "overflow"); | |
1461 __ end_a_stub(); | |
1462 return offset; | |
1463 } | |
1464 | |
1465 uint size_deopt_handler() | |
1466 { | |
1467 // three 5 byte instructions | |
1468 return 15; | |
1469 } | |
1470 | |
1471 // Emit deopt handler code. | |
1472 int emit_deopt_handler(CodeBuffer& cbuf) | |
1473 { | |
1474 | |
1475 // Note that the code buffer's insts_mark is always relative to insts. | |
1476 // That's why we must use the macroassembler to generate a handler. | |
1477 MacroAssembler _masm(&cbuf); | |
1478 address base = | |
1479 __ start_a_stub(size_deopt_handler()); | |
1480 if (base == NULL) return 0; // CodeBuffer::expand failed | |
1481 int offset = __ offset(); | |
1482 address the_pc = (address) __ pc(); | |
1483 Label next; | |
1484 // push a "the_pc" on the stack without destroying any registers | |
1485 // as they all may be live. | |
1486 | |
1487 // push address of "next" | |
1488 __ call(next, relocInfo::none); // reloc none is fine since it is a disp32 | |
1489 __ bind(next); | |
1490 // adjust it so it matches "the_pc" | |
1491 __ subptr(Address(rsp, 0), __ offset() - offset); | |
1492 __ jump(RuntimeAddress(SharedRuntime::deopt_blob()->unpack())); | |
1493 assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow"); | |
1494 __ end_a_stub(); | |
1495 return offset; | |
1496 } | |
1497 | 1447 |
1498 int Matcher::regnum_to_fpu_offset(int regnum) | 1448 int Matcher::regnum_to_fpu_offset(int regnum) |
1499 { | 1449 { |
1500 return regnum - 32; // The FP registers are in the second chunk | 1450 return regnum - 32; // The FP registers are in the second chunk |
1501 } | 1451 } |
1539 // No additional cost for CMOVL. | 1489 // No additional cost for CMOVL. |
1540 const int Matcher::long_cmove_cost() { return 0; } | 1490 const int Matcher::long_cmove_cost() { return 0; } |
1541 | 1491 |
1542 // No CMOVF/CMOVD with SSE2 | 1492 // No CMOVF/CMOVD with SSE2 |
1543 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } | 1493 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } |
1494 | |
1495 // Does the CPU require late expand (see block.cpp for description of late expand)? | |
1496 const bool Matcher::require_postalloc_expand = false; | |
1544 | 1497 |
1545 // Should the Matcher clone shifts on addressing modes, expecting them | 1498 // Should the Matcher clone shifts on addressing modes, expecting them |
1546 // to be subsumed into complex addressing expressions or compute them | 1499 // to be subsumed into complex addressing expressions or compute them |
1547 // into registers? True for Intel but false for most RISCs | 1500 // into registers? True for Intel but false for most RISCs |
1548 const bool Matcher::clone_shift_expressions = true; | 1501 const bool Matcher::clone_shift_expressions = true; |
1645 return LONG_RDX_REG_mask(); | 1598 return LONG_RDX_REG_mask(); |
1646 } | 1599 } |
1647 | 1600 |
1648 const RegMask Matcher::method_handle_invoke_SP_save_mask() { | 1601 const RegMask Matcher::method_handle_invoke_SP_save_mask() { |
1649 return PTR_RBP_REG_mask(); | 1602 return PTR_RBP_REG_mask(); |
1650 } | |
1651 | |
1652 const RegMask Matcher::mathExactI_result_proj_mask() { | |
1653 return INT_RAX_REG_mask(); | |
1654 } | |
1655 | |
1656 const RegMask Matcher::mathExactL_result_proj_mask() { | |
1657 return LONG_RAX_REG_mask(); | |
1658 } | |
1659 | |
1660 const RegMask Matcher::mathExactI_flags_proj_mask() { | |
1661 return INT_FLAGS_mask(); | |
1662 } | 1603 } |
1663 | 1604 |
1664 %} | 1605 %} |
1665 | 1606 |
1666 //----------ENCODING BLOCK----------------------------------------------------- | 1607 //----------ENCODING BLOCK----------------------------------------------------- |
2586 enc_class Push_SrcXD(regD src) %{ | 2527 enc_class Push_SrcXD(regD src) %{ |
2587 MacroAssembler _masm(&cbuf); | 2528 MacroAssembler _masm(&cbuf); |
2588 __ subptr(rsp, 8); | 2529 __ subptr(rsp, 8); |
2589 __ movdbl(Address(rsp, 0), $src$$XMMRegister); | 2530 __ movdbl(Address(rsp, 0), $src$$XMMRegister); |
2590 __ fld_d(Address(rsp, 0)); | 2531 __ fld_d(Address(rsp, 0)); |
2591 %} | |
2592 | |
2593 | |
2594 // obj: object to lock | |
2595 // box: box address (header location) -- killed | |
2596 // tmp: rax -- killed | |
2597 // scr: rbx -- killed | |
2598 // | |
2599 // What follows is a direct transliteration of fast_lock() and fast_unlock() | |
2600 // from i486.ad. See that file for comments. | |
2601 // TODO: where possible switch from movq (r, 0) to movl(r,0) and | |
2602 // use the shorter encoding. (Movl clears the high-order 32-bits). | |
2603 | |
2604 | |
2605 enc_class Fast_Lock(rRegP obj, rRegP box, rax_RegI tmp, rRegP scr) | |
2606 %{ | |
2607 Register objReg = as_Register((int)$obj$$reg); | |
2608 Register boxReg = as_Register((int)$box$$reg); | |
2609 Register tmpReg = as_Register($tmp$$reg); | |
2610 Register scrReg = as_Register($scr$$reg); | |
2611 MacroAssembler masm(&cbuf); | |
2612 | |
2613 // Verify uniqueness of register assignments -- necessary but not sufficient | |
2614 assert (objReg != boxReg && objReg != tmpReg && | |
2615 objReg != scrReg && tmpReg != scrReg, "invariant") ; | |
2616 | |
2617 if (_counters != NULL) { | |
2618 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); | |
2619 } | |
2620 if (EmitSync & 1) { | |
2621 // Without cast to int32_t a movptr will destroy r10 which is typically obj | |
2622 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; | |
2623 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; | |
2624 } else | |
2625 if (EmitSync & 2) { | |
2626 Label DONE_LABEL; | |
2627 if (UseBiasedLocking) { | |
2628 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. | |
2629 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, false, DONE_LABEL, NULL, _counters); | |
2630 } | |
2631 // QQQ was movl... | |
2632 masm.movptr(tmpReg, 0x1); | |
2633 masm.orptr(tmpReg, Address(objReg, 0)); | |
2634 masm.movptr(Address(boxReg, 0), tmpReg); | |
2635 if (os::is_MP()) { | |
2636 masm.lock(); | |
2637 } | |
2638 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg | |
2639 masm.jcc(Assembler::equal, DONE_LABEL); | |
2640 | |
2641 // Recursive locking | |
2642 masm.subptr(tmpReg, rsp); | |
2643 masm.andptr(tmpReg, 7 - os::vm_page_size()); | |
2644 masm.movptr(Address(boxReg, 0), tmpReg); | |
2645 | |
2646 masm.bind(DONE_LABEL); | |
2647 masm.nop(); // avoid branch to branch | |
2648 } else { | |
2649 Label DONE_LABEL, IsInflated, Egress; | |
2650 | |
2651 masm.movptr(tmpReg, Address(objReg, 0)) ; | |
2652 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased | |
2653 masm.jcc (Assembler::notZero, IsInflated) ; | |
2654 | |
2655 // it's stack-locked, biased or neutral | |
2656 // TODO: optimize markword triage order to reduce the number of | |
2657 // conditional branches in the most common cases. | |
2658 // Beware -- there's a subtle invariant that fetch of the markword | |
2659 // at [FETCH], below, will never observe a biased encoding (*101b). | |
2660 // If this invariant is not held we'll suffer exclusion (safety) failure. | |
2661 | |
2662 if (UseBiasedLocking && !UseOptoBiasInlining) { | |
2663 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); | |
2664 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] | |
2665 } | |
2666 | |
2667 // was q will it destroy high? | |
2668 masm.orl (tmpReg, 1) ; | |
2669 masm.movptr(Address(boxReg, 0), tmpReg) ; | |
2670 if (os::is_MP()) { masm.lock(); } | |
2671 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg | |
2672 if (_counters != NULL) { | |
2673 masm.cond_inc32(Assembler::equal, | |
2674 ExternalAddress((address) _counters->fast_path_entry_count_addr())); | |
2675 } | |
2676 masm.jcc (Assembler::equal, DONE_LABEL); | |
2677 | |
2678 // Recursive locking | |
2679 masm.subptr(tmpReg, rsp); | |
2680 masm.andptr(tmpReg, 7 - os::vm_page_size()); | |
2681 masm.movptr(Address(boxReg, 0), tmpReg); | |
2682 if (_counters != NULL) { | |
2683 masm.cond_inc32(Assembler::equal, | |
2684 ExternalAddress((address) _counters->fast_path_entry_count_addr())); | |
2685 } | |
2686 masm.jmp (DONE_LABEL) ; | |
2687 | |
2688 masm.bind (IsInflated) ; | |
2689 // It's inflated | |
2690 | |
2691 // TODO: someday avoid the ST-before-CAS penalty by | |
2692 // relocating (deferring) the following ST. | |
2693 // We should also think about trying a CAS without having | |
2694 // fetched _owner. If the CAS is successful we may | |
2695 // avoid an RTO->RTS upgrade on the $line. | |
2696 // Without cast to int32_t a movptr will destroy r10 which is typically obj | |
2697 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; | |
2698 | |
2699 masm.mov (boxReg, tmpReg) ; | |
2700 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; | |
2701 masm.testptr(tmpReg, tmpReg) ; | |
2702 masm.jcc (Assembler::notZero, DONE_LABEL) ; | |
2703 | |
2704 // It's inflated and appears unlocked | |
2705 if (os::is_MP()) { masm.lock(); } | |
2706 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; | |
2707 // Intentional fall-through into DONE_LABEL ... | |
2708 | |
2709 masm.bind (DONE_LABEL) ; | |
2710 masm.nop () ; // avoid jmp to jmp | |
2711 } | |
2712 %} | |
2713 | |
2714 // obj: object to unlock | |
2715 // box: box address (displaced header location), killed | |
2716 // RBX: killed tmp; cannot be obj nor box | |
2717 enc_class Fast_Unlock(rRegP obj, rax_RegP box, rRegP tmp) | |
2718 %{ | |
2719 | |
2720 Register objReg = as_Register($obj$$reg); | |
2721 Register boxReg = as_Register($box$$reg); | |
2722 Register tmpReg = as_Register($tmp$$reg); | |
2723 MacroAssembler masm(&cbuf); | |
2724 | |
2725 if (EmitSync & 4) { | |
2726 masm.cmpptr(rsp, 0) ; | |
2727 } else | |
2728 if (EmitSync & 8) { | |
2729 Label DONE_LABEL; | |
2730 if (UseBiasedLocking) { | |
2731 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); | |
2732 } | |
2733 | |
2734 // Check whether the displaced header is 0 | |
2735 //(=> recursive unlock) | |
2736 masm.movptr(tmpReg, Address(boxReg, 0)); | |
2737 masm.testptr(tmpReg, tmpReg); | |
2738 masm.jcc(Assembler::zero, DONE_LABEL); | |
2739 | |
2740 // If not recursive lock, reset the header to displaced header | |
2741 if (os::is_MP()) { | |
2742 masm.lock(); | |
2743 } | |
2744 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box | |
2745 masm.bind(DONE_LABEL); | |
2746 masm.nop(); // avoid branch to branch | |
2747 } else { | |
2748 Label DONE_LABEL, Stacked, CheckSucc ; | |
2749 | |
2750 if (UseBiasedLocking && !UseOptoBiasInlining) { | |
2751 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); | |
2752 } | |
2753 | |
2754 masm.movptr(tmpReg, Address(objReg, 0)) ; | |
2755 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; | |
2756 masm.jcc (Assembler::zero, DONE_LABEL) ; | |
2757 masm.testl (tmpReg, 0x02) ; | |
2758 masm.jcc (Assembler::zero, Stacked) ; | |
2759 | |
2760 // It's inflated | |
2761 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; | |
2762 masm.xorptr(boxReg, r15_thread) ; | |
2763 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; | |
2764 masm.jcc (Assembler::notZero, DONE_LABEL) ; | |
2765 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; | |
2766 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; | |
2767 masm.jcc (Assembler::notZero, CheckSucc) ; | |
2768 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; | |
2769 masm.jmp (DONE_LABEL) ; | |
2770 | |
2771 if ((EmitSync & 65536) == 0) { | |
2772 Label LSuccess, LGoSlowPath ; | |
2773 masm.bind (CheckSucc) ; | |
2774 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; | |
2775 masm.jcc (Assembler::zero, LGoSlowPath) ; | |
2776 | |
2777 // I'd much rather use lock:andl m->_owner, 0 as it's faster than the | |
2778 // the explicit ST;MEMBAR combination, but masm doesn't currently support | |
2779 // "ANDQ M,IMM". Don't use MFENCE here. lock:add to TOS, xchg, etc | |
2780 // are all faster when the write buffer is populated. | |
2781 masm.movptr (Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; | |
2782 if (os::is_MP()) { | |
2783 masm.lock () ; masm.addl (Address(rsp, 0), 0) ; | |
2784 } | |
2785 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; | |
2786 masm.jcc (Assembler::notZero, LSuccess) ; | |
2787 | |
2788 masm.movptr (boxReg, (int32_t)NULL_WORD) ; // box is really EAX | |
2789 if (os::is_MP()) { masm.lock(); } | |
2790 masm.cmpxchgptr(r15_thread, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)); | |
2791 masm.jcc (Assembler::notEqual, LSuccess) ; | |
2792 // Intentional fall-through into slow-path | |
2793 | |
2794 masm.bind (LGoSlowPath) ; | |
2795 masm.orl (boxReg, 1) ; // set ICC.ZF=0 to indicate failure | |
2796 masm.jmp (DONE_LABEL) ; | |
2797 | |
2798 masm.bind (LSuccess) ; | |
2799 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success | |
2800 masm.jmp (DONE_LABEL) ; | |
2801 } | |
2802 | |
2803 masm.bind (Stacked) ; | |
2804 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch | |
2805 if (os::is_MP()) { masm.lock(); } | |
2806 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box | |
2807 | |
2808 if (EmitSync & 65536) { | |
2809 masm.bind (CheckSucc) ; | |
2810 } | |
2811 masm.bind(DONE_LABEL); | |
2812 if (EmitSync & 32768) { | |
2813 masm.nop(); // avoid branch to branch | |
2814 } | |
2815 } | |
2816 %} | 2532 %} |
2817 | 2533 |
2818 | 2534 |
2819 enc_class enc_rethrow() | 2535 enc_class enc_rethrow() |
2820 %{ | 2536 %{ |
2951 %} | 2667 %} |
2952 | 2668 |
2953 c_calling_convention | 2669 c_calling_convention |
2954 %{ | 2670 %{ |
2955 // This is obviously always outgoing | 2671 // This is obviously always outgoing |
2956 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); | 2672 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); |
2957 %} | 2673 %} |
2958 | 2674 |
2959 // Location of compiled Java return values. Same as C for now. | 2675 // Location of compiled Java return values. Same as C for now. |
2960 return_value | 2676 return_value |
2961 %{ | 2677 %{ |
6249 %} | 5965 %} |
6250 ins_pipe(ialu_reg); | 5966 ins_pipe(ialu_reg); |
6251 %} | 5967 %} |
6252 | 5968 |
6253 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ | 5969 instruct countTrailingZerosI(rRegI dst, rRegI src, rFlagsReg cr) %{ |
5970 predicate(UseCountTrailingZerosInstruction); | |
5971 match(Set dst (CountTrailingZerosI src)); | |
5972 effect(KILL cr); | |
5973 | |
5974 format %{ "tzcntl $dst, $src\t# count trailing zeros (int)" %} | |
5975 ins_encode %{ | |
5976 __ tzcntl($dst$$Register, $src$$Register); | |
5977 %} | |
5978 ins_pipe(ialu_reg); | |
5979 %} | |
5980 | |
5981 instruct countTrailingZerosI_bsf(rRegI dst, rRegI src, rFlagsReg cr) %{ | |
5982 predicate(!UseCountTrailingZerosInstruction); | |
6254 match(Set dst (CountTrailingZerosI src)); | 5983 match(Set dst (CountTrailingZerosI src)); |
6255 effect(KILL cr); | 5984 effect(KILL cr); |
6256 | 5985 |
6257 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" | 5986 format %{ "bsfl $dst, $src\t# count trailing zeros (int)\n\t" |
6258 "jnz done\n\t" | 5987 "jnz done\n\t" |
6268 %} | 5997 %} |
6269 ins_pipe(ialu_reg); | 5998 ins_pipe(ialu_reg); |
6270 %} | 5999 %} |
6271 | 6000 |
6272 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ | 6001 instruct countTrailingZerosL(rRegI dst, rRegL src, rFlagsReg cr) %{ |
6002 predicate(UseCountTrailingZerosInstruction); | |
6003 match(Set dst (CountTrailingZerosL src)); | |
6004 effect(KILL cr); | |
6005 | |
6006 format %{ "tzcntq $dst, $src\t# count trailing zeros (long)" %} | |
6007 ins_encode %{ | |
6008 __ tzcntq($dst$$Register, $src$$Register); | |
6009 %} | |
6010 ins_pipe(ialu_reg); | |
6011 %} | |
6012 | |
6013 instruct countTrailingZerosL_bsf(rRegI dst, rRegL src, rFlagsReg cr) %{ | |
6014 predicate(!UseCountTrailingZerosInstruction); | |
6273 match(Set dst (CountTrailingZerosL src)); | 6015 match(Set dst (CountTrailingZerosL src)); |
6274 effect(KILL cr); | 6016 effect(KILL cr); |
6275 | 6017 |
6276 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" | 6018 format %{ "bsfq $dst, $src\t# count trailing zeros (long)\n\t" |
6277 "jnz done\n\t" | 6019 "jnz done\n\t" |
6346 // Memory barrier flavors | 6088 // Memory barrier flavors |
6347 | 6089 |
6348 instruct membar_acquire() | 6090 instruct membar_acquire() |
6349 %{ | 6091 %{ |
6350 match(MemBarAcquire); | 6092 match(MemBarAcquire); |
6093 match(LoadFence); | |
6351 ins_cost(0); | 6094 ins_cost(0); |
6352 | 6095 |
6353 size(0); | 6096 size(0); |
6354 format %{ "MEMBAR-acquire ! (empty encoding)" %} | 6097 format %{ "MEMBAR-acquire ! (empty encoding)" %} |
6355 ins_encode(); | 6098 ins_encode(); |
6368 %} | 6111 %} |
6369 | 6112 |
6370 instruct membar_release() | 6113 instruct membar_release() |
6371 %{ | 6114 %{ |
6372 match(MemBarRelease); | 6115 match(MemBarRelease); |
6116 match(StoreFence); | |
6373 ins_cost(0); | 6117 ins_cost(0); |
6374 | 6118 |
6375 size(0); | 6119 size(0); |
6376 format %{ "MEMBAR-release ! (empty encoding)" %} | 6120 format %{ "MEMBAR-release ! (empty encoding)" %} |
6377 ins_encode(); | 6121 ins_encode(); |
6951 %} | 6695 %} |
6952 | 6696 |
6953 //----------Arithmetic Instructions-------------------------------------------- | 6697 //----------Arithmetic Instructions-------------------------------------------- |
6954 //----------Addition Instructions---------------------------------------------- | 6698 //----------Addition Instructions---------------------------------------------- |
6955 | 6699 |
6956 instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) | |
6957 %{ | |
6958 match(AddExactI dst src); | |
6959 effect(DEF cr); | |
6960 | |
6961 format %{ "addl $dst, $src\t# addExact int" %} | |
6962 ins_encode %{ | |
6963 __ addl($dst$$Register, $src$$Register); | |
6964 %} | |
6965 ins_pipe(ialu_reg_reg); | |
6966 %} | |
6967 | |
6968 instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) | |
6969 %{ | |
6970 match(AddExactI dst src); | |
6971 effect(DEF cr); | |
6972 | |
6973 format %{ "addl $dst, $src\t# addExact int" %} | |
6974 ins_encode %{ | |
6975 __ addl($dst$$Register, $src$$constant); | |
6976 %} | |
6977 ins_pipe(ialu_reg_reg); | |
6978 %} | |
6979 | |
6980 instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
6981 %{ | |
6982 match(AddExactI dst (LoadI src)); | |
6983 effect(DEF cr); | |
6984 | |
6985 ins_cost(125); // XXX | |
6986 format %{ "addl $dst, $src\t# addExact int" %} | |
6987 ins_encode %{ | |
6988 __ addl($dst$$Register, $src$$Address); | |
6989 %} | |
6990 | |
6991 ins_pipe(ialu_reg_mem); | |
6992 %} | |
6993 | |
6994 instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) | |
6995 %{ | |
6996 match(AddExactL dst src); | |
6997 effect(DEF cr); | |
6998 | |
6999 format %{ "addq $dst, $src\t# addExact long" %} | |
7000 ins_encode %{ | |
7001 __ addq($dst$$Register, $src$$Register); | |
7002 %} | |
7003 ins_pipe(ialu_reg_reg); | |
7004 %} | |
7005 | |
7006 instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr) | |
7007 %{ | |
7008 match(AddExactL dst src); | |
7009 effect(DEF cr); | |
7010 | |
7011 format %{ "addq $dst, $src\t# addExact long" %} | |
7012 ins_encode %{ | |
7013 __ addq($dst$$Register, $src$$constant); | |
7014 %} | |
7015 ins_pipe(ialu_reg_reg); | |
7016 %} | |
7017 | |
7018 instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr) | |
7019 %{ | |
7020 match(AddExactL dst (LoadL src)); | |
7021 effect(DEF cr); | |
7022 | |
7023 ins_cost(125); // XXX | |
7024 format %{ "addq $dst, $src\t# addExact long" %} | |
7025 ins_encode %{ | |
7026 __ addq($dst$$Register, $src$$Address); | |
7027 %} | |
7028 | |
7029 ins_pipe(ialu_reg_mem); | |
7030 %} | |
7031 | |
7032 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | 6700 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) |
7033 %{ | 6701 %{ |
7034 match(Set dst (AddI dst src)); | 6702 match(Set dst (AddI dst src)); |
7035 effect(KILL cr); | 6703 effect(KILL cr); |
7036 | 6704 |
7639 opcode(0x81); /* Opcode 81 /5 id */ | 7307 opcode(0x81); /* Opcode 81 /5 id */ |
7640 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); | 7308 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); |
7641 ins_pipe(ialu_mem_imm); | 7309 ins_pipe(ialu_mem_imm); |
7642 %} | 7310 %} |
7643 | 7311 |
7644 instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) | |
7645 %{ | |
7646 match(SubExactI dst src); | |
7647 effect(DEF cr); | |
7648 | |
7649 format %{ "subl $dst, $src\t# subExact int" %} | |
7650 ins_encode %{ | |
7651 __ subl($dst$$Register, $src$$Register); | |
7652 %} | |
7653 ins_pipe(ialu_reg_reg); | |
7654 %} | |
7655 | |
7656 instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) | |
7657 %{ | |
7658 match(SubExactI dst src); | |
7659 effect(DEF cr); | |
7660 | |
7661 format %{ "subl $dst, $src\t# subExact int" %} | |
7662 ins_encode %{ | |
7663 __ subl($dst$$Register, $src$$constant); | |
7664 %} | |
7665 ins_pipe(ialu_reg_reg); | |
7666 %} | |
7667 | |
7668 instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
7669 %{ | |
7670 match(SubExactI dst (LoadI src)); | |
7671 effect(DEF cr); | |
7672 | |
7673 ins_cost(125); | |
7674 format %{ "subl $dst, $src\t# subExact int" %} | |
7675 ins_encode %{ | |
7676 __ subl($dst$$Register, $src$$Address); | |
7677 %} | |
7678 ins_pipe(ialu_reg_mem); | |
7679 %} | |
7680 | |
7681 instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) | |
7682 %{ | |
7683 match(SubExactL dst src); | |
7684 effect(DEF cr); | |
7685 | |
7686 format %{ "subq $dst, $src\t# subExact long" %} | |
7687 ins_encode %{ | |
7688 __ subq($dst$$Register, $src$$Register); | |
7689 %} | |
7690 ins_pipe(ialu_reg_reg); | |
7691 %} | |
7692 | |
7693 instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr) | |
7694 %{ | |
7695 match(SubExactL dst (LoadL src)); | |
7696 effect(DEF cr); | |
7697 | |
7698 format %{ "subq $dst, $src\t# subExact long" %} | |
7699 ins_encode %{ | |
7700 __ subq($dst$$Register, $src$$constant); | |
7701 %} | |
7702 ins_pipe(ialu_reg_reg); | |
7703 %} | |
7704 | |
7705 instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
7706 %{ | |
7707 match(SubExactI dst src); | |
7708 effect(DEF cr); | |
7709 | |
7710 ins_cost(125); | |
7711 format %{ "subq $dst, $src\t# subExact long" %} | |
7712 ins_encode %{ | |
7713 __ subq($dst$$Register, $src$$Address); | |
7714 %} | |
7715 ins_pipe(ialu_reg_mem); | |
7716 %} | |
7717 | |
7718 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | 7312 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) |
7719 %{ | 7313 %{ |
7720 match(Set dst (SubL dst src)); | 7314 match(Set dst (SubL dst src)); |
7721 effect(KILL cr); | 7315 effect(KILL cr); |
7722 | 7316 |
7829 opcode(0xF7, 0x03); // Opcode F7 /3 | 7423 opcode(0xF7, 0x03); // Opcode F7 /3 |
7830 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | 7424 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); |
7831 ins_pipe(ialu_reg); | 7425 ins_pipe(ialu_reg); |
7832 %} | 7426 %} |
7833 | 7427 |
7834 instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr) | |
7835 %{ | |
7836 match(NegExactI dst); | |
7837 effect(KILL cr); | |
7838 | |
7839 format %{ "negl $dst\t# negExact int" %} | |
7840 ins_encode %{ | |
7841 __ negl($dst$$Register); | |
7842 %} | |
7843 ins_pipe(ialu_reg); | |
7844 %} | |
7845 | |
7846 instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr) | |
7847 %{ | |
7848 match(NegExactL dst); | |
7849 effect(KILL cr); | |
7850 | |
7851 format %{ "negq $dst\t# negExact long" %} | |
7852 ins_encode %{ | |
7853 __ negq($dst$$Register); | |
7854 %} | |
7855 ins_pipe(ialu_reg); | |
7856 %} | |
7857 | |
7858 | |
7859 //----------Multiplication/Division Instructions------------------------------- | 7428 //----------Multiplication/Division Instructions------------------------------- |
7860 // Integer Multiplication Instructions | 7429 // Integer Multiplication Instructions |
7861 // Multiply Register | 7430 // Multiply Register |
7862 | 7431 |
7863 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | 7432 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) |
7968 ins_cost(300); | 7537 ins_cost(300); |
7969 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} | 7538 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} |
7970 opcode(0xF7, 0x5); /* Opcode F7 /5 */ | 7539 opcode(0xF7, 0x5); /* Opcode F7 /5 */ |
7971 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); | 7540 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); |
7972 ins_pipe(ialu_reg_reg_alu0); | 7541 ins_pipe(ialu_reg_reg_alu0); |
7973 %} | |
7974 | |
7975 | |
7976 instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) | |
7977 %{ | |
7978 match(MulExactI dst src); | |
7979 effect(DEF cr); | |
7980 | |
7981 ins_cost(300); | |
7982 format %{ "imull $dst, $src\t# mulExact int" %} | |
7983 ins_encode %{ | |
7984 __ imull($dst$$Register, $src$$Register); | |
7985 %} | |
7986 ins_pipe(ialu_reg_reg_alu0); | |
7987 %} | |
7988 | |
7989 | |
7990 instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr) | |
7991 %{ | |
7992 match(MulExactI src imm); | |
7993 effect(DEF cr); | |
7994 | |
7995 ins_cost(300); | |
7996 format %{ "imull $dst, $src, $imm\t# mulExact int" %} | |
7997 ins_encode %{ | |
7998 __ imull($dst$$Register, $src$$Register, $imm$$constant); | |
7999 %} | |
8000 ins_pipe(ialu_reg_reg_alu0); | |
8001 %} | |
8002 | |
8003 instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
8004 %{ | |
8005 match(MulExactI dst (LoadI src)); | |
8006 effect(DEF cr); | |
8007 | |
8008 ins_cost(350); | |
8009 format %{ "imull $dst, $src\t# mulExact int" %} | |
8010 ins_encode %{ | |
8011 __ imull($dst$$Register, $src$$Address); | |
8012 %} | |
8013 ins_pipe(ialu_reg_mem_alu0); | |
8014 %} | |
8015 | |
8016 instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) | |
8017 %{ | |
8018 match(MulExactL dst src); | |
8019 effect(DEF cr); | |
8020 | |
8021 ins_cost(300); | |
8022 format %{ "imulq $dst, $src\t# mulExact long" %} | |
8023 ins_encode %{ | |
8024 __ imulq($dst$$Register, $src$$Register); | |
8025 %} | |
8026 ins_pipe(ialu_reg_reg_alu0); | |
8027 %} | |
8028 | |
8029 instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr) | |
8030 %{ | |
8031 match(MulExactL src imm); | |
8032 effect(DEF cr); | |
8033 | |
8034 ins_cost(300); | |
8035 format %{ "imulq $dst, $src, $imm\t# mulExact long" %} | |
8036 ins_encode %{ | |
8037 __ imulq($dst$$Register, $src$$Register, $imm$$constant); | |
8038 %} | |
8039 ins_pipe(ialu_reg_reg_alu0); | |
8040 %} | |
8041 | |
8042 instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr) | |
8043 %{ | |
8044 match(MulExactL dst (LoadL src)); | |
8045 effect(DEF cr); | |
8046 | |
8047 ins_cost(350); | |
8048 format %{ "imulq $dst, $src\t# mulExact long" %} | |
8049 ins_encode %{ | |
8050 __ imulq($dst$$Register, $src$$Address); | |
8051 %} | |
8052 ins_pipe(ialu_reg_mem_alu0); | |
8053 %} | 7542 %} |
8054 | 7543 |
8055 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, | 7544 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, |
8056 rFlagsReg cr) | 7545 rFlagsReg cr) |
8057 %{ | 7546 %{ |
9102 ins_encode(REX_mem(dst), OpcSE(src), | 8591 ins_encode(REX_mem(dst), OpcSE(src), |
9103 RM_opc_mem(secondary, dst), Con8or32(src)); | 8592 RM_opc_mem(secondary, dst), Con8or32(src)); |
9104 ins_pipe(ialu_mem_imm); | 8593 ins_pipe(ialu_mem_imm); |
9105 %} | 8594 %} |
9106 | 8595 |
8596 // BMI1 instructions | |
8597 instruct andnI_rReg_rReg_mem(rRegI dst, rRegI src1, memory src2, immI_M1 minus_1, rFlagsReg cr) %{ | |
8598 match(Set dst (AndI (XorI src1 minus_1) (LoadI src2))); | |
8599 predicate(UseBMI1Instructions); | |
8600 effect(KILL cr); | |
8601 | |
8602 ins_cost(125); | |
8603 format %{ "andnl $dst, $src1, $src2" %} | |
8604 | |
8605 ins_encode %{ | |
8606 __ andnl($dst$$Register, $src1$$Register, $src2$$Address); | |
8607 %} | |
8608 ins_pipe(ialu_reg_mem); | |
8609 %} | |
8610 | |
8611 instruct andnI_rReg_rReg_rReg(rRegI dst, rRegI src1, rRegI src2, immI_M1 minus_1, rFlagsReg cr) %{ | |
8612 match(Set dst (AndI (XorI src1 minus_1) src2)); | |
8613 predicate(UseBMI1Instructions); | |
8614 effect(KILL cr); | |
8615 | |
8616 format %{ "andnl $dst, $src1, $src2" %} | |
8617 | |
8618 ins_encode %{ | |
8619 __ andnl($dst$$Register, $src1$$Register, $src2$$Register); | |
8620 %} | |
8621 ins_pipe(ialu_reg); | |
8622 %} | |
8623 | |
8624 instruct blsiI_rReg_rReg(rRegI dst, rRegI src, immI0 imm_zero, rFlagsReg cr) %{ | |
8625 match(Set dst (AndI (SubI imm_zero src) src)); | |
8626 predicate(UseBMI1Instructions); | |
8627 effect(KILL cr); | |
8628 | |
8629 format %{ "blsil $dst, $src" %} | |
8630 | |
8631 ins_encode %{ | |
8632 __ blsil($dst$$Register, $src$$Register); | |
8633 %} | |
8634 ins_pipe(ialu_reg); | |
8635 %} | |
8636 | |
8637 instruct blsiI_rReg_mem(rRegI dst, memory src, immI0 imm_zero, rFlagsReg cr) %{ | |
8638 match(Set dst (AndI (SubI imm_zero (LoadI src) ) (LoadI src) )); | |
8639 predicate(UseBMI1Instructions); | |
8640 effect(KILL cr); | |
8641 | |
8642 ins_cost(125); | |
8643 format %{ "blsil $dst, $src" %} | |
8644 | |
8645 ins_encode %{ | |
8646 __ blsil($dst$$Register, $src$$Address); | |
8647 %} | |
8648 ins_pipe(ialu_reg_mem); | |
8649 %} | |
8650 | |
8651 instruct blsmskI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) | |
8652 %{ | |
8653 match(Set dst (XorI (AddI (LoadI src) minus_1) (LoadI src) ) ); | |
8654 predicate(UseBMI1Instructions); | |
8655 effect(KILL cr); | |
8656 | |
8657 ins_cost(125); | |
8658 format %{ "blsmskl $dst, $src" %} | |
8659 | |
8660 ins_encode %{ | |
8661 __ blsmskl($dst$$Register, $src$$Address); | |
8662 %} | |
8663 ins_pipe(ialu_reg_mem); | |
8664 %} | |
8665 | |
8666 instruct blsmskI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) | |
8667 %{ | |
8668 match(Set dst (XorI (AddI src minus_1) src)); | |
8669 predicate(UseBMI1Instructions); | |
8670 effect(KILL cr); | |
8671 | |
8672 format %{ "blsmskl $dst, $src" %} | |
8673 | |
8674 ins_encode %{ | |
8675 __ blsmskl($dst$$Register, $src$$Register); | |
8676 %} | |
8677 | |
8678 ins_pipe(ialu_reg); | |
8679 %} | |
8680 | |
8681 instruct blsrI_rReg_rReg(rRegI dst, rRegI src, immI_M1 minus_1, rFlagsReg cr) | |
8682 %{ | |
8683 match(Set dst (AndI (AddI src minus_1) src) ); | |
8684 predicate(UseBMI1Instructions); | |
8685 effect(KILL cr); | |
8686 | |
8687 format %{ "blsrl $dst, $src" %} | |
8688 | |
8689 ins_encode %{ | |
8690 __ blsrl($dst$$Register, $src$$Register); | |
8691 %} | |
8692 | |
8693 ins_pipe(ialu_reg_mem); | |
8694 %} | |
8695 | |
8696 instruct blsrI_rReg_mem(rRegI dst, memory src, immI_M1 minus_1, rFlagsReg cr) | |
8697 %{ | |
8698 match(Set dst (AndI (AddI (LoadI src) minus_1) (LoadI src) ) ); | |
8699 predicate(UseBMI1Instructions); | |
8700 effect(KILL cr); | |
8701 | |
8702 ins_cost(125); | |
8703 format %{ "blsrl $dst, $src" %} | |
8704 | |
8705 ins_encode %{ | |
8706 __ blsrl($dst$$Register, $src$$Address); | |
8707 %} | |
8708 | |
8709 ins_pipe(ialu_reg); | |
8710 %} | |
8711 | |
9107 // Or Instructions | 8712 // Or Instructions |
9108 // Or Register with Register | 8713 // Or Register with Register |
9109 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | 8714 instruct orI_rReg(rRegI dst, rRegI src, rFlagsReg cr) |
9110 %{ | 8715 %{ |
9111 match(Set dst (OrI dst src)); | 8716 match(Set dst (OrI dst src)); |
9331 format %{ "andq $dst, $src\t# long" %} | 8936 format %{ "andq $dst, $src\t# long" %} |
9332 opcode(0x81, 0x4); /* Opcode 81 /4 id */ | 8937 opcode(0x81, 0x4); /* Opcode 81 /4 id */ |
9333 ins_encode(REX_mem_wide(dst), OpcSE(src), | 8938 ins_encode(REX_mem_wide(dst), OpcSE(src), |
9334 RM_opc_mem(secondary, dst), Con8or32(src)); | 8939 RM_opc_mem(secondary, dst), Con8or32(src)); |
9335 ins_pipe(ialu_mem_imm); | 8940 ins_pipe(ialu_mem_imm); |
8941 %} | |
8942 | |
8943 // BMI1 instructions | |
8944 instruct andnL_rReg_rReg_mem(rRegL dst, rRegL src1, memory src2, immL_M1 minus_1, rFlagsReg cr) %{ | |
8945 match(Set dst (AndL (XorL src1 minus_1) (LoadL src2))); | |
8946 predicate(UseBMI1Instructions); | |
8947 effect(KILL cr); | |
8948 | |
8949 ins_cost(125); | |
8950 format %{ "andnq $dst, $src1, $src2" %} | |
8951 | |
8952 ins_encode %{ | |
8953 __ andnq($dst$$Register, $src1$$Register, $src2$$Address); | |
8954 %} | |
8955 ins_pipe(ialu_reg_mem); | |
8956 %} | |
8957 | |
8958 instruct andnL_rReg_rReg_rReg(rRegL dst, rRegL src1, rRegL src2, immL_M1 minus_1, rFlagsReg cr) %{ | |
8959 match(Set dst (AndL (XorL src1 minus_1) src2)); | |
8960 predicate(UseBMI1Instructions); | |
8961 effect(KILL cr); | |
8962 | |
8963 format %{ "andnq $dst, $src1, $src2" %} | |
8964 | |
8965 ins_encode %{ | |
8966 __ andnq($dst$$Register, $src1$$Register, $src2$$Register); | |
8967 %} | |
8968 ins_pipe(ialu_reg_mem); | |
8969 %} | |
8970 | |
8971 instruct blsiL_rReg_rReg(rRegL dst, rRegL src, immL0 imm_zero, rFlagsReg cr) %{ | |
8972 match(Set dst (AndL (SubL imm_zero src) src)); | |
8973 predicate(UseBMI1Instructions); | |
8974 effect(KILL cr); | |
8975 | |
8976 format %{ "blsiq $dst, $src" %} | |
8977 | |
8978 ins_encode %{ | |
8979 __ blsiq($dst$$Register, $src$$Register); | |
8980 %} | |
8981 ins_pipe(ialu_reg); | |
8982 %} | |
8983 | |
8984 instruct blsiL_rReg_mem(rRegL dst, memory src, immL0 imm_zero, rFlagsReg cr) %{ | |
8985 match(Set dst (AndL (SubL imm_zero (LoadL src) ) (LoadL src) )); | |
8986 predicate(UseBMI1Instructions); | |
8987 effect(KILL cr); | |
8988 | |
8989 ins_cost(125); | |
8990 format %{ "blsiq $dst, $src" %} | |
8991 | |
8992 ins_encode %{ | |
8993 __ blsiq($dst$$Register, $src$$Address); | |
8994 %} | |
8995 ins_pipe(ialu_reg_mem); | |
8996 %} | |
8997 | |
8998 instruct blsmskL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) | |
8999 %{ | |
9000 match(Set dst (XorL (AddL (LoadL src) minus_1) (LoadL src) ) ); | |
9001 predicate(UseBMI1Instructions); | |
9002 effect(KILL cr); | |
9003 | |
9004 ins_cost(125); | |
9005 format %{ "blsmskq $dst, $src" %} | |
9006 | |
9007 ins_encode %{ | |
9008 __ blsmskq($dst$$Register, $src$$Address); | |
9009 %} | |
9010 ins_pipe(ialu_reg_mem); | |
9011 %} | |
9012 | |
9013 instruct blsmskL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) | |
9014 %{ | |
9015 match(Set dst (XorL (AddL src minus_1) src)); | |
9016 predicate(UseBMI1Instructions); | |
9017 effect(KILL cr); | |
9018 | |
9019 format %{ "blsmskq $dst, $src" %} | |
9020 | |
9021 ins_encode %{ | |
9022 __ blsmskq($dst$$Register, $src$$Register); | |
9023 %} | |
9024 | |
9025 ins_pipe(ialu_reg); | |
9026 %} | |
9027 | |
9028 instruct blsrL_rReg_rReg(rRegL dst, rRegL src, immL_M1 minus_1, rFlagsReg cr) | |
9029 %{ | |
9030 match(Set dst (AndL (AddL src minus_1) src) ); | |
9031 predicate(UseBMI1Instructions); | |
9032 effect(KILL cr); | |
9033 | |
9034 format %{ "blsrq $dst, $src" %} | |
9035 | |
9036 ins_encode %{ | |
9037 __ blsrq($dst$$Register, $src$$Register); | |
9038 %} | |
9039 | |
9040 ins_pipe(ialu_reg); | |
9041 %} | |
9042 | |
9043 instruct blsrL_rReg_mem(rRegL dst, memory src, immL_M1 minus_1, rFlagsReg cr) | |
9044 %{ | |
9045 match(Set dst (AndL (AddL (LoadL src) minus_1) (LoadL src)) ); | |
9046 predicate(UseBMI1Instructions); | |
9047 effect(KILL cr); | |
9048 | |
9049 ins_cost(125); | |
9050 format %{ "blsrq $dst, $src" %} | |
9051 | |
9052 ins_encode %{ | |
9053 __ blsrq($dst$$Register, $src$$Address); | |
9054 %} | |
9055 | |
9056 ins_pipe(ialu_reg); | |
9336 %} | 9057 %} |
9337 | 9058 |
9338 // Or Instructions | 9059 // Or Instructions |
9339 // Or Register with Register | 9060 // Or Register with Register |
9340 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | 9061 instruct orL_rReg(rRegL dst, rRegL src, rFlagsReg cr) |
10658 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); | 10379 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); |
10659 %} | 10380 %} |
10660 ins_pipe( pipe_slow ); | 10381 ins_pipe( pipe_slow ); |
10661 %} | 10382 %} |
10662 | 10383 |
10384 //----------Overflow Math Instructions----------------------------------------- | |
10385 | |
10386 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) | |
10387 %{ | |
10388 match(Set cr (OverflowAddI op1 op2)); | |
10389 effect(DEF cr, USE_KILL op1, USE op2); | |
10390 | |
10391 format %{ "addl $op1, $op2\t# overflow check int" %} | |
10392 | |
10393 ins_encode %{ | |
10394 __ addl($op1$$Register, $op2$$Register); | |
10395 %} | |
10396 ins_pipe(ialu_reg_reg); | |
10397 %} | |
10398 | |
10399 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) | |
10400 %{ | |
10401 match(Set cr (OverflowAddI op1 op2)); | |
10402 effect(DEF cr, USE_KILL op1, USE op2); | |
10403 | |
10404 format %{ "addl $op1, $op2\t# overflow check int" %} | |
10405 | |
10406 ins_encode %{ | |
10407 __ addl($op1$$Register, $op2$$constant); | |
10408 %} | |
10409 ins_pipe(ialu_reg_reg); | |
10410 %} | |
10411 | |
10412 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) | |
10413 %{ | |
10414 match(Set cr (OverflowAddL op1 op2)); | |
10415 effect(DEF cr, USE_KILL op1, USE op2); | |
10416 | |
10417 format %{ "addq $op1, $op2\t# overflow check long" %} | |
10418 ins_encode %{ | |
10419 __ addq($op1$$Register, $op2$$Register); | |
10420 %} | |
10421 ins_pipe(ialu_reg_reg); | |
10422 %} | |
10423 | |
10424 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) | |
10425 %{ | |
10426 match(Set cr (OverflowAddL op1 op2)); | |
10427 effect(DEF cr, USE_KILL op1, USE op2); | |
10428 | |
10429 format %{ "addq $op1, $op2\t# overflow check long" %} | |
10430 ins_encode %{ | |
10431 __ addq($op1$$Register, $op2$$constant); | |
10432 %} | |
10433 ins_pipe(ialu_reg_reg); | |
10434 %} | |
10435 | |
10436 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) | |
10437 %{ | |
10438 match(Set cr (OverflowSubI op1 op2)); | |
10439 | |
10440 format %{ "cmpl $op1, $op2\t# overflow check int" %} | |
10441 ins_encode %{ | |
10442 __ cmpl($op1$$Register, $op2$$Register); | |
10443 %} | |
10444 ins_pipe(ialu_reg_reg); | |
10445 %} | |
10446 | |
10447 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) | |
10448 %{ | |
10449 match(Set cr (OverflowSubI op1 op2)); | |
10450 | |
10451 format %{ "cmpl $op1, $op2\t# overflow check int" %} | |
10452 ins_encode %{ | |
10453 __ cmpl($op1$$Register, $op2$$constant); | |
10454 %} | |
10455 ins_pipe(ialu_reg_reg); | |
10456 %} | |
10457 | |
10458 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) | |
10459 %{ | |
10460 match(Set cr (OverflowSubL op1 op2)); | |
10461 | |
10462 format %{ "cmpq $op1, $op2\t# overflow check long" %} | |
10463 ins_encode %{ | |
10464 __ cmpq($op1$$Register, $op2$$Register); | |
10465 %} | |
10466 ins_pipe(ialu_reg_reg); | |
10467 %} | |
10468 | |
10469 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) | |
10470 %{ | |
10471 match(Set cr (OverflowSubL op1 op2)); | |
10472 | |
10473 format %{ "cmpq $op1, $op2\t# overflow check long" %} | |
10474 ins_encode %{ | |
10475 __ cmpq($op1$$Register, $op2$$constant); | |
10476 %} | |
10477 ins_pipe(ialu_reg_reg); | |
10478 %} | |
10479 | |
10480 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) | |
10481 %{ | |
10482 match(Set cr (OverflowSubI zero op2)); | |
10483 effect(DEF cr, USE_KILL op2); | |
10484 | |
10485 format %{ "negl $op2\t# overflow check int" %} | |
10486 ins_encode %{ | |
10487 __ negl($op2$$Register); | |
10488 %} | |
10489 ins_pipe(ialu_reg_reg); | |
10490 %} | |
10491 | |
10492 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) | |
10493 %{ | |
10494 match(Set cr (OverflowSubL zero op2)); | |
10495 effect(DEF cr, USE_KILL op2); | |
10496 | |
10497 format %{ "negq $op2\t# overflow check long" %} | |
10498 ins_encode %{ | |
10499 __ negq($op2$$Register); | |
10500 %} | |
10501 ins_pipe(ialu_reg_reg); | |
10502 %} | |
10503 | |
10504 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) | |
10505 %{ | |
10506 match(Set cr (OverflowMulI op1 op2)); | |
10507 effect(DEF cr, USE_KILL op1, USE op2); | |
10508 | |
10509 format %{ "imull $op1, $op2\t# overflow check int" %} | |
10510 ins_encode %{ | |
10511 __ imull($op1$$Register, $op2$$Register); | |
10512 %} | |
10513 ins_pipe(ialu_reg_reg_alu0); | |
10514 %} | |
10515 | |
10516 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) | |
10517 %{ | |
10518 match(Set cr (OverflowMulI op1 op2)); | |
10519 effect(DEF cr, TEMP tmp, USE op1, USE op2); | |
10520 | |
10521 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} | |
10522 ins_encode %{ | |
10523 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); | |
10524 %} | |
10525 ins_pipe(ialu_reg_reg_alu0); | |
10526 %} | |
10527 | |
10528 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) | |
10529 %{ | |
10530 match(Set cr (OverflowMulL op1 op2)); | |
10531 effect(DEF cr, USE_KILL op1, USE op2); | |
10532 | |
10533 format %{ "imulq $op1, $op2\t# overflow check long" %} | |
10534 ins_encode %{ | |
10535 __ imulq($op1$$Register, $op2$$Register); | |
10536 %} | |
10537 ins_pipe(ialu_reg_reg_alu0); | |
10538 %} | |
10539 | |
10540 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) | |
10541 %{ | |
10542 match(Set cr (OverflowMulL op1 op2)); | |
10543 effect(DEF cr, TEMP tmp, USE op1, USE op2); | |
10544 | |
10545 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} | |
10546 ins_encode %{ | |
10547 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); | |
10548 %} | |
10549 ins_pipe(ialu_reg_reg_alu0); | |
10550 %} | |
10551 | |
10663 | 10552 |
10664 //----------Control Flow Instructions------------------------------------------ | 10553 //----------Control Flow Instructions------------------------------------------ |
10665 // Signed compare Instructions | 10554 // Signed compare Instructions |
10666 | 10555 |
10667 // XXX more variants!! | 10556 // XXX more variants!! |
11441 %} | 11330 %} |
11442 | 11331 |
11443 // ============================================================================ | 11332 // ============================================================================ |
11444 // inlined locking and unlocking | 11333 // inlined locking and unlocking |
11445 | 11334 |
11446 instruct cmpFastLock(rFlagsReg cr, | 11335 instruct cmpFastLockRTM(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rdx_RegI scr, rRegI cx1, rRegI cx2) %{ |
11447 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) | 11336 predicate(Compile::current()->use_rtm()); |
11448 %{ | 11337 match(Set cr (FastLock object box)); |
11338 effect(TEMP tmp, TEMP scr, TEMP cx1, TEMP cx2, USE_KILL box); | |
11339 ins_cost(300); | |
11340 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr,$cx1,$cx2" %} | |
11341 ins_encode %{ | |
11342 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, | |
11343 $scr$$Register, $cx1$$Register, $cx2$$Register, | |
11344 _counters, _rtm_counters, _stack_rtm_counters, | |
11345 ((Method*)(ra_->C->method()->constant_encoding()))->method_data(), | |
11346 true, ra_->C->profile_rtm()); | |
11347 %} | |
11348 ins_pipe(pipe_slow); | |
11349 %} | |
11350 | |
11351 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ | |
11352 predicate(!Compile::current()->use_rtm()); | |
11449 match(Set cr (FastLock object box)); | 11353 match(Set cr (FastLock object box)); |
11450 effect(TEMP tmp, TEMP scr, USE_KILL box); | 11354 effect(TEMP tmp, TEMP scr, USE_KILL box); |
11451 | |
11452 ins_cost(300); | 11355 ins_cost(300); |
11453 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} | 11356 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} |
11454 ins_encode(Fast_Lock(object, box, tmp, scr)); | 11357 ins_encode %{ |
11358 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, | |
11359 $scr$$Register, noreg, noreg, _counters, NULL, NULL, NULL, false, false); | |
11360 %} | |
11455 ins_pipe(pipe_slow); | 11361 ins_pipe(pipe_slow); |
11456 %} | 11362 %} |
11457 | 11363 |
11458 instruct cmpFastUnlock(rFlagsReg cr, | 11364 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ |
11459 rRegP object, rax_RegP box, rRegP tmp) | |
11460 %{ | |
11461 match(Set cr (FastUnlock object box)); | 11365 match(Set cr (FastUnlock object box)); |
11462 effect(TEMP tmp, USE_KILL box); | 11366 effect(TEMP tmp, USE_KILL box); |
11463 | |
11464 ins_cost(300); | 11367 ins_cost(300); |
11465 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} | 11368 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} |
11466 ins_encode(Fast_Unlock(object, box, tmp)); | 11369 ins_encode %{ |
11370 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register, ra_->C->use_rtm()); | |
11371 %} | |
11467 ins_pipe(pipe_slow); | 11372 ins_pipe(pipe_slow); |
11468 %} | 11373 %} |
11469 | 11374 |
11470 | 11375 |
11471 // ============================================================================ | 11376 // ============================================================================ |