Mercurial > hg > truffle
comparison src/cpu/x86/vm/x86_64.ad @ 420:a1980da045cc
6462850: generate biased locking code in C2 ideal graph
Summary: Inline biased locking code in C2 ideal graph during macro nodes expansion
Reviewed-by: never
author | kvn |
---|---|
date | Fri, 07 Nov 2008 09:29:38 -0800 |
parents | 4d9884b01ba6 |
children | 3b5ac9e7e6ea |
comparison
equal
deleted
inserted
replaced
419:0bf25c4807f9 | 420:a1980da045cc |
---|---|
3570 // conditional branches in the most common cases. | 3570 // conditional branches in the most common cases. |
3571 // Beware -- there's a subtle invariant that fetch of the markword | 3571 // Beware -- there's a subtle invariant that fetch of the markword |
3572 // at [FETCH], below, will never observe a biased encoding (*101b). | 3572 // at [FETCH], below, will never observe a biased encoding (*101b). |
3573 // If this invariant is not held we'll suffer exclusion (safety) failure. | 3573 // If this invariant is not held we'll suffer exclusion (safety) failure. |
3574 | 3574 |
3575 if (UseBiasedLocking) { | 3575 if (UseBiasedLocking && !UseOptoBiasInlining) { |
3576 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); | 3576 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); |
3577 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] | 3577 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] |
3578 } | 3578 } |
3579 | 3579 |
3580 // was q will it destroy high? | 3580 // was q will it destroy high? |
3658 masm.bind(DONE_LABEL); | 3658 masm.bind(DONE_LABEL); |
3659 masm.nop(); // avoid branch to branch | 3659 masm.nop(); // avoid branch to branch |
3660 } else { | 3660 } else { |
3661 Label DONE_LABEL, Stacked, CheckSucc ; | 3661 Label DONE_LABEL, Stacked, CheckSucc ; |
3662 | 3662 |
3663 if (UseBiasedLocking) { | 3663 if (UseBiasedLocking && !UseOptoBiasInlining) { |
3664 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); | 3664 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); |
3665 } | 3665 } |
3666 | 3666 |
3667 masm.movptr(tmpReg, Address(objReg, 0)) ; | 3667 masm.movptr(tmpReg, Address(objReg, 0)) ; |
3668 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; | 3668 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; |
7843 instruct storePConditional(memory heap_top_ptr, | 7843 instruct storePConditional(memory heap_top_ptr, |
7844 rax_RegP oldval, rRegP newval, | 7844 rax_RegP oldval, rRegP newval, |
7845 rFlagsReg cr) | 7845 rFlagsReg cr) |
7846 %{ | 7846 %{ |
7847 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); | 7847 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); |
7848 | 7848 |
7849 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " | 7849 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " |
7850 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} | 7850 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} |
7851 opcode(0x0F, 0xB1); | 7851 opcode(0x0F, 0xB1); |
7852 ins_encode(lock_prefix, | 7852 ins_encode(lock_prefix, |
7853 REX_reg_mem_wide(newval, heap_top_ptr), | 7853 REX_reg_mem_wide(newval, heap_top_ptr), |
7854 OpcP, OpcS, | 7854 OpcP, OpcS, |
7855 reg_mem(newval, heap_top_ptr)); | 7855 reg_mem(newval, heap_top_ptr)); |
7856 ins_pipe(pipe_cmpxchg); | 7856 ins_pipe(pipe_cmpxchg); |
7857 %} | 7857 %} |
7858 | 7858 |
7859 // Conditional-store of a long value | 7859 // Conditional-store of an int value. |
7860 // Returns a boolean value (0/1) on success. Implemented with a | 7860 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. |
7861 // CMPXCHG8 on Intel. mem_ptr can actually be in either RSI or RDI | 7861 instruct storeIConditional(memory mem, rax_RegI oldval, rRegI newval, rFlagsReg cr) |
7862 | 7862 %{ |
7863 instruct storeLConditional(rRegI res, | 7863 match(Set cr (StoreIConditional mem (Binary oldval newval))); |
7864 memory mem_ptr, | 7864 effect(KILL oldval); |
7865 rax_RegL oldval, rRegL newval, | 7865 |
7866 rFlagsReg cr) | 7866 format %{ "cmpxchgl $mem, $newval\t# If rax == $mem then store $newval into $mem" %} |
7867 %{ | |
7868 match(Set res (StoreLConditional mem_ptr (Binary oldval newval))); | |
7869 effect(KILL cr); | |
7870 | |
7871 format %{ "cmpxchgq $mem_ptr, $newval\t# (long) " | |
7872 "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" | |
7873 "sete $res\n\t" | |
7874 "movzbl $res, $res" %} | |
7875 opcode(0x0F, 0xB1); | 7867 opcode(0x0F, 0xB1); |
7876 ins_encode(lock_prefix, | 7868 ins_encode(lock_prefix, |
7877 REX_reg_mem_wide(newval, mem_ptr), | 7869 REX_reg_mem(newval, mem), |
7878 OpcP, OpcS, | 7870 OpcP, OpcS, |
7879 reg_mem(newval, mem_ptr), | 7871 reg_mem(newval, mem)); |
7880 REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete | |
7881 REX_reg_breg(res, res), // movzbl | |
7882 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | |
7883 ins_pipe(pipe_cmpxchg); | 7872 ins_pipe(pipe_cmpxchg); |
7884 %} | 7873 %} |
7885 | 7874 |
7886 // Conditional-store of a long value | 7875 // Conditional-store of a long value. |
7887 // ZF flag is set on success, reset otherwise. Implemented with a | 7876 // ZF flag is set on success, reset otherwise. Implemented with a CMPXCHG. |
7888 // CMPXCHG8 on Intel. mem_ptr can actually be in either RSI or RDI | 7877 instruct storeLConditional(memory mem, rax_RegL oldval, rRegL newval, rFlagsReg cr) |
7889 instruct storeLConditional_flags(memory mem_ptr, | 7878 %{ |
7890 rax_RegL oldval, rRegL newval, | 7879 match(Set cr (StoreLConditional mem (Binary oldval newval))); |
7891 rFlagsReg cr, | 7880 effect(KILL oldval); |
7892 immI0 zero) | 7881 |
7893 %{ | 7882 format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %} |
7894 match(Set cr (CmpI (StoreLConditional mem_ptr (Binary oldval newval)) zero)); | |
7895 | |
7896 format %{ "cmpxchgq $mem_ptr, $newval\t# (long) " | |
7897 "If rax == $mem_ptr then store $newval into $mem_ptr" %} | |
7898 opcode(0x0F, 0xB1); | 7883 opcode(0x0F, 0xB1); |
7899 ins_encode(lock_prefix, | 7884 ins_encode(lock_prefix, |
7900 REX_reg_mem_wide(newval, mem_ptr), | 7885 REX_reg_mem_wide(newval, mem), |
7901 OpcP, OpcS, | 7886 OpcP, OpcS, |
7902 reg_mem(newval, mem_ptr)); | 7887 reg_mem(newval, mem)); |
7903 ins_pipe(pipe_cmpxchg); | 7888 ins_pipe(pipe_cmpxchg); |
7904 %} | 7889 %} |
7905 | 7890 |
7891 | |
7892 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them | |
7906 instruct compareAndSwapP(rRegI res, | 7893 instruct compareAndSwapP(rRegI res, |
7907 memory mem_ptr, | 7894 memory mem_ptr, |
7908 rax_RegP oldval, rRegP newval, | 7895 rax_RegP oldval, rRegP newval, |
7909 rFlagsReg cr) | 7896 rFlagsReg cr) |
7910 %{ | 7897 %{ |
7924 REX_reg_breg(res, res), // movzbl | 7911 REX_reg_breg(res, res), // movzbl |
7925 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); | 7912 Opcode(0xF), Opcode(0xB6), reg_reg(res, res)); |
7926 ins_pipe( pipe_cmpxchg ); | 7913 ins_pipe( pipe_cmpxchg ); |
7927 %} | 7914 %} |
7928 | 7915 |
7929 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them | |
7930 instruct compareAndSwapL(rRegI res, | 7916 instruct compareAndSwapL(rRegI res, |
7931 memory mem_ptr, | 7917 memory mem_ptr, |
7932 rax_RegL oldval, rRegL newval, | 7918 rax_RegL oldval, rRegL newval, |
7933 rFlagsReg cr) | 7919 rFlagsReg cr) |
7934 %{ | 7920 %{ |
8874 opcode(0xC1, 0x5); /* C1 /5 ib */ | 8860 opcode(0xC1, 0x5); /* C1 /5 ib */ |
8875 ins_encode(reg_opc_imm_wide(dst, shift)); | 8861 ins_encode(reg_opc_imm_wide(dst, shift)); |
8876 ins_pipe(ialu_reg); | 8862 ins_pipe(ialu_reg); |
8877 %} | 8863 %} |
8878 | 8864 |
8865 | |
8879 // Logical Shift Right by 8-bit immediate | 8866 // Logical Shift Right by 8-bit immediate |
8880 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) | 8867 instruct shrL_mem_imm(memory dst, immI8 shift, rFlagsReg cr) |
8881 %{ | 8868 %{ |
8882 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); | 8869 match(Set dst (StoreL dst (URShiftL (LoadL dst) shift))); |
8883 effect(KILL cr); | 8870 effect(KILL cr); |
9582 format %{ "orq $dst, $src\t# long" %} | 9569 format %{ "orq $dst, $src\t# long" %} |
9583 opcode(0x0B); | 9570 opcode(0x0B); |
9584 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | 9571 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); |
9585 ins_pipe(ialu_reg_reg); | 9572 ins_pipe(ialu_reg_reg); |
9586 %} | 9573 %} |
9574 | |
9575 // Use any_RegP to match R15 (TLS register) without spilling. | |
9576 instruct orL_rReg_castP2X(rRegL dst, any_RegP src, rFlagsReg cr) %{ | |
9577 match(Set dst (OrL dst (CastP2X src))); | |
9578 effect(KILL cr); | |
9579 | |
9580 format %{ "orq $dst, $src\t# long" %} | |
9581 opcode(0x0B); | |
9582 ins_encode(REX_reg_reg_wide(dst, src), OpcP, reg_reg(dst, src)); | |
9583 ins_pipe(ialu_reg_reg); | |
9584 %} | |
9585 | |
9587 | 9586 |
9588 // Or Register with Immediate | 9587 // Or Register with Immediate |
9589 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) | 9588 instruct orL_rReg_imm(rRegL dst, immL32 src, rFlagsReg cr) |
9590 %{ | 9589 %{ |
9591 match(Set dst (OrL dst src)); | 9590 match(Set dst (OrL dst src)); |