< prev index next >

src/hotspot/cpu/x86/x86_32.ad

Print this page




2070     int    jf_as_bits = jint_cast( jf );
2071     emit_d32(cbuf, jf_as_bits);
2072   %}
2073 
2074   enc_class Con16 (immI src) %{    // Con16(storeImmI)
2075     // Output immediate
2076     $$$emit16$src$$constant;
2077   %}
2078 
2079   enc_class Con_d32(immI src) %{
2080     emit_d32(cbuf,$src$$constant);
2081   %}
2082 
2083   enc_class conmemref (eRegP t1) %{    // Con32(storeImmI)
2084     // Output immediate memory reference
2085     emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2086     emit_d32(cbuf, 0x00);
2087   %}
2088 
2089   enc_class lock_prefix( ) %{
2090     if( os::is_MP() )
2091       emit_opcode(cbuf,0xF0);         // [Lock]
2092   %}
2093 
2094   // Cmp-xchg long value.
2095   // Note: we need to swap rbx, and rcx before and after the
2096   //       cmpxchg8 instruction because the instruction uses
2097   //       rcx as the high order word of the new value to store but
2098   //       our register encoding uses rbx,.
2099   enc_class enc_cmpxchg8(eSIRegP mem_ptr) %{
2100 
2101     // XCHG  rbx,ecx
2102     emit_opcode(cbuf,0x87);
2103     emit_opcode(cbuf,0xD9);
2104     // [Lock]
2105     if( os::is_MP() )
2106       emit_opcode(cbuf,0xF0);
2107     // CMPXCHG8 [Eptr]
2108     emit_opcode(cbuf,0x0F);
2109     emit_opcode(cbuf,0xC7);
2110     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2111     // XCHG  rbx,ecx
2112     emit_opcode(cbuf,0x87);
2113     emit_opcode(cbuf,0xD9);
2114   %}
2115 
2116   enc_class enc_cmpxchg(eSIRegP mem_ptr) %{
2117     // [Lock]
2118     if( os::is_MP() )
2119       emit_opcode(cbuf,0xF0);
2120 
2121     // CMPXCHG [Eptr]
2122     emit_opcode(cbuf,0x0F);
2123     emit_opcode(cbuf,0xB1);
2124     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2125   %}
2126 
2127   enc_class enc_cmpxchgb(eSIRegP mem_ptr) %{
2128     // [Lock]
2129     if( os::is_MP() )
2130       emit_opcode(cbuf,0xF0);
2131 
2132     // CMPXCHGB [Eptr]
2133     emit_opcode(cbuf,0x0F);
2134     emit_opcode(cbuf,0xB0);
2135     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2136   %}
2137 
2138   enc_class enc_cmpxchgw(eSIRegP mem_ptr) %{
2139     // [Lock]
2140     if( os::is_MP() )
2141       emit_opcode(cbuf,0xF0);
2142 
2143     // 16-bit mode
2144     emit_opcode(cbuf, 0x66);
2145 
2146     // CMPXCHGW [Eptr]
2147     emit_opcode(cbuf,0x0F);
2148     emit_opcode(cbuf,0xB1);
2149     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2150   %}
2151 
2152   enc_class enc_flags_ne_to_boolean( iRegI res ) %{
2153     int res_encoding = $res$$reg;
2154 
2155     // MOV  res,0
2156     emit_opcode( cbuf, 0xB8 + res_encoding);
2157     emit_d32( cbuf, 0 );
2158     // JNE,s  fail
2159     emit_opcode(cbuf,0x75);
2160     emit_d8(cbuf, 5 );


6657   ins_pipe(empty);
6658 %}
6659 
6660 instruct membar_release_lock() %{
6661   match(MemBarReleaseLock);
6662   ins_cost(0);
6663 
6664   size(0);
6665   format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6666   ins_encode( );
6667   ins_pipe(empty);
6668 %}
6669 
6670 instruct membar_volatile(eFlagsReg cr) %{
6671   match(MemBarVolatile);
6672   effect(KILL cr);
6673   ins_cost(400);
6674 
6675   format %{
6676     $$template
6677     if (os::is_MP()) {
6678       $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile"
6679     } else {
6680       $$emit$$"MEMBAR-volatile ! (empty encoding)"
6681     }
6682   %}
6683   ins_encode %{
6684     __ membar(Assembler::StoreLoad);
6685   %}
6686   ins_pipe(pipe_slow);
6687 %}
6688 
6689 instruct unnecessary_membar_volatile() %{
6690   match(MemBarVolatile);
6691   predicate(Matcher::post_store_load_barrier(n));
6692   ins_cost(0);
6693 
6694   size(0);
6695   format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6696   ins_encode( );
6697   ins_pipe(empty);
6698 %}
6699 
6700 instruct membar_storestore() %{
6701   match(MemBarStoreStore);


7266   format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
7267   ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
7268   ins_pipe( pipe_cmpxchg );
7269 %}
7270 
7271 // Conditional-store of a long value.
7272 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG8 on Intel.
7273 instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7274   match(Set cr (StoreLConditional mem (Binary oldval newval)));
7275   effect(KILL oldval);
7276   format %{ "XCHG   EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
7277             "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
7278             "XCHG   EBX,ECX"
7279   %}
7280   ins_encode %{
7281     // Note: we need to swap rbx, and rcx before and after the
7282     //       cmpxchg8 instruction because the instruction uses
7283     //       rcx as the high order word of the new value to store but
7284     //       our register encoding uses rbx.
7285     __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7286     if( os::is_MP() )
7287       __ lock();
7288     __ cmpxchg8($mem$$Address);
7289     __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7290   %}
7291   ins_pipe( pipe_cmpxchg );
7292 %}
7293 
7294 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7295 
7296 instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7297   predicate(VM_Version::supports_cx8());
7298   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7299   match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
7300   effect(KILL cr, KILL oldval);
7301   format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7302             "MOV    $res,0\n\t"
7303             "JNE,s  fail\n\t"
7304             "MOV    $res,1\n"
7305           "fail:" %}
7306   ins_encode( enc_cmpxchg8(mem_ptr),


7392   effect(KILL cr);
7393   format %{ "CMPXCHGW [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
7394   ins_encode( enc_cmpxchgw(mem_ptr) );
7395   ins_pipe( pipe_cmpxchg );
7396 %}
7397 
7398 instruct compareAndExchangeI( pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
7399   match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
7400   effect(KILL cr);
7401   format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
7402   ins_encode( enc_cmpxchg(mem_ptr) );
7403   ins_pipe( pipe_cmpxchg );
7404 %}
7405 
7406 instruct xaddB_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
7407   predicate(n->as_LoadStore()->result_not_used());
7408   match(Set dummy (GetAndAddB mem add));
7409   effect(KILL cr);
7410   format %{ "ADDB  [$mem],$add" %}
7411   ins_encode %{
7412     if (os::is_MP()) { __ lock(); }
7413     __ addb($mem$$Address, $add$$constant);
7414   %}
7415   ins_pipe( pipe_cmpxchg );
7416 %}
7417 
7418 // Important to match to xRegI: only 8-bit regs.
7419 instruct xaddB( memory mem, xRegI newval, eFlagsReg cr) %{
7420   match(Set newval (GetAndAddB mem newval));
7421   effect(KILL cr);
7422   format %{ "XADDB  [$mem],$newval" %}
7423   ins_encode %{
7424     if (os::is_MP()) { __ lock(); }
7425     __ xaddb($mem$$Address, $newval$$Register);
7426   %}
7427   ins_pipe( pipe_cmpxchg );
7428 %}
7429 
7430 instruct xaddS_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
7431   predicate(n->as_LoadStore()->result_not_used());
7432   match(Set dummy (GetAndAddS mem add));
7433   effect(KILL cr);
7434   format %{ "ADDS  [$mem],$add" %}
7435   ins_encode %{
7436     if (os::is_MP()) { __ lock(); }
7437     __ addw($mem$$Address, $add$$constant);
7438   %}
7439   ins_pipe( pipe_cmpxchg );
7440 %}
7441 
7442 instruct xaddS( memory mem, rRegI newval, eFlagsReg cr) %{
7443   match(Set newval (GetAndAddS mem newval));
7444   effect(KILL cr);
7445   format %{ "XADDS  [$mem],$newval" %}
7446   ins_encode %{
7447     if (os::is_MP()) { __ lock(); }
7448     __ xaddw($mem$$Address, $newval$$Register);
7449   %}
7450   ins_pipe( pipe_cmpxchg );
7451 %}
7452 
7453 instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
7454   predicate(n->as_LoadStore()->result_not_used());
7455   match(Set dummy (GetAndAddI mem add));
7456   effect(KILL cr);
7457   format %{ "ADDL  [$mem],$add" %}
7458   ins_encode %{
7459     if (os::is_MP()) { __ lock(); }
7460     __ addl($mem$$Address, $add$$constant);
7461   %}
7462   ins_pipe( pipe_cmpxchg );
7463 %}
7464 
7465 instruct xaddI( memory mem, rRegI newval, eFlagsReg cr) %{
7466   match(Set newval (GetAndAddI mem newval));
7467   effect(KILL cr);
7468   format %{ "XADDL  [$mem],$newval" %}
7469   ins_encode %{
7470     if (os::is_MP()) { __ lock(); }
7471     __ xaddl($mem$$Address, $newval$$Register);
7472   %}
7473   ins_pipe( pipe_cmpxchg );
7474 %}
7475 
7476 // Important to match to xRegI: only 8-bit regs.
7477 instruct xchgB( memory mem, xRegI newval) %{
7478   match(Set newval (GetAndSetB mem newval));
7479   format %{ "XCHGB  $newval,[$mem]" %}
7480   ins_encode %{
7481     __ xchgb($newval$$Register, $mem$$Address);
7482   %}
7483   ins_pipe( pipe_cmpxchg );
7484 %}
7485 
7486 instruct xchgS( memory mem, rRegI newval) %{
7487   match(Set newval (GetAndSetS mem newval));
7488   format %{ "XCHGW  $newval,[$mem]" %}
7489   ins_encode %{
7490     __ xchgw($newval$$Register, $mem$$Address);




2070     int    jf_as_bits = jint_cast( jf );
2071     emit_d32(cbuf, jf_as_bits);
2072   %}
2073 
2074   enc_class Con16 (immI src) %{    // Con16(storeImmI)
2075     // Output immediate
2076     $$$emit16$src$$constant;
2077   %}
2078 
2079   enc_class Con_d32(immI src) %{
2080     emit_d32(cbuf,$src$$constant);
2081   %}
2082 
2083   enc_class conmemref (eRegP t1) %{    // Con32(storeImmI)
2084     // Output immediate memory reference
2085     emit_rm(cbuf, 0x00, $t1$$reg, 0x05 );
2086     emit_d32(cbuf, 0x00);
2087   %}
2088 
2089   enc_class lock_prefix( ) %{

2090     emit_opcode(cbuf,0xF0);         // [Lock]
2091   %}
2092 
2093   // Cmp-xchg long value.
2094   // Note: we need to swap rbx, and rcx before and after the
2095   //       cmpxchg8 instruction because the instruction uses
2096   //       rcx as the high order word of the new value to store but
2097   //       our register encoding uses rbx,.
2098   enc_class enc_cmpxchg8(eSIRegP mem_ptr) %{
2099 
2100     // XCHG  rbx,ecx
2101     emit_opcode(cbuf,0x87);
2102     emit_opcode(cbuf,0xD9);
2103     // [Lock]

2104     emit_opcode(cbuf,0xF0);
2105     // CMPXCHG8 [Eptr]
2106     emit_opcode(cbuf,0x0F);
2107     emit_opcode(cbuf,0xC7);
2108     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2109     // XCHG  rbx,ecx
2110     emit_opcode(cbuf,0x87);
2111     emit_opcode(cbuf,0xD9);
2112   %}
2113 
2114   enc_class enc_cmpxchg(eSIRegP mem_ptr) %{
2115     // [Lock]

2116     emit_opcode(cbuf,0xF0);
2117 
2118     // CMPXCHG [Eptr]
2119     emit_opcode(cbuf,0x0F);
2120     emit_opcode(cbuf,0xB1);
2121     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2122   %}
2123 
2124   enc_class enc_cmpxchgb(eSIRegP mem_ptr) %{
2125     // [Lock]

2126     emit_opcode(cbuf,0xF0);
2127 
2128     // CMPXCHGB [Eptr]
2129     emit_opcode(cbuf,0x0F);
2130     emit_opcode(cbuf,0xB0);
2131     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2132   %}
2133 
2134   enc_class enc_cmpxchgw(eSIRegP mem_ptr) %{
2135     // [Lock]

2136     emit_opcode(cbuf,0xF0);
2137 
2138     // 16-bit mode
2139     emit_opcode(cbuf, 0x66);
2140 
2141     // CMPXCHGW [Eptr]
2142     emit_opcode(cbuf,0x0F);
2143     emit_opcode(cbuf,0xB1);
2144     emit_rm( cbuf, 0x0, 1, $mem_ptr$$reg );
2145   %}
2146 
2147   enc_class enc_flags_ne_to_boolean( iRegI res ) %{
2148     int res_encoding = $res$$reg;
2149 
2150     // MOV  res,0
2151     emit_opcode( cbuf, 0xB8 + res_encoding);
2152     emit_d32( cbuf, 0 );
2153     // JNE,s  fail
2154     emit_opcode(cbuf,0x75);
2155     emit_d8(cbuf, 5 );


6652   ins_pipe(empty);
6653 %}
6654 
6655 instruct membar_release_lock() %{
6656   match(MemBarReleaseLock);
6657   ins_cost(0);
6658 
6659   size(0);
6660   format %{ "MEMBAR-release (a FastUnlock follows so empty encoding)" %}
6661   ins_encode( );
6662   ins_pipe(empty);
6663 %}
6664 
6665 instruct membar_volatile(eFlagsReg cr) %{
6666   match(MemBarVolatile);
6667   effect(KILL cr);
6668   ins_cost(400);
6669 
6670   format %{
6671     $$template

6672     $$emit$$"LOCK ADDL [ESP + #0], 0\t! membar_volatile"



6673   %}
6674   ins_encode %{
6675     __ membar(Assembler::StoreLoad);
6676   %}
6677   ins_pipe(pipe_slow);
6678 %}
6679 
6680 instruct unnecessary_membar_volatile() %{
6681   match(MemBarVolatile);
6682   predicate(Matcher::post_store_load_barrier(n));
6683   ins_cost(0);
6684 
6685   size(0);
6686   format %{ "MEMBAR-volatile (unnecessary so empty encoding)" %}
6687   ins_encode( );
6688   ins_pipe(empty);
6689 %}
6690 
6691 instruct membar_storestore() %{
6692   match(MemBarStoreStore);


7257   format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
7258   ins_encode( lock_prefix, Opcode(0x0F), Opcode(0xB1), RegMem(newval, mem) );
7259   ins_pipe( pipe_cmpxchg );
7260 %}
7261 
7262 // Conditional-store of a long value.
7263 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG8 on Intel.
7264 instruct storeLConditional( memory mem, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7265   match(Set cr (StoreLConditional mem (Binary oldval newval)));
7266   effect(KILL oldval);
7267   format %{ "XCHG   EBX,ECX\t# correct order for CMPXCHG8 instruction\n\t"
7268             "CMPXCHG8 $mem,ECX:EBX\t# If EDX:EAX==$mem Then store ECX:EBX into $mem\n\t"
7269             "XCHG   EBX,ECX"
7270   %}
7271   ins_encode %{
7272     // Note: we need to swap rbx, and rcx before and after the
7273     //       cmpxchg8 instruction because the instruction uses
7274     //       rcx as the high order word of the new value to store but
7275     //       our register encoding uses rbx.
7276     __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));

7277     __ lock();
7278     __ cmpxchg8($mem$$Address);
7279     __ xchgl(as_Register(EBX_enc), as_Register(ECX_enc));
7280   %}
7281   ins_pipe( pipe_cmpxchg );
7282 %}
7283 
7284 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
7285 
7286 instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
7287   predicate(VM_Version::supports_cx8());
7288   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
7289   match(Set res (WeakCompareAndSwapL mem_ptr (Binary oldval newval)));
7290   effect(KILL cr, KILL oldval);
7291   format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
7292             "MOV    $res,0\n\t"
7293             "JNE,s  fail\n\t"
7294             "MOV    $res,1\n"
7295           "fail:" %}
7296   ins_encode( enc_cmpxchg8(mem_ptr),


7382   effect(KILL cr);
7383   format %{ "CMPXCHGW [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
7384   ins_encode( enc_cmpxchgw(mem_ptr) );
7385   ins_pipe( pipe_cmpxchg );
7386 %}
7387 
7388 instruct compareAndExchangeI( pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
7389   match(Set oldval (CompareAndExchangeI mem_ptr (Binary oldval newval)));
7390   effect(KILL cr);
7391   format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" %}
7392   ins_encode( enc_cmpxchg(mem_ptr) );
7393   ins_pipe( pipe_cmpxchg );
7394 %}
7395 
7396 instruct xaddB_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
7397   predicate(n->as_LoadStore()->result_not_used());
7398   match(Set dummy (GetAndAddB mem add));
7399   effect(KILL cr);
7400   format %{ "ADDB  [$mem],$add" %}
7401   ins_encode %{
7402     __ lock();
7403     __ addb($mem$$Address, $add$$constant);
7404   %}
7405   ins_pipe( pipe_cmpxchg );
7406 %}
7407 
7408 // Important to match to xRegI: only 8-bit regs.
7409 instruct xaddB( memory mem, xRegI newval, eFlagsReg cr) %{
7410   match(Set newval (GetAndAddB mem newval));
7411   effect(KILL cr);
7412   format %{ "XADDB  [$mem],$newval" %}
7413   ins_encode %{
7414     __ lock();
7415     __ xaddb($mem$$Address, $newval$$Register);
7416   %}
7417   ins_pipe( pipe_cmpxchg );
7418 %}
7419 
7420 instruct xaddS_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
7421   predicate(n->as_LoadStore()->result_not_used());
7422   match(Set dummy (GetAndAddS mem add));
7423   effect(KILL cr);
7424   format %{ "ADDS  [$mem],$add" %}
7425   ins_encode %{
7426     __ lock();
7427     __ addw($mem$$Address, $add$$constant);
7428   %}
7429   ins_pipe( pipe_cmpxchg );
7430 %}
7431 
7432 instruct xaddS( memory mem, rRegI newval, eFlagsReg cr) %{
7433   match(Set newval (GetAndAddS mem newval));
7434   effect(KILL cr);
7435   format %{ "XADDS  [$mem],$newval" %}
7436   ins_encode %{
7437     __ lock();
7438     __ xaddw($mem$$Address, $newval$$Register);
7439   %}
7440   ins_pipe( pipe_cmpxchg );
7441 %}
7442 
7443 instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
7444   predicate(n->as_LoadStore()->result_not_used());
7445   match(Set dummy (GetAndAddI mem add));
7446   effect(KILL cr);
7447   format %{ "ADDL  [$mem],$add" %}
7448   ins_encode %{
7449     __ lock();
7450     __ addl($mem$$Address, $add$$constant);
7451   %}
7452   ins_pipe( pipe_cmpxchg );
7453 %}
7454 
7455 instruct xaddI( memory mem, rRegI newval, eFlagsReg cr) %{
7456   match(Set newval (GetAndAddI mem newval));
7457   effect(KILL cr);
7458   format %{ "XADDL  [$mem],$newval" %}
7459   ins_encode %{
7460     __ lock();
7461     __ xaddl($mem$$Address, $newval$$Register);
7462   %}
7463   ins_pipe( pipe_cmpxchg );
7464 %}
7465 
7466 // Important to match to xRegI: only 8-bit regs.
7467 instruct xchgB( memory mem, xRegI newval) %{
7468   match(Set newval (GetAndSetB mem newval));
7469   format %{ "XCHGB  $newval,[$mem]" %}
7470   ins_encode %{
7471     __ xchgb($newval$$Register, $mem$$Address);
7472   %}
7473   ins_pipe( pipe_cmpxchg );
7474 %}
7475 
7476 instruct xchgS( memory mem, rRegI newval) %{
7477   match(Set newval (GetAndSetS mem newval));
7478   format %{ "XCHGW  $newval,[$mem]" %}
7479   ins_encode %{
7480     __ xchgw($newval$$Register, $mem$$Address);


< prev index next >