< prev index next >

src/hotspot/cpu/x86/x86_64.ad

Print this page


   1 //
   2 // Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
   3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 //
   5 // This code is free software; you can redistribute it and/or modify it
   6 // under the terms of the GNU General Public License version 2 only, as
   7 // published by the Free Software Foundation.
   8 //
   9 // This code is distributed in the hope that it will be useful, but WITHOUT
  10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 // version 2 for more details (a copy is included in the LICENSE file that
  13 // accompanied this code).
  14 //
  15 // You should have received a copy of the GNU General Public License version
  16 // 2 along with this work; if not, write to the Free Software Foundation,
  17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 //
  19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 // or visit www.oracle.com if you need additional information or have any
  21 // questions.
  22 //


 525 reg_class int_rbx_reg(RBX);
 526 
 527 // Singleton class for RCX int register
 528 reg_class int_rcx_reg(RCX);
 529 
 530 // Singleton class for RCX int register
 531 reg_class int_rdx_reg(RDX);
 532 
 533 // Singleton class for RCX int register
 534 reg_class int_rdi_reg(RDI);
 535 
 536 // Singleton class for instruction pointer
 537 // reg_class ip_reg(RIP);
 538 
 539 %}
 540 
 541 source_hpp %{
 542 #if INCLUDE_ZGC
 543 #include "gc/z/zBarrierSetAssembler.hpp"
 544 #endif










 545 %}
 546 
 547 //----------SOURCE BLOCK-------------------------------------------------------
 548 // This is a block of C++ code which provides values, functions, and
 549 // definitions necessary in the rest of the architecture description
 550 source %{
 551 #define   RELOC_IMM64    Assembler::imm_operand
 552 #define   RELOC_DISP32   Assembler::disp32_operand
 553 
 554 #define __ _masm.
 555 
 556 static bool generate_vzeroupper(Compile* C) {
 557   return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false;  // Generate vzeroupper
 558 }
 559 
 560 static int clear_avx_size() {
 561   return generate_vzeroupper(Compile::current()) ? 3: 0;  // vzeroupper
 562 }
 563 
 564 // !!!!! Special hack to get all types of calls to specify the byte offset


6694   ins_encode %{
6695     __ movl($dst$$Register, $src$$Register);
6696   %}
6697   ins_pipe(ialu_reg_reg); // XXX
6698 %}
6699 
6700 // Convert compressed oop into int for vectors alignment masking
6701 // in case of 32bit oops (heap < 4Gb).
6702 instruct convN2I(rRegI dst, rRegN src)
6703 %{
6704   predicate(Universe::narrow_oop_shift() == 0);
6705   match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6706 
6707   format %{ "movl    $dst, $src\t# compressed ptr -> int" %}
6708   ins_encode %{
6709     __ movl($dst$$Register, $src$$Register);
6710   %}
6711   ins_pipe(ialu_reg_reg); // XXX
6712 %}
6713 





















































6714 // Convert oop pointer into compressed form
6715 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6716   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6717   match(Set dst (EncodeP src));
6718   effect(KILL cr);
6719   format %{ "encode_heap_oop $dst,$src" %}
6720   ins_encode %{
6721     Register s = $src$$Register;
6722     Register d = $dst$$Register;
6723     if (s != d) {
6724       __ movq(d, s);
6725     }
6726     __ encode_heap_oop(d);
6727   %}
6728   ins_pipe(ialu_reg_long);
6729 %}
6730 
6731 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6732   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6733   match(Set dst (EncodeP src));


7543 %{
7544   match(Set cr (StoreLConditional mem (Binary oldval newval)));
7545   effect(KILL oldval);
7546 
7547   format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7548   opcode(0x0F, 0xB1);
7549   ins_encode(lock_prefix,
7550              REX_reg_mem_wide(newval, mem),
7551              OpcP, OpcS,
7552              reg_mem(newval, mem));
7553   ins_pipe(pipe_cmpxchg);
7554 %}
7555 
7556 
7557 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7558 instruct compareAndSwapP(rRegI res,
7559                          memory mem_ptr,
7560                          rax_RegP oldval, rRegP newval,
7561                          rFlagsReg cr)
7562 %{
7563   predicate(VM_Version::supports_cx8());
7564   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7565   match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
7566   effect(KILL cr, KILL oldval);
7567 
7568   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7569             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7570             "sete    $res\n\t"
7571             "movzbl  $res, $res" %}
7572   opcode(0x0F, 0xB1);
7573   ins_encode(lock_prefix,
7574              REX_reg_mem_wide(newval, mem_ptr),
7575              OpcP, OpcS,
7576              reg_mem(newval, mem_ptr),
7577              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7578              REX_reg_breg(res, res), // movzbl
7579              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7580   ins_pipe( pipe_cmpxchg );
7581 %}
7582 


























7583 instruct compareAndSwapL(rRegI res,
7584                          memory mem_ptr,
7585                          rax_RegL oldval, rRegL newval,
7586                          rFlagsReg cr)
7587 %{
7588   predicate(VM_Version::supports_cx8());
7589   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7590   match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
7591   effect(KILL cr, KILL oldval);
7592 
7593   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7594             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7595             "sete    $res\n\t"
7596             "movzbl  $res, $res" %}
7597   opcode(0x0F, 0xB1);
7598   ins_encode(lock_prefix,
7599              REX_reg_mem_wide(newval, mem_ptr),
7600              OpcP, OpcS,
7601              reg_mem(newval, mem_ptr),
7602              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete


7665   format %{ "cmpxchgw $mem_ptr,$newval\t# "
7666             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7667             "sete    $res\n\t"
7668             "movzbl  $res, $res" %}
7669   opcode(0x0F, 0xB1);
7670   ins_encode(lock_prefix,
7671              SizePrefix,
7672              REX_reg_mem(newval, mem_ptr),
7673              OpcP, OpcS,
7674              reg_mem(newval, mem_ptr),
7675              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7676              REX_reg_breg(res, res), // movzbl
7677              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7678   ins_pipe( pipe_cmpxchg );
7679 %}
7680 
7681 instruct compareAndSwapN(rRegI res,
7682                           memory mem_ptr,
7683                           rax_RegN oldval, rRegN newval,
7684                           rFlagsReg cr) %{

7685   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7686   match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
7687   effect(KILL cr, KILL oldval);
7688 
7689   format %{ "cmpxchgl $mem_ptr,$newval\t# "
7690             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7691             "sete    $res\n\t"
7692             "movzbl  $res, $res" %}
7693   opcode(0x0F, 0xB1);
7694   ins_encode(lock_prefix,
7695              REX_reg_mem(newval, mem_ptr),
7696              OpcP, OpcS,
7697              reg_mem(newval, mem_ptr),
7698              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7699              REX_reg_breg(res, res), // movzbl
7700              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7701   ins_pipe( pipe_cmpxchg );
7702 %}
7703 

























7704 instruct compareAndExchangeB(
7705                          memory mem_ptr,
7706                          rax_RegI oldval, rRegI newval,
7707                          rFlagsReg cr)
7708 %{
7709   match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval)));
7710   effect(KILL cr);
7711 
7712   format %{ "cmpxchgb $mem_ptr,$newval\t# "
7713             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"  %}
7714   opcode(0x0F, 0xB0);
7715   ins_encode(lock_prefix,
7716              REX_breg_mem(newval, mem_ptr),
7717              OpcP, OpcS,
7718              reg_mem(newval, mem_ptr) // lock cmpxchg
7719              );
7720   ins_pipe( pipe_cmpxchg );
7721 %}
7722 
7723 instruct compareAndExchangeS(


7766 %{
7767   predicate(VM_Version::supports_cx8());
7768   match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
7769   effect(KILL cr);
7770 
7771   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7772             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"  %}
7773   opcode(0x0F, 0xB1);
7774   ins_encode(lock_prefix,
7775              REX_reg_mem_wide(newval, mem_ptr),
7776              OpcP, OpcS,
7777              reg_mem(newval, mem_ptr)  // lock cmpxchg
7778             );
7779   ins_pipe( pipe_cmpxchg );
7780 %}
7781 
7782 instruct compareAndExchangeN(
7783                           memory mem_ptr,
7784                           rax_RegN oldval, rRegN newval,
7785                           rFlagsReg cr) %{

7786   match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
7787   effect(KILL cr);
7788 
7789   format %{ "cmpxchgl $mem_ptr,$newval\t# "
7790             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7791   opcode(0x0F, 0xB1);
7792   ins_encode(lock_prefix,
7793              REX_reg_mem(newval, mem_ptr),
7794              OpcP, OpcS,
7795              reg_mem(newval, mem_ptr)  // lock cmpxchg
7796           );
7797   ins_pipe( pipe_cmpxchg );
7798 %}
7799 























7800 instruct compareAndExchangeP(
7801                          memory mem_ptr,
7802                          rax_RegP oldval, rRegP newval,
7803                          rFlagsReg cr)
7804 %{
7805   predicate(VM_Version::supports_cx8());
7806   match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
7807   effect(KILL cr);
7808 
7809   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7810             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7811   opcode(0x0F, 0xB1);
7812   ins_encode(lock_prefix,
7813              REX_reg_mem_wide(newval, mem_ptr),
7814              OpcP, OpcS,
7815              reg_mem(newval, mem_ptr)  // lock cmpxchg
7816           );

























7817   ins_pipe( pipe_cmpxchg );
7818 %}
7819 
7820 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7821   predicate(n->as_LoadStore()->result_not_used());
7822   match(Set dummy (GetAndAddB mem add));
7823   effect(KILL cr);
7824   format %{ "ADDB  [$mem],$add" %}
7825   ins_encode %{
7826     if (os::is_MP()) { __ lock(); }
7827     __ addb($mem$$Address, $add$$constant);
7828   %}
7829   ins_pipe( pipe_cmpxchg );
7830 %}
7831 
7832 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{
7833   match(Set newval (GetAndAddB mem newval));
7834   effect(KILL cr);
7835   format %{ "XADDB  [$mem],$newval" %}
7836   ins_encode %{


   1 //
   2 // Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 //
   5 // This code is free software; you can redistribute it and/or modify it
   6 // under the terms of the GNU General Public License version 2 only, as
   7 // published by the Free Software Foundation.
   8 //
   9 // This code is distributed in the hope that it will be useful, but WITHOUT
  10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 // version 2 for more details (a copy is included in the LICENSE file that
  13 // accompanied this code).
  14 //
  15 // You should have received a copy of the GNU General Public License version
  16 // 2 along with this work; if not, write to the Free Software Foundation,
  17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 //
  19 // Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20 // or visit www.oracle.com if you need additional information or have any
  21 // questions.
  22 //


 525 reg_class int_rbx_reg(RBX);
 526 
 527 // Singleton class for RCX int register
 528 reg_class int_rcx_reg(RCX);
 529 
 530 // Singleton class for RCX int register
 531 reg_class int_rdx_reg(RDX);
 532 
 533 // Singleton class for RCX int register
 534 reg_class int_rdi_reg(RDI);
 535 
 536 // Singleton class for instruction pointer
 537 // reg_class ip_reg(RIP);
 538 
 539 %}
 540 
 541 source_hpp %{
 542 #if INCLUDE_ZGC
 543 #include "gc/z/zBarrierSetAssembler.hpp"
 544 #endif
 545 #if INCLUDE_SHENANDOAHGC
 546 #include "gc/shenandoah/shenandoahBrooksPointer.hpp"
 547 #include "gc/shenandoah/shenandoahBarrierSetAssembler.hpp"
 548 #else
 549 // This is normally available through shenandoah_globals.hpp, but if Shenandoah
 550 // compilation is disabled, there is no such header. Fake the constants for predicates
 551 // to work. This workaround would be removed as we backport more stuff, including
 552 // the split shenandoah_x86_64.ad.
 553 #define ShenandoahCASBarrier false
 554 #endif
 555 %}
 556 
 557 //----------SOURCE BLOCK-------------------------------------------------------
 558 // This is a block of C++ code which provides values, functions, and
 559 // definitions necessary in the rest of the architecture description
 560 source %{
 561 #define   RELOC_IMM64    Assembler::imm_operand
 562 #define   RELOC_DISP32   Assembler::disp32_operand
 563 
 564 #define __ _masm.
 565 
 566 static bool generate_vzeroupper(Compile* C) {
 567   return (VM_Version::supports_vzeroupper() && (C->max_vector_size() > 16 || C->clear_upper_avx() == true)) ? true: false;  // Generate vzeroupper
 568 }
 569 
 570 static int clear_avx_size() {
 571   return generate_vzeroupper(Compile::current()) ? 3: 0;  // vzeroupper
 572 }
 573 
 574 // !!!!! Special hack to get all types of calls to specify the byte offset


6704   ins_encode %{
6705     __ movl($dst$$Register, $src$$Register);
6706   %}
6707   ins_pipe(ialu_reg_reg); // XXX
6708 %}
6709 
6710 // Convert compressed oop into int for vectors alignment masking
6711 // in case of 32bit oops (heap < 4Gb).
6712 instruct convN2I(rRegI dst, rRegN src)
6713 %{
6714   predicate(Universe::narrow_oop_shift() == 0);
6715   match(Set dst (ConvL2I (CastP2X (DecodeN src))));
6716 
6717   format %{ "movl    $dst, $src\t# compressed ptr -> int" %}
6718   ins_encode %{
6719     __ movl($dst$$Register, $src$$Register);
6720   %}
6721   ins_pipe(ialu_reg_reg); // XXX
6722 %}
6723 
6724 instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{
6725   match(Set dst (ShenandoahReadBarrier src));
6726   effect(DEF dst, USE src);
6727   ins_cost(125); // XXX
6728   format %{ "shenandoah_rb $dst, $src" %}
6729   ins_encode %{
6730 #if INCLUDE_SHENANDOAHGC
6731     Register d = $dst$$Register;
6732     Register s = $src$$Register;
6733     __ movptr(d, Address(s, ShenandoahBrooksPointer::byte_offset()));
6734 #else
6735     ShouldNotReachHere();
6736 #endif
6737   %}
6738   ins_pipe(ialu_reg_mem);
6739 %}
6740 
6741 instruct shenandoahRBNarrow(rRegP dst, rRegN src) %{
6742   predicate(UseCompressedOops && (Universe::narrow_oop_shift() == 0));
6743   match(Set dst (ShenandoahReadBarrier (DecodeN src)));
6744   effect(DEF dst, USE src);
6745   ins_cost(125); // XXX
6746   format %{ "shenandoah_rb $dst, $src" %}
6747   ins_encode %{
6748 #if INCLUDE_SHENANDOAHGC
6749     Register d = $dst$$Register;
6750     Register s = $src$$Register;
6751     __ movptr(d, Address(r12, s, Address::times_1, ShenandoahBrooksPointer::byte_offset()));
6752 #else
6753     ShouldNotReachHere();
6754 #endif
6755   %}
6756   ins_pipe(ialu_reg_mem);
6757 %}
6758 
6759 instruct shenandoahRBNarrowShift(rRegP dst, rRegN src) %{
6760   predicate(UseCompressedOops && (Universe::narrow_oop_shift() == Address::times_8));
6761   match(Set dst (ShenandoahReadBarrier (DecodeN src)));
6762   effect(DEF dst, USE src);
6763   ins_cost(125); // XXX
6764   format %{ "shenandoah_rb $dst, $src" %}
6765   ins_encode %{
6766 #if INCLUDE_SHENANDOAHGC
6767     Register d = $dst$$Register;
6768     Register s = $src$$Register;
6769     __ movptr(d, Address(r12, s, Address::times_8, ShenandoahBrooksPointer::byte_offset()));
6770 #else
6771     ShouldNotReachHere();
6772 #endif
6773   %}
6774   ins_pipe(ialu_reg_mem);
6775 %}
6776 
6777 // Convert oop pointer into compressed form
6778 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
6779   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
6780   match(Set dst (EncodeP src));
6781   effect(KILL cr);
6782   format %{ "encode_heap_oop $dst,$src" %}
6783   ins_encode %{
6784     Register s = $src$$Register;
6785     Register d = $dst$$Register;
6786     if (s != d) {
6787       __ movq(d, s);
6788     }
6789     __ encode_heap_oop(d);
6790   %}
6791   ins_pipe(ialu_reg_long);
6792 %}
6793 
6794 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
6795   predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
6796   match(Set dst (EncodeP src));


7606 %{
7607   match(Set cr (StoreLConditional mem (Binary oldval newval)));
7608   effect(KILL oldval);
7609 
7610   format %{ "cmpxchgq $mem, $newval\t# If rax == $mem then store $newval into $mem" %}
7611   opcode(0x0F, 0xB1);
7612   ins_encode(lock_prefix,
7613              REX_reg_mem_wide(newval, mem),
7614              OpcP, OpcS,
7615              reg_mem(newval, mem));
7616   ins_pipe(pipe_cmpxchg);
7617 %}
7618 
7619 
7620 // XXX No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7621 instruct compareAndSwapP(rRegI res,
7622                          memory mem_ptr,
7623                          rax_RegP oldval, rRegP newval,
7624                          rFlagsReg cr)
7625 %{
7626   predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR));
7627   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7628   match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
7629   effect(KILL cr, KILL oldval);
7630 
7631   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7632             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7633             "sete    $res\n\t"
7634             "movzbl  $res, $res" %}
7635   opcode(0x0F, 0xB1);
7636   ins_encode(lock_prefix,
7637              REX_reg_mem_wide(newval, mem_ptr),
7638              OpcP, OpcS,
7639              reg_mem(newval, mem_ptr),
7640              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7641              REX_reg_breg(res, res), // movzbl
7642              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7643   ins_pipe( pipe_cmpxchg );
7644 %}
7645 
7646 instruct compareAndSwapP_shenandoah(rRegI res,
7647                                     memory mem_ptr,
7648                                     rRegP tmp1, rRegP tmp2,
7649                                     rax_RegP oldval, rRegP newval,
7650                                     rFlagsReg cr)
7651 %{
7652   predicate(VM_Version::supports_cx8() && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR);
7653   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
7654   match(Set res (WeakCompareAndSwapP mem_ptr (Binary oldval newval)));
7655   effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
7656 
7657   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
7658 
7659   ins_encode %{
7660 #if INCLUDE_SHENANDOAHGC
7661     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
7662             false, // swap
7663             $tmp1$$Register, $tmp2$$Register
7664     );
7665 #else
7666     ShouldNotReachHere();
7667 #endif
7668   %}
7669   ins_pipe( pipe_cmpxchg );
7670 %}
7671 
7672 instruct compareAndSwapL(rRegI res,
7673                          memory mem_ptr,
7674                          rax_RegL oldval, rRegL newval,
7675                          rFlagsReg cr)
7676 %{
7677   predicate(VM_Version::supports_cx8());
7678   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7679   match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
7680   effect(KILL cr, KILL oldval);
7681 
7682   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7683             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7684             "sete    $res\n\t"
7685             "movzbl  $res, $res" %}
7686   opcode(0x0F, 0xB1);
7687   ins_encode(lock_prefix,
7688              REX_reg_mem_wide(newval, mem_ptr),
7689              OpcP, OpcS,
7690              reg_mem(newval, mem_ptr),
7691              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete


7754   format %{ "cmpxchgw $mem_ptr,$newval\t# "
7755             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7756             "sete    $res\n\t"
7757             "movzbl  $res, $res" %}
7758   opcode(0x0F, 0xB1);
7759   ins_encode(lock_prefix,
7760              SizePrefix,
7761              REX_reg_mem(newval, mem_ptr),
7762              OpcP, OpcS,
7763              reg_mem(newval, mem_ptr),
7764              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7765              REX_reg_breg(res, res), // movzbl
7766              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7767   ins_pipe( pipe_cmpxchg );
7768 %}
7769 
7770 instruct compareAndSwapN(rRegI res,
7771                           memory mem_ptr,
7772                           rax_RegN oldval, rRegN newval,
7773                           rFlagsReg cr) %{
7774   predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR);
7775   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7776   match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
7777   effect(KILL cr, KILL oldval);
7778 
7779   format %{ "cmpxchgl $mem_ptr,$newval\t# "
7780             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"
7781             "sete    $res\n\t"
7782             "movzbl  $res, $res" %}
7783   opcode(0x0F, 0xB1);
7784   ins_encode(lock_prefix,
7785              REX_reg_mem(newval, mem_ptr),
7786              OpcP, OpcS,
7787              reg_mem(newval, mem_ptr),
7788              REX_breg(res), Opcode(0x0F), Opcode(0x94), reg(res), // sete
7789              REX_reg_breg(res, res), // movzbl
7790              Opcode(0xF), Opcode(0xB6), reg_reg(res, res));
7791   ins_pipe( pipe_cmpxchg );
7792 %}
7793 
7794 instruct compareAndSwapN_shenandoah(rRegI res,
7795                                     memory mem_ptr,
7796                                     rRegP tmp1, rRegP tmp2,
7797                                     rax_RegN oldval, rRegN newval,
7798                                     rFlagsReg cr) %{
7799   predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR);
7800   match(Set res (CompareAndSwapN mem_ptr (Binary oldval newval)));
7801   match(Set res (WeakCompareAndSwapN mem_ptr (Binary oldval newval)));
7802   effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval);
7803 
7804   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
7805 
7806   ins_encode %{
7807 #if INCLUDE_SHENANDOAHGC
7808     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
7809             false, // swap
7810             $tmp1$$Register, $tmp2$$Register
7811     );
7812 #else
7813     ShouldNotReachHere();
7814 #endif
7815   %}
7816   ins_pipe( pipe_cmpxchg );
7817 %}
7818 
7819 instruct compareAndExchangeB(
7820                          memory mem_ptr,
7821                          rax_RegI oldval, rRegI newval,
7822                          rFlagsReg cr)
7823 %{
7824   match(Set oldval (CompareAndExchangeB mem_ptr (Binary oldval newval)));
7825   effect(KILL cr);
7826 
7827   format %{ "cmpxchgb $mem_ptr,$newval\t# "
7828             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"  %}
7829   opcode(0x0F, 0xB0);
7830   ins_encode(lock_prefix,
7831              REX_breg_mem(newval, mem_ptr),
7832              OpcP, OpcS,
7833              reg_mem(newval, mem_ptr) // lock cmpxchg
7834              );
7835   ins_pipe( pipe_cmpxchg );
7836 %}
7837 
7838 instruct compareAndExchangeS(


7881 %{
7882   predicate(VM_Version::supports_cx8());
7883   match(Set oldval (CompareAndExchangeL mem_ptr (Binary oldval newval)));
7884   effect(KILL cr);
7885 
7886   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7887             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t"  %}
7888   opcode(0x0F, 0xB1);
7889   ins_encode(lock_prefix,
7890              REX_reg_mem_wide(newval, mem_ptr),
7891              OpcP, OpcS,
7892              reg_mem(newval, mem_ptr)  // lock cmpxchg
7893             );
7894   ins_pipe( pipe_cmpxchg );
7895 %}
7896 
7897 instruct compareAndExchangeN(
7898                           memory mem_ptr,
7899                           rax_RegN oldval, rRegN newval,
7900                           rFlagsReg cr) %{
7901   predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypeNarrowOop::NULL_PTR);
7902   match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
7903   effect(KILL cr);
7904 
7905   format %{ "cmpxchgl $mem_ptr,$newval\t# "
7906             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7907   opcode(0x0F, 0xB1);
7908   ins_encode(lock_prefix,
7909              REX_reg_mem(newval, mem_ptr),
7910              OpcP, OpcS,
7911              reg_mem(newval, mem_ptr)  // lock cmpxchg
7912           );
7913   ins_pipe( pipe_cmpxchg );
7914 %}
7915 
7916 instruct compareAndExchangeN_shenandoah(memory mem_ptr,
7917                                         rax_RegN oldval, rRegN newval,
7918                                         rRegP tmp1, rRegP tmp2,
7919                                         rFlagsReg cr) %{
7920   predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypeNarrowOop::NULL_PTR);
7921   match(Set oldval (CompareAndExchangeN mem_ptr (Binary oldval newval)));
7922   effect(TEMP tmp1, TEMP tmp2, KILL cr);
7923 
7924   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
7925 
7926   ins_encode %{
7927 #if INCLUDE_SHENANDOAHGC
7928     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
7929             true, // exchange
7930             $tmp1$$Register, $tmp2$$Register
7931     );
7932 #else
7933     ShouldNotReachHere();
7934 #endif
7935   %}
7936   ins_pipe( pipe_cmpxchg );
7937 %}
7938 
7939 instruct compareAndExchangeP(
7940                          memory mem_ptr,
7941                          rax_RegP oldval, rRegP newval,
7942                          rFlagsReg cr)
7943 %{
7944   predicate(VM_Version::supports_cx8() && (!UseShenandoahGC || ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR));
7945   match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
7946   effect(KILL cr);
7947 
7948   format %{ "cmpxchgq $mem_ptr,$newval\t# "
7949             "If rax == $mem_ptr then store $newval into $mem_ptr\n\t" %}
7950   opcode(0x0F, 0xB1);
7951   ins_encode(lock_prefix,
7952              REX_reg_mem_wide(newval, mem_ptr),
7953              OpcP, OpcS,
7954              reg_mem(newval, mem_ptr)  // lock cmpxchg
7955           );
7956   ins_pipe( pipe_cmpxchg );
7957 %}
7958 
7959 instruct compareAndExchangeP_shenandoah(memory mem_ptr,
7960                                         rax_RegP oldval, rRegP newval,
7961                                         rRegP tmp1, rRegP tmp2,
7962                                         rFlagsReg cr)
7963 %{
7964   predicate(VM_Version::supports_cx8() && UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR);
7965   match(Set oldval (CompareAndExchangeP mem_ptr (Binary oldval newval)));
7966   effect(KILL cr, TEMP tmp1, TEMP tmp2);
7967   ins_cost(1000);
7968 
7969   format %{ "shenandoah_cas_oop $mem_ptr,$newval" %}
7970 
7971   ins_encode %{
7972 #if INCLUDE_SHENANDOAHGC
7973     ShenandoahBarrierSet::assembler()->cmpxchg_oop(&_masm, NULL, $mem_ptr$$Address, $oldval$$Register, $newval$$Register,
7974             true,  // exchange
7975             $tmp1$$Register, $tmp2$$Register
7976     );
7977 #else
7978     ShouldNotReachHere();
7979 #endif
7980   %}
7981   ins_pipe( pipe_cmpxchg );
7982 %}
7983 
7984 instruct xaddB_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
7985   predicate(n->as_LoadStore()->result_not_used());
7986   match(Set dummy (GetAndAddB mem add));
7987   effect(KILL cr);
7988   format %{ "ADDB  [$mem],$add" %}
7989   ins_encode %{
7990     if (os::is_MP()) { __ lock(); }
7991     __ addb($mem$$Address, $add$$constant);
7992   %}
7993   ins_pipe( pipe_cmpxchg );
7994 %}
7995 
7996 instruct xaddB( memory mem, rRegI newval, rFlagsReg cr) %{
7997   match(Set newval (GetAndAddB mem newval));
7998   effect(KILL cr);
7999   format %{ "XADDB  [$mem],$newval" %}
8000   ins_encode %{


< prev index next >