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);
|