Mercurial > hg > graal-compiler
comparison src/cpu/x86/vm/x86_64.ad @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | cd5d10655495 |
children | 89152779163c |
comparison
equal
deleted
inserted
replaced
14908:8db6e76cb658 | 14909:4ca6dc0799b6 |
---|---|
684 //============================================================================= | 684 //============================================================================= |
685 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; | 685 const RegMask& MachConstantBaseNode::_out_RegMask = RegMask::Empty; |
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 } | |
690 | |
691 bool MachConstantBaseNode::requires_postalloc_expand() const { return false; } | |
692 void MachConstantBaseNode::postalloc_expand(GrowableArray <Node *> *nodes, PhaseRegAlloc *ra_) { | |
693 ShouldNotReachHere(); | |
694 } | 689 } |
695 | 690 |
696 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { | 691 void MachConstantBaseNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const { |
697 // Empty encoding | 692 // Empty encoding |
698 } | 693 } |
1545 const int Matcher::long_cmove_cost() { return 0; } | 1540 const int Matcher::long_cmove_cost() { return 0; } |
1546 | 1541 |
1547 // No CMOVF/CMOVD with SSE2 | 1542 // No CMOVF/CMOVD with SSE2 |
1548 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } | 1543 const int Matcher::float_cmove_cost() { return ConditionalMoveLimit; } |
1549 | 1544 |
1550 // Does the CPU require late expand (see block.cpp for description of late expand)? | |
1551 const bool Matcher::require_postalloc_expand = false; | |
1552 | |
1553 // Should the Matcher clone shifts on addressing modes, expecting them | 1545 // Should the Matcher clone shifts on addressing modes, expecting them |
1554 // to be subsumed into complex addressing expressions or compute them | 1546 // to be subsumed into complex addressing expressions or compute them |
1555 // into registers? True for Intel but false for most RISCs | 1547 // into registers? True for Intel but false for most RISCs |
1556 const bool Matcher::clone_shift_expressions = true; | 1548 const bool Matcher::clone_shift_expressions = true; |
1557 | 1549 |
1653 return LONG_RDX_REG_mask(); | 1645 return LONG_RDX_REG_mask(); |
1654 } | 1646 } |
1655 | 1647 |
1656 const RegMask Matcher::method_handle_invoke_SP_save_mask() { | 1648 const RegMask Matcher::method_handle_invoke_SP_save_mask() { |
1657 return PTR_RBP_REG_mask(); | 1649 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(); | |
1658 } | 1662 } |
1659 | 1663 |
1660 %} | 1664 %} |
1661 | 1665 |
1662 //----------ENCODING BLOCK----------------------------------------------------- | 1666 //----------ENCODING BLOCK----------------------------------------------------- |
2582 enc_class Push_SrcXD(regD src) %{ | 2586 enc_class Push_SrcXD(regD src) %{ |
2583 MacroAssembler _masm(&cbuf); | 2587 MacroAssembler _masm(&cbuf); |
2584 __ subptr(rsp, 8); | 2588 __ subptr(rsp, 8); |
2585 __ movdbl(Address(rsp, 0), $src$$XMMRegister); | 2589 __ movdbl(Address(rsp, 0), $src$$XMMRegister); |
2586 __ fld_d(Address(rsp, 0)); | 2590 __ 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 } | |
2587 %} | 2816 %} |
2588 | 2817 |
2589 | 2818 |
2590 enc_class enc_rethrow() | 2819 enc_class enc_rethrow() |
2591 %{ | 2820 %{ |
2722 %} | 2951 %} |
2723 | 2952 |
2724 c_calling_convention | 2953 c_calling_convention |
2725 %{ | 2954 %{ |
2726 // This is obviously always outgoing | 2955 // This is obviously always outgoing |
2727 (void) SharedRuntime::c_calling_convention(sig_bt, regs, /*regs2=*/NULL, length); | 2956 (void) SharedRuntime::c_calling_convention(sig_bt, regs, length); |
2728 %} | 2957 %} |
2729 | 2958 |
2730 // Location of compiled Java return values. Same as C for now. | 2959 // Location of compiled Java return values. Same as C for now. |
2731 return_value | 2960 return_value |
2732 %{ | 2961 %{ |
2855 op_cost(10); | 3084 op_cost(10); |
2856 format %{ %} | 3085 format %{ %} |
2857 interface(CONST_INTER); | 3086 interface(CONST_INTER); |
2858 %} | 3087 %} |
2859 | 3088 |
2860 // Int Immediate non-negative | |
2861 operand immU31() | |
2862 %{ | |
2863 predicate(n->get_int() >= 0); | |
2864 match(ConI); | |
2865 | |
2866 op_cost(0); | |
2867 format %{ %} | |
2868 interface(CONST_INTER); | |
2869 %} | |
2870 | |
2871 // Constant for long shifts | 3089 // Constant for long shifts |
2872 operand immI_32() | 3090 operand immI_32() |
2873 %{ | 3091 %{ |
2874 predicate( n->get_int() == 32 ); | 3092 predicate( n->get_int() == 32 ); |
2875 match(ConI); | 3093 match(ConI); |
4822 __ movzwq($dst$$Register, $mem$$Address); | 5040 __ movzwq($dst$$Register, $mem$$Address); |
4823 %} | 5041 %} |
4824 ins_pipe(ialu_reg_mem); | 5042 ins_pipe(ialu_reg_mem); |
4825 %} | 5043 %} |
4826 | 5044 |
4827 // Load Integer with a 31-bit mask into Long Register | 5045 // Load Integer with a 32-bit mask into Long Register |
4828 instruct loadI2L_immU31(rRegL dst, memory mem, immU31 mask, rFlagsReg cr) %{ | 5046 instruct loadI2L_immI(rRegL dst, memory mem, immI mask, rFlagsReg cr) %{ |
4829 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); | 5047 match(Set dst (ConvI2L (AndI (LoadI mem) mask))); |
4830 effect(KILL cr); | 5048 effect(KILL cr); |
4831 | 5049 |
4832 format %{ "movl $dst, $mem\t# int & 31-bit mask -> long\n\t" | 5050 format %{ "movl $dst, $mem\t# int & 32-bit mask -> long\n\t" |
4833 "andl $dst, $mask" %} | 5051 "andl $dst, $mask" %} |
4834 ins_encode %{ | 5052 ins_encode %{ |
4835 Register Rdst = $dst$$Register; | 5053 Register Rdst = $dst$$Register; |
4836 __ movl(Rdst, $mem$$Address); | 5054 __ movl(Rdst, $mem$$Address); |
4837 __ andl(Rdst, $mask$$constant); | 5055 __ andl(Rdst, $mask$$constant); |
6117 // Memory barrier flavors | 6335 // Memory barrier flavors |
6118 | 6336 |
6119 instruct membar_acquire() | 6337 instruct membar_acquire() |
6120 %{ | 6338 %{ |
6121 match(MemBarAcquire); | 6339 match(MemBarAcquire); |
6122 match(LoadFence); | |
6123 ins_cost(0); | 6340 ins_cost(0); |
6124 | 6341 |
6125 size(0); | 6342 size(0); |
6126 format %{ "MEMBAR-acquire ! (empty encoding)" %} | 6343 format %{ "MEMBAR-acquire ! (empty encoding)" %} |
6127 ins_encode(); | 6344 ins_encode(); |
6140 %} | 6357 %} |
6141 | 6358 |
6142 instruct membar_release() | 6359 instruct membar_release() |
6143 %{ | 6360 %{ |
6144 match(MemBarRelease); | 6361 match(MemBarRelease); |
6145 match(StoreFence); | |
6146 ins_cost(0); | 6362 ins_cost(0); |
6147 | 6363 |
6148 size(0); | 6364 size(0); |
6149 format %{ "MEMBAR-release ! (empty encoding)" %} | 6365 format %{ "MEMBAR-release ! (empty encoding)" %} |
6150 ins_encode(); | 6366 ins_encode(); |
6724 %} | 6940 %} |
6725 | 6941 |
6726 //----------Arithmetic Instructions-------------------------------------------- | 6942 //----------Arithmetic Instructions-------------------------------------------- |
6727 //----------Addition Instructions---------------------------------------------- | 6943 //----------Addition Instructions---------------------------------------------- |
6728 | 6944 |
6945 instruct addExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) | |
6946 %{ | |
6947 match(AddExactI dst src); | |
6948 effect(DEF cr); | |
6949 | |
6950 format %{ "addl $dst, $src\t# addExact int" %} | |
6951 ins_encode %{ | |
6952 __ addl($dst$$Register, $src$$Register); | |
6953 %} | |
6954 ins_pipe(ialu_reg_reg); | |
6955 %} | |
6956 | |
6957 instruct addExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) | |
6958 %{ | |
6959 match(AddExactI dst src); | |
6960 effect(DEF cr); | |
6961 | |
6962 format %{ "addl $dst, $src\t# addExact int" %} | |
6963 ins_encode %{ | |
6964 __ addl($dst$$Register, $src$$constant); | |
6965 %} | |
6966 ins_pipe(ialu_reg_reg); | |
6967 %} | |
6968 | |
6969 instruct addExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
6970 %{ | |
6971 match(AddExactI dst (LoadI src)); | |
6972 effect(DEF cr); | |
6973 | |
6974 ins_cost(125); // XXX | |
6975 format %{ "addl $dst, $src\t# addExact int" %} | |
6976 ins_encode %{ | |
6977 __ addl($dst$$Register, $src$$Address); | |
6978 %} | |
6979 | |
6980 ins_pipe(ialu_reg_mem); | |
6981 %} | |
6982 | |
6983 instruct addExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) | |
6984 %{ | |
6985 match(AddExactL dst src); | |
6986 effect(DEF cr); | |
6987 | |
6988 format %{ "addq $dst, $src\t# addExact long" %} | |
6989 ins_encode %{ | |
6990 __ addq($dst$$Register, $src$$Register); | |
6991 %} | |
6992 ins_pipe(ialu_reg_reg); | |
6993 %} | |
6994 | |
6995 instruct addExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr) | |
6996 %{ | |
6997 match(AddExactL dst src); | |
6998 effect(DEF cr); | |
6999 | |
7000 format %{ "addq $dst, $src\t# addExact long" %} | |
7001 ins_encode %{ | |
7002 __ addq($dst$$Register, $src$$constant); | |
7003 %} | |
7004 ins_pipe(ialu_reg_reg); | |
7005 %} | |
7006 | |
7007 instruct addExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr) | |
7008 %{ | |
7009 match(AddExactL dst (LoadL src)); | |
7010 effect(DEF cr); | |
7011 | |
7012 ins_cost(125); // XXX | |
7013 format %{ "addq $dst, $src\t# addExact long" %} | |
7014 ins_encode %{ | |
7015 __ addq($dst$$Register, $src$$Address); | |
7016 %} | |
7017 | |
7018 ins_pipe(ialu_reg_mem); | |
7019 %} | |
7020 | |
6729 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | 7021 instruct addI_rReg(rRegI dst, rRegI src, rFlagsReg cr) |
6730 %{ | 7022 %{ |
6731 match(Set dst (AddI dst src)); | 7023 match(Set dst (AddI dst src)); |
6732 effect(KILL cr); | 7024 effect(KILL cr); |
6733 | 7025 |
7336 opcode(0x81); /* Opcode 81 /5 id */ | 7628 opcode(0x81); /* Opcode 81 /5 id */ |
7337 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); | 7629 ins_encode(REX_mem(dst), OpcSE(src), RM_opc_mem(0x05, dst), Con8or32(src)); |
7338 ins_pipe(ialu_mem_imm); | 7630 ins_pipe(ialu_mem_imm); |
7339 %} | 7631 %} |
7340 | 7632 |
7633 instruct subExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) | |
7634 %{ | |
7635 match(SubExactI dst src); | |
7636 effect(DEF cr); | |
7637 | |
7638 format %{ "subl $dst, $src\t# subExact int" %} | |
7639 ins_encode %{ | |
7640 __ subl($dst$$Register, $src$$Register); | |
7641 %} | |
7642 ins_pipe(ialu_reg_reg); | |
7643 %} | |
7644 | |
7645 instruct subExactI_rReg_imm(rax_RegI dst, immI src, rFlagsReg cr) | |
7646 %{ | |
7647 match(SubExactI dst src); | |
7648 effect(DEF cr); | |
7649 | |
7650 format %{ "subl $dst, $src\t# subExact int" %} | |
7651 ins_encode %{ | |
7652 __ subl($dst$$Register, $src$$constant); | |
7653 %} | |
7654 ins_pipe(ialu_reg_reg); | |
7655 %} | |
7656 | |
7657 instruct subExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
7658 %{ | |
7659 match(SubExactI dst (LoadI src)); | |
7660 effect(DEF cr); | |
7661 | |
7662 ins_cost(125); | |
7663 format %{ "subl $dst, $src\t# subExact int" %} | |
7664 ins_encode %{ | |
7665 __ subl($dst$$Register, $src$$Address); | |
7666 %} | |
7667 ins_pipe(ialu_reg_mem); | |
7668 %} | |
7669 | |
7670 instruct subExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) | |
7671 %{ | |
7672 match(SubExactL dst src); | |
7673 effect(DEF cr); | |
7674 | |
7675 format %{ "subq $dst, $src\t# subExact long" %} | |
7676 ins_encode %{ | |
7677 __ subq($dst$$Register, $src$$Register); | |
7678 %} | |
7679 ins_pipe(ialu_reg_reg); | |
7680 %} | |
7681 | |
7682 instruct subExactL_rReg_imm(rax_RegL dst, immL32 src, rFlagsReg cr) | |
7683 %{ | |
7684 match(SubExactL dst (LoadL src)); | |
7685 effect(DEF cr); | |
7686 | |
7687 format %{ "subq $dst, $src\t# subExact long" %} | |
7688 ins_encode %{ | |
7689 __ subq($dst$$Register, $src$$constant); | |
7690 %} | |
7691 ins_pipe(ialu_reg_reg); | |
7692 %} | |
7693 | |
7694 instruct subExactL_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
7695 %{ | |
7696 match(SubExactI dst src); | |
7697 effect(DEF cr); | |
7698 | |
7699 ins_cost(125); | |
7700 format %{ "subq $dst, $src\t# subExact long" %} | |
7701 ins_encode %{ | |
7702 __ subq($dst$$Register, $src$$Address); | |
7703 %} | |
7704 ins_pipe(ialu_reg_mem); | |
7705 %} | |
7706 | |
7341 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) | 7707 instruct subL_rReg(rRegL dst, rRegL src, rFlagsReg cr) |
7342 %{ | 7708 %{ |
7343 match(Set dst (SubL dst src)); | 7709 match(Set dst (SubL dst src)); |
7344 effect(KILL cr); | 7710 effect(KILL cr); |
7345 | 7711 |
7452 opcode(0xF7, 0x03); // Opcode F7 /3 | 7818 opcode(0xF7, 0x03); // Opcode F7 /3 |
7453 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); | 7819 ins_encode(REX_mem_wide(dst), OpcP, RM_opc_mem(secondary, dst)); |
7454 ins_pipe(ialu_reg); | 7820 ins_pipe(ialu_reg); |
7455 %} | 7821 %} |
7456 | 7822 |
7823 instruct negExactI_rReg(rax_RegI dst, rFlagsReg cr) | |
7824 %{ | |
7825 match(NegExactI dst); | |
7826 effect(KILL cr); | |
7827 | |
7828 format %{ "negl $dst\t# negExact int" %} | |
7829 ins_encode %{ | |
7830 __ negl($dst$$Register); | |
7831 %} | |
7832 ins_pipe(ialu_reg); | |
7833 %} | |
7834 | |
7835 instruct negExactL_rReg(rax_RegL dst, rFlagsReg cr) | |
7836 %{ | |
7837 match(NegExactL dst); | |
7838 effect(KILL cr); | |
7839 | |
7840 format %{ "negq $dst\t# negExact long" %} | |
7841 ins_encode %{ | |
7842 __ negq($dst$$Register); | |
7843 %} | |
7844 ins_pipe(ialu_reg); | |
7845 %} | |
7846 | |
7847 | |
7457 //----------Multiplication/Division Instructions------------------------------- | 7848 //----------Multiplication/Division Instructions------------------------------- |
7458 // Integer Multiplication Instructions | 7849 // Integer Multiplication Instructions |
7459 // Multiply Register | 7850 // Multiply Register |
7460 | 7851 |
7461 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) | 7852 instruct mulI_rReg(rRegI dst, rRegI src, rFlagsReg cr) |
7566 ins_cost(300); | 7957 ins_cost(300); |
7567 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} | 7958 format %{ "imulq RDX:RAX, RAX, $src\t# mulhi" %} |
7568 opcode(0xF7, 0x5); /* Opcode F7 /5 */ | 7959 opcode(0xF7, 0x5); /* Opcode F7 /5 */ |
7569 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); | 7960 ins_encode(REX_reg_wide(src), OpcP, reg_opc(src)); |
7570 ins_pipe(ialu_reg_reg_alu0); | 7961 ins_pipe(ialu_reg_reg_alu0); |
7962 %} | |
7963 | |
7964 | |
7965 instruct mulExactI_rReg(rax_RegI dst, rRegI src, rFlagsReg cr) | |
7966 %{ | |
7967 match(MulExactI dst src); | |
7968 effect(DEF cr); | |
7969 | |
7970 ins_cost(300); | |
7971 format %{ "imull $dst, $src\t# mulExact int" %} | |
7972 ins_encode %{ | |
7973 __ imull($dst$$Register, $src$$Register); | |
7974 %} | |
7975 ins_pipe(ialu_reg_reg_alu0); | |
7976 %} | |
7977 | |
7978 | |
7979 instruct mulExactI_rReg_imm(rax_RegI dst, rRegI src, immI imm, rFlagsReg cr) | |
7980 %{ | |
7981 match(MulExactI src imm); | |
7982 effect(DEF cr); | |
7983 | |
7984 ins_cost(300); | |
7985 format %{ "imull $dst, $src, $imm\t# mulExact int" %} | |
7986 ins_encode %{ | |
7987 __ imull($dst$$Register, $src$$Register, $imm$$constant); | |
7988 %} | |
7989 ins_pipe(ialu_reg_reg_alu0); | |
7990 %} | |
7991 | |
7992 instruct mulExactI_rReg_mem(rax_RegI dst, memory src, rFlagsReg cr) | |
7993 %{ | |
7994 match(MulExactI dst (LoadI src)); | |
7995 effect(DEF cr); | |
7996 | |
7997 ins_cost(350); | |
7998 format %{ "imull $dst, $src\t# mulExact int" %} | |
7999 ins_encode %{ | |
8000 __ imull($dst$$Register, $src$$Address); | |
8001 %} | |
8002 ins_pipe(ialu_reg_mem_alu0); | |
8003 %} | |
8004 | |
8005 instruct mulExactL_rReg(rax_RegL dst, rRegL src, rFlagsReg cr) | |
8006 %{ | |
8007 match(MulExactL dst src); | |
8008 effect(DEF cr); | |
8009 | |
8010 ins_cost(300); | |
8011 format %{ "imulq $dst, $src\t# mulExact long" %} | |
8012 ins_encode %{ | |
8013 __ imulq($dst$$Register, $src$$Register); | |
8014 %} | |
8015 ins_pipe(ialu_reg_reg_alu0); | |
8016 %} | |
8017 | |
8018 instruct mulExactL_rReg_imm(rax_RegL dst, rRegL src, immL32 imm, rFlagsReg cr) | |
8019 %{ | |
8020 match(MulExactL src imm); | |
8021 effect(DEF cr); | |
8022 | |
8023 ins_cost(300); | |
8024 format %{ "imulq $dst, $src, $imm\t# mulExact long" %} | |
8025 ins_encode %{ | |
8026 __ imulq($dst$$Register, $src$$Register, $imm$$constant); | |
8027 %} | |
8028 ins_pipe(ialu_reg_reg_alu0); | |
8029 %} | |
8030 | |
8031 instruct mulExactL_rReg_mem(rax_RegL dst, memory src, rFlagsReg cr) | |
8032 %{ | |
8033 match(MulExactL dst (LoadL src)); | |
8034 effect(DEF cr); | |
8035 | |
8036 ins_cost(350); | |
8037 format %{ "imulq $dst, $src\t# mulExact long" %} | |
8038 ins_encode %{ | |
8039 __ imulq($dst$$Register, $src$$Address); | |
8040 %} | |
8041 ins_pipe(ialu_reg_mem_alu0); | |
7571 %} | 8042 %} |
7572 | 8043 |
7573 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, | 8044 instruct divI_rReg(rax_RegI rax, rdx_RegI rdx, no_rax_rdx_RegI div, |
7574 rFlagsReg cr) | 8045 rFlagsReg cr) |
7575 %{ | 8046 %{ |
10176 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); | 10647 $tmp4$$XMMRegister, $tmp5$$Register, $result$$Register); |
10177 %} | 10648 %} |
10178 ins_pipe( pipe_slow ); | 10649 ins_pipe( pipe_slow ); |
10179 %} | 10650 %} |
10180 | 10651 |
10181 //----------Overflow Math Instructions----------------------------------------- | |
10182 | |
10183 instruct overflowAddI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) | |
10184 %{ | |
10185 match(Set cr (OverflowAddI op1 op2)); | |
10186 effect(DEF cr, USE_KILL op1, USE op2); | |
10187 | |
10188 format %{ "addl $op1, $op2\t# overflow check int" %} | |
10189 | |
10190 ins_encode %{ | |
10191 __ addl($op1$$Register, $op2$$Register); | |
10192 %} | |
10193 ins_pipe(ialu_reg_reg); | |
10194 %} | |
10195 | |
10196 instruct overflowAddI_rReg_imm(rFlagsReg cr, rax_RegI op1, immI op2) | |
10197 %{ | |
10198 match(Set cr (OverflowAddI op1 op2)); | |
10199 effect(DEF cr, USE_KILL op1, USE op2); | |
10200 | |
10201 format %{ "addl $op1, $op2\t# overflow check int" %} | |
10202 | |
10203 ins_encode %{ | |
10204 __ addl($op1$$Register, $op2$$constant); | |
10205 %} | |
10206 ins_pipe(ialu_reg_reg); | |
10207 %} | |
10208 | |
10209 instruct overflowAddL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) | |
10210 %{ | |
10211 match(Set cr (OverflowAddL op1 op2)); | |
10212 effect(DEF cr, USE_KILL op1, USE op2); | |
10213 | |
10214 format %{ "addq $op1, $op2\t# overflow check long" %} | |
10215 ins_encode %{ | |
10216 __ addq($op1$$Register, $op2$$Register); | |
10217 %} | |
10218 ins_pipe(ialu_reg_reg); | |
10219 %} | |
10220 | |
10221 instruct overflowAddL_rReg_imm(rFlagsReg cr, rax_RegL op1, immL32 op2) | |
10222 %{ | |
10223 match(Set cr (OverflowAddL op1 op2)); | |
10224 effect(DEF cr, USE_KILL op1, USE op2); | |
10225 | |
10226 format %{ "addq $op1, $op2\t# overflow check long" %} | |
10227 ins_encode %{ | |
10228 __ addq($op1$$Register, $op2$$constant); | |
10229 %} | |
10230 ins_pipe(ialu_reg_reg); | |
10231 %} | |
10232 | |
10233 instruct overflowSubI_rReg(rFlagsReg cr, rRegI op1, rRegI op2) | |
10234 %{ | |
10235 match(Set cr (OverflowSubI op1 op2)); | |
10236 | |
10237 format %{ "cmpl $op1, $op2\t# overflow check int" %} | |
10238 ins_encode %{ | |
10239 __ cmpl($op1$$Register, $op2$$Register); | |
10240 %} | |
10241 ins_pipe(ialu_reg_reg); | |
10242 %} | |
10243 | |
10244 instruct overflowSubI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2) | |
10245 %{ | |
10246 match(Set cr (OverflowSubI op1 op2)); | |
10247 | |
10248 format %{ "cmpl $op1, $op2\t# overflow check int" %} | |
10249 ins_encode %{ | |
10250 __ cmpl($op1$$Register, $op2$$constant); | |
10251 %} | |
10252 ins_pipe(ialu_reg_reg); | |
10253 %} | |
10254 | |
10255 instruct overflowSubL_rReg(rFlagsReg cr, rRegL op1, rRegL op2) | |
10256 %{ | |
10257 match(Set cr (OverflowSubL op1 op2)); | |
10258 | |
10259 format %{ "cmpq $op1, $op2\t# overflow check long" %} | |
10260 ins_encode %{ | |
10261 __ cmpq($op1$$Register, $op2$$Register); | |
10262 %} | |
10263 ins_pipe(ialu_reg_reg); | |
10264 %} | |
10265 | |
10266 instruct overflowSubL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2) | |
10267 %{ | |
10268 match(Set cr (OverflowSubL op1 op2)); | |
10269 | |
10270 format %{ "cmpq $op1, $op2\t# overflow check long" %} | |
10271 ins_encode %{ | |
10272 __ cmpq($op1$$Register, $op2$$constant); | |
10273 %} | |
10274 ins_pipe(ialu_reg_reg); | |
10275 %} | |
10276 | |
10277 instruct overflowNegI_rReg(rFlagsReg cr, immI0 zero, rax_RegI op2) | |
10278 %{ | |
10279 match(Set cr (OverflowSubI zero op2)); | |
10280 effect(DEF cr, USE_KILL op2); | |
10281 | |
10282 format %{ "negl $op2\t# overflow check int" %} | |
10283 ins_encode %{ | |
10284 __ negl($op2$$Register); | |
10285 %} | |
10286 ins_pipe(ialu_reg_reg); | |
10287 %} | |
10288 | |
10289 instruct overflowNegL_rReg(rFlagsReg cr, immL0 zero, rax_RegL op2) | |
10290 %{ | |
10291 match(Set cr (OverflowSubL zero op2)); | |
10292 effect(DEF cr, USE_KILL op2); | |
10293 | |
10294 format %{ "negq $op2\t# overflow check long" %} | |
10295 ins_encode %{ | |
10296 __ negq($op2$$Register); | |
10297 %} | |
10298 ins_pipe(ialu_reg_reg); | |
10299 %} | |
10300 | |
10301 instruct overflowMulI_rReg(rFlagsReg cr, rax_RegI op1, rRegI op2) | |
10302 %{ | |
10303 match(Set cr (OverflowMulI op1 op2)); | |
10304 effect(DEF cr, USE_KILL op1, USE op2); | |
10305 | |
10306 format %{ "imull $op1, $op2\t# overflow check int" %} | |
10307 ins_encode %{ | |
10308 __ imull($op1$$Register, $op2$$Register); | |
10309 %} | |
10310 ins_pipe(ialu_reg_reg_alu0); | |
10311 %} | |
10312 | |
10313 instruct overflowMulI_rReg_imm(rFlagsReg cr, rRegI op1, immI op2, rRegI tmp) | |
10314 %{ | |
10315 match(Set cr (OverflowMulI op1 op2)); | |
10316 effect(DEF cr, TEMP tmp, USE op1, USE op2); | |
10317 | |
10318 format %{ "imull $tmp, $op1, $op2\t# overflow check int" %} | |
10319 ins_encode %{ | |
10320 __ imull($tmp$$Register, $op1$$Register, $op2$$constant); | |
10321 %} | |
10322 ins_pipe(ialu_reg_reg_alu0); | |
10323 %} | |
10324 | |
10325 instruct overflowMulL_rReg(rFlagsReg cr, rax_RegL op1, rRegL op2) | |
10326 %{ | |
10327 match(Set cr (OverflowMulL op1 op2)); | |
10328 effect(DEF cr, USE_KILL op1, USE op2); | |
10329 | |
10330 format %{ "imulq $op1, $op2\t# overflow check long" %} | |
10331 ins_encode %{ | |
10332 __ imulq($op1$$Register, $op2$$Register); | |
10333 %} | |
10334 ins_pipe(ialu_reg_reg_alu0); | |
10335 %} | |
10336 | |
10337 instruct overflowMulL_rReg_imm(rFlagsReg cr, rRegL op1, immL32 op2, rRegL tmp) | |
10338 %{ | |
10339 match(Set cr (OverflowMulL op1 op2)); | |
10340 effect(DEF cr, TEMP tmp, USE op1, USE op2); | |
10341 | |
10342 format %{ "imulq $tmp, $op1, $op2\t# overflow check long" %} | |
10343 ins_encode %{ | |
10344 __ imulq($tmp$$Register, $op1$$Register, $op2$$constant); | |
10345 %} | |
10346 ins_pipe(ialu_reg_reg_alu0); | |
10347 %} | |
10348 | |
10349 | 10652 |
10350 //----------Control Flow Instructions------------------------------------------ | 10653 //----------Control Flow Instructions------------------------------------------ |
10351 // Signed compare Instructions | 10654 // Signed compare Instructions |
10352 | 10655 |
10353 // XXX more variants!! | 10656 // XXX more variants!! |
11127 %} | 11430 %} |
11128 | 11431 |
11129 // ============================================================================ | 11432 // ============================================================================ |
11130 // inlined locking and unlocking | 11433 // inlined locking and unlocking |
11131 | 11434 |
11132 instruct cmpFastLock(rFlagsReg cr, rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) %{ | 11435 instruct cmpFastLock(rFlagsReg cr, |
11436 rRegP object, rbx_RegP box, rax_RegI tmp, rRegP scr) | |
11437 %{ | |
11133 match(Set cr (FastLock object box)); | 11438 match(Set cr (FastLock object box)); |
11134 effect(TEMP tmp, TEMP scr, USE_KILL box); | 11439 effect(TEMP tmp, TEMP scr, USE_KILL box); |
11440 | |
11135 ins_cost(300); | 11441 ins_cost(300); |
11136 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} | 11442 format %{ "fastlock $object,$box\t! kills $box,$tmp,$scr" %} |
11137 ins_encode %{ | 11443 ins_encode(Fast_Lock(object, box, tmp, scr)); |
11138 __ fast_lock($object$$Register, $box$$Register, $tmp$$Register, $scr$$Register, _counters); | |
11139 %} | |
11140 ins_pipe(pipe_slow); | 11444 ins_pipe(pipe_slow); |
11141 %} | 11445 %} |
11142 | 11446 |
11143 instruct cmpFastUnlock(rFlagsReg cr, rRegP object, rax_RegP box, rRegP tmp) %{ | 11447 instruct cmpFastUnlock(rFlagsReg cr, |
11448 rRegP object, rax_RegP box, rRegP tmp) | |
11449 %{ | |
11144 match(Set cr (FastUnlock object box)); | 11450 match(Set cr (FastUnlock object box)); |
11145 effect(TEMP tmp, USE_KILL box); | 11451 effect(TEMP tmp, USE_KILL box); |
11452 | |
11146 ins_cost(300); | 11453 ins_cost(300); |
11147 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} | 11454 format %{ "fastunlock $object,$box\t! kills $box,$tmp" %} |
11148 ins_encode %{ | 11455 ins_encode(Fast_Unlock(object, box, tmp)); |
11149 __ fast_unlock($object$$Register, $box$$Register, $tmp$$Register); | |
11150 %} | |
11151 ins_pipe(pipe_slow); | 11456 ins_pipe(pipe_slow); |
11152 %} | 11457 %} |
11153 | 11458 |
11154 | 11459 |
11155 // ============================================================================ | 11460 // ============================================================================ |