212 // Dynamic register class that selects between nadx_reg and nadx_reg_no_ebp. 213 reg_class_dynamic nadx_reg(nadx_reg_no_ebp, nadx_reg_with_ebp, %{ PreserveFramePointer %}); 214 215 // Floating point registers. Notice FPR0 is not a choice. 216 // FPR0 is not ever allocated; we use clever encodings to fake 217 // a 2-address instructions out of Intels FP stack. 218 reg_class fp_flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L ); 219 220 reg_class fp_dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H, 221 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H, 222 FPR7L,FPR7H ); 223 224 reg_class fp_flt_reg0( FPR1L ); 225 reg_class fp_dbl_reg0( FPR1L,FPR1H ); 226 reg_class fp_dbl_reg1( FPR2L,FPR2H ); 227 reg_class fp_dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H, 228 FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H ); 229 230 %} 231 232 233 //----------SOURCE BLOCK------------------------------------------------------- 234 // This is a block of C++ code which provides values, functions, and 235 // definitions necessary in the rest of the architecture description 236 source_hpp %{ 237 // Must be visible to the DFA in dfa_x86_32.cpp 238 extern bool is_operand_hi32_zero(Node* n); 239 %} 240 241 source %{ 242 #define RELOC_IMM32 Assembler::imm_operand 243 #define RELOC_DISP32 Assembler::disp32_operand 244 245 #define __ _masm. 246 247 // How to find the high register of a Long pair, given the low register 248 #define HIGH_FROM_LOW(x) ((x)+2) 249 250 // These masks are used to provide 128-bit aligned bitmasks to the XMM 251 // instructions, to allow sign-masking or sign-bit flipping. They allow 7283 ins_pipe( pipe_cmpxchg ); 7284 %} 7285 7286 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7287 7288 instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ 7289 predicate(VM_Version::supports_cx8()); 7290 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7291 effect(KILL cr, KILL oldval); 7292 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7293 "MOV $res,0\n\t" 7294 "JNE,s fail\n\t" 7295 "MOV $res,1\n" 7296 "fail:" %} 7297 ins_encode( enc_cmpxchg8(mem_ptr), 7298 enc_flags_ne_to_boolean(res) ); 7299 ins_pipe( pipe_cmpxchg ); 7300 %} 7301 7302 instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{ 7303 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7304 effect(KILL cr, KILL oldval); 7305 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7306 "MOV $res,0\n\t" 7307 "JNE,s fail\n\t" 7308 "MOV $res,1\n" 7309 "fail:" %} 7310 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 7311 ins_pipe( pipe_cmpxchg ); 7312 %} 7313 7314 instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{ 7315 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7316 effect(KILL cr, KILL oldval); 7317 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7318 "MOV $res,0\n\t" 7319 "JNE,s fail\n\t" 7320 "MOV $res,1\n" 7321 "fail:" %} 7322 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 7323 ins_pipe( pipe_cmpxchg ); 7324 %} 7325 7326 instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{ 7327 predicate(n->as_LoadStore()->result_not_used()); 7328 match(Set dummy (GetAndAddI mem add)); 7329 effect(KILL cr); 7330 format %{ "ADDL [$mem],$add" %} | 212 // Dynamic register class that selects between nadx_reg and nadx_reg_no_ebp. 213 reg_class_dynamic nadx_reg(nadx_reg_no_ebp, nadx_reg_with_ebp, %{ PreserveFramePointer %}); 214 215 // Floating point registers. Notice FPR0 is not a choice. 216 // FPR0 is not ever allocated; we use clever encodings to fake 217 // a 2-address instructions out of Intels FP stack. 218 reg_class fp_flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L ); 219 220 reg_class fp_dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H, 221 FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H, 222 FPR7L,FPR7H ); 223 224 reg_class fp_flt_reg0( FPR1L ); 225 reg_class fp_dbl_reg0( FPR1L,FPR1H ); 226 reg_class fp_dbl_reg1( FPR2L,FPR2H ); 227 reg_class fp_dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H, 228 FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H ); 229 230 %} 231 232 source_hpp %{ 233 #if INCLUDE_ALL_GCS 234 #include "shenandoahBarrierSetAssembler_x86.hpp" 235 #endif 236 %} 237 238 //----------SOURCE BLOCK------------------------------------------------------- 239 // This is a block of C++ code which provides values, functions, and 240 // definitions necessary in the rest of the architecture description 241 source_hpp %{ 242 // Must be visible to the DFA in dfa_x86_32.cpp 243 extern bool is_operand_hi32_zero(Node* n); 244 %} 245 246 source %{ 247 #define RELOC_IMM32 Assembler::imm_operand 248 #define RELOC_DISP32 Assembler::disp32_operand 249 250 #define __ _masm. 251 252 // How to find the high register of a Long pair, given the low register 253 #define HIGH_FROM_LOW(x) ((x)+2) 254 255 // These masks are used to provide 128-bit aligned bitmasks to the XMM 256 // instructions, to allow sign-masking or sign-bit flipping. They allow 7288 ins_pipe( pipe_cmpxchg ); 7289 %} 7290 7291 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them 7292 7293 instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{ 7294 predicate(VM_Version::supports_cx8()); 7295 match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval))); 7296 effect(KILL cr, KILL oldval); 7297 format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7298 "MOV $res,0\n\t" 7299 "JNE,s fail\n\t" 7300 "MOV $res,1\n" 7301 "fail:" %} 7302 ins_encode( enc_cmpxchg8(mem_ptr), 7303 enc_flags_ne_to_boolean(res) ); 7304 ins_pipe( pipe_cmpxchg ); 7305 %} 7306 7307 instruct compareAndSwapP( rRegI res, pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{ 7308 predicate(!UseShenandoahGC || !ShenandoahCASBarrier || n->in(3)->in(1)->bottom_type() == TypePtr::NULL_PTR); 7309 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7310 effect(KILL cr, KILL oldval); 7311 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7312 "MOV $res,0\n\t" 7313 "JNE,s fail\n\t" 7314 "MOV $res,1\n" 7315 "fail:" %} 7316 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 7317 ins_pipe( pipe_cmpxchg ); 7318 %} 7319 7320 instruct compareAndSwapP_shenandoah(rRegI res, 7321 memory mem_ptr, 7322 eRegP tmp1, eRegP tmp2, 7323 eAXRegP oldval, eCXRegP newval, 7324 eFlagsReg cr) 7325 %{ 7326 predicate(UseShenandoahGC && ShenandoahCASBarrier && n->in(3)->in(1)->bottom_type() != TypePtr::NULL_PTR); 7327 match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval))); 7328 effect(TEMP tmp1, TEMP tmp2, KILL cr, KILL oldval); 7329 7330 format %{ "shenandoah_cas_oop $mem_ptr,$newval" %} 7331 7332 ins_encode %{ 7333 ShenandoahBarrierSetAssembler::bsasm()->cmpxchg_oop(&_masm, 7334 $res$$Register, $mem_ptr$$Address, $oldval$$Register, $newval$$Register, 7335 false, // swap 7336 $tmp1$$Register, $tmp2$$Register 7337 ); 7338 %} 7339 ins_pipe( pipe_cmpxchg ); 7340 %} 7341 7342 instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{ 7343 match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval))); 7344 effect(KILL cr, KILL oldval); 7345 format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t" 7346 "MOV $res,0\n\t" 7347 "JNE,s fail\n\t" 7348 "MOV $res,1\n" 7349 "fail:" %} 7350 ins_encode( enc_cmpxchg(mem_ptr), enc_flags_ne_to_boolean(res) ); 7351 ins_pipe( pipe_cmpxchg ); 7352 %} 7353 7354 instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{ 7355 predicate(n->as_LoadStore()->result_not_used()); 7356 match(Set dummy (GetAndAddI mem add)); 7357 effect(KILL cr); 7358 format %{ "ADDL [$mem],$add" %} |