comparison src/cpu/x86/vm/x86_64.ad @ 2404:b40d4fa697bf

6964776: c2 should ensure the polling page is reachable on 64 bit Summary: Materialize the pointer to the polling page in a register instead of using rip-relative addressing when the distance from the code cache is larger than disp32. Reviewed-by: never, kvn
author iveresov
date Sun, 27 Mar 2011 13:17:37 -0700
parents 7e88bdae86ec
children 9340a27154cb
comparison
equal deleted inserted replaced
2403:1927db75dd85 2404:b40d4fa697bf
572 } 572 }
573 573
574 // In os_cpu .ad file 574 // In os_cpu .ad file
575 // int MachCallRuntimeNode::ret_addr_offset() 575 // int MachCallRuntimeNode::ret_addr_offset()
576 576
577 // Indicate if the safepoint node needs the polling page as an input. 577 // Indicate if the safepoint node needs the polling page as an input,
578 // Since amd64 does not have absolute addressing but RIP-relative 578 // it does if the polling page is more than disp32 away.
579 // addressing and the polling page is within 2G, it doesn't.
580 bool SafePointNode::needs_polling_address_input() 579 bool SafePointNode::needs_polling_address_input()
581 { 580 {
582 return false; 581 return Assembler::is_polling_page_far();
583 } 582 }
584 583
585 // 584 //
586 // Compute padding required for nodes which need alignment 585 // Compute padding required for nodes which need alignment
587 // 586 //
990 // Remove word for return adr already pushed 989 // Remove word for return adr already pushed
991 // and RBP 990 // and RBP
992 framesize -= 2*wordSize; 991 framesize -= 2*wordSize;
993 992
994 if (framesize) { 993 if (framesize) {
995 st->print_cr("addq\trsp, %d\t# Destroy frame", framesize); 994 st->print_cr("addq rsp, %d\t# Destroy frame", framesize);
996 st->print("\t"); 995 st->print("\t");
997 } 996 }
998 997
999 st->print_cr("popq\trbp"); 998 st->print_cr("popq rbp");
1000 if (do_polling() && C->is_method_compilation()) { 999 if (do_polling() && C->is_method_compilation()) {
1001 st->print_cr("\ttestl\trax, [rip + #offset_to_poll_page]\t"
1002 "# Safepoint: poll for GC");
1003 st->print("\t"); 1000 st->print("\t");
1001 if (Assembler::is_polling_page_far()) {
1002 st->print_cr("movq rscratch1, #polling_page_address\n\t"
1003 "testl rax, [rscratch1]\t"
1004 "# Safepoint: poll for GC");
1005 } else {
1006 st->print_cr("testl rax, [rip + #offset_to_poll_page]\t"
1007 "# Safepoint: poll for GC");
1008 }
1004 } 1009 }
1005 } 1010 }
1006 #endif 1011 #endif
1007 1012
1008 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const 1013 void MachEpilogNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const
1031 1036
1032 // popq rbp 1037 // popq rbp
1033 emit_opcode(cbuf, 0x58 | RBP_enc); 1038 emit_opcode(cbuf, 0x58 | RBP_enc);
1034 1039
1035 if (do_polling() && C->is_method_compilation()) { 1040 if (do_polling() && C->is_method_compilation()) {
1036 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes 1041 MacroAssembler _masm(&cbuf);
1037 // XXX reg_mem doesn't support RIP-relative addressing yet 1042 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_return_type);
1038 cbuf.set_insts_mark(); 1043 if (Assembler::is_polling_page_far()) {
1039 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_return_type, 0); // XXX 1044 __ lea(rscratch1, polling_page);
1040 emit_opcode(cbuf, 0x85); // testl 1045 __ relocate(relocInfo::poll_return_type);
1041 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5 1046 __ testl(rax, Address(rscratch1, 0));
1042 // cbuf.insts_mark() is beginning of instruction 1047 } else {
1043 emit_d32_reloc(cbuf, os::get_polling_page()); 1048 __ testl(rax, polling_page);
1044 // relocInfo::poll_return_type, 1049 }
1045 } 1050 }
1046 } 1051 }
1047 1052
1048 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const 1053 uint MachEpilogNode::size(PhaseRegAlloc* ra_) const
1049 { 1054 {
1050 Compile* C = ra_->C; 1055 return MachNode::size(ra_); // too many variables; just compute it
1051 int framesize = C->frame_slots() << LogBytesPerInt; 1056 // the hard way
1052 assert((framesize & (StackAlignmentInBytes-1)) == 0, "frame size not aligned");
1053 // Remove word for return adr already pushed
1054 // and RBP
1055 framesize -= 2*wordSize;
1056
1057 uint size = 0;
1058
1059 if (do_polling() && C->is_method_compilation()) {
1060 size += 6;
1061 }
1062
1063 // count popq rbp
1064 size++;
1065
1066 if (framesize) {
1067 if (framesize < 0x80) {
1068 size += 4;
1069 } else if (framesize) {
1070 size += 7;
1071 }
1072 }
1073
1074 return size;
1075 } 1057 }
1076 1058
1077 int MachEpilogNode::reloc() const 1059 int MachEpilogNode::reloc() const
1078 { 1060 {
1079 return 2; // a large enough number 1061 return 2; // a large enough number
3408 if (_counters != NULL) { 3390 if (_counters != NULL) {
3409 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr())); 3391 masm.atomic_incl(ExternalAddress((address) _counters->total_entry_count_addr()));
3410 } 3392 }
3411 if (EmitSync & 1) { 3393 if (EmitSync & 1) {
3412 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3394 // Without cast to int32_t a movptr will destroy r10 which is typically obj
3413 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3395 masm.movptr (Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
3414 masm.cmpptr(rsp, (int32_t)NULL_WORD) ; 3396 masm.cmpptr(rsp, (int32_t)NULL_WORD) ;
3415 } else 3397 } else
3416 if (EmitSync & 2) { 3398 if (EmitSync & 2) {
3417 Label DONE_LABEL; 3399 Label DONE_LABEL;
3418 if (UseBiasedLocking) { 3400 if (UseBiasedLocking) {
3419 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument. 3401 // Note: tmpReg maps to the swap_reg argument and scrReg to the tmp_reg argument.
3437 masm.bind(DONE_LABEL); 3419 masm.bind(DONE_LABEL);
3438 masm.nop(); // avoid branch to branch 3420 masm.nop(); // avoid branch to branch
3439 } else { 3421 } else {
3440 Label DONE_LABEL, IsInflated, Egress; 3422 Label DONE_LABEL, IsInflated, Egress;
3441 3423
3442 masm.movptr(tmpReg, Address(objReg, 0)) ; 3424 masm.movptr(tmpReg, Address(objReg, 0)) ;
3443 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased 3425 masm.testl (tmpReg, 0x02) ; // inflated vs stack-locked|neutral|biased
3444 masm.jcc (Assembler::notZero, IsInflated) ; 3426 masm.jcc (Assembler::notZero, IsInflated) ;
3445 3427
3446 // it's stack-locked, biased or neutral 3428 // it's stack-locked, biased or neutral
3447 // TODO: optimize markword triage order to reduce the number of 3429 // TODO: optimize markword triage order to reduce the number of
3448 // conditional branches in the most common cases. 3430 // conditional branches in the most common cases.
3449 // Beware -- there's a subtle invariant that fetch of the markword 3431 // Beware -- there's a subtle invariant that fetch of the markword
3450 // at [FETCH], below, will never observe a biased encoding (*101b). 3432 // at [FETCH], below, will never observe a biased encoding (*101b).
3454 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters); 3436 masm.biased_locking_enter(boxReg, objReg, tmpReg, scrReg, true, DONE_LABEL, NULL, _counters);
3455 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH] 3437 masm.movptr(tmpReg, Address(objReg, 0)) ; // [FETCH]
3456 } 3438 }
3457 3439
3458 // was q will it destroy high? 3440 // was q will it destroy high?
3459 masm.orl (tmpReg, 1) ; 3441 masm.orl (tmpReg, 1) ;
3460 masm.movptr(Address(boxReg, 0), tmpReg) ; 3442 masm.movptr(Address(boxReg, 0), tmpReg) ;
3461 if (os::is_MP()) { masm.lock(); } 3443 if (os::is_MP()) { masm.lock(); }
3462 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg 3444 masm.cmpxchgptr(boxReg, Address(objReg, 0)); // Updates tmpReg
3463 if (_counters != NULL) { 3445 if (_counters != NULL) {
3464 masm.cond_inc32(Assembler::equal, 3446 masm.cond_inc32(Assembler::equal,
3465 ExternalAddress((address) _counters->fast_path_entry_count_addr())); 3447 ExternalAddress((address) _counters->fast_path_entry_count_addr()));
3466 } 3448 }
3483 // relocating (deferring) the following ST. 3465 // relocating (deferring) the following ST.
3484 // We should also think about trying a CAS without having 3466 // We should also think about trying a CAS without having
3485 // fetched _owner. If the CAS is successful we may 3467 // fetched _owner. If the CAS is successful we may
3486 // avoid an RTO->RTS upgrade on the $line. 3468 // avoid an RTO->RTS upgrade on the $line.
3487 // Without cast to int32_t a movptr will destroy r10 which is typically obj 3469 // Without cast to int32_t a movptr will destroy r10 which is typically obj
3488 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ; 3470 masm.movptr(Address(boxReg, 0), (int32_t)intptr_t(markOopDesc::unused_mark())) ;
3489 3471
3490 masm.mov (boxReg, tmpReg) ; 3472 masm.mov (boxReg, tmpReg) ;
3491 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3473 masm.movptr (tmpReg, Address(tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3492 masm.testptr(tmpReg, tmpReg) ; 3474 masm.testptr(tmpReg, tmpReg) ;
3493 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3475 masm.jcc (Assembler::notZero, DONE_LABEL) ;
3494 3476
3495 // It's inflated and appears unlocked 3477 // It's inflated and appears unlocked
3496 if (os::is_MP()) { masm.lock(); } 3478 if (os::is_MP()) { masm.lock(); }
3497 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3479 masm.cmpxchgptr(r15_thread, Address(boxReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3498 // Intentional fall-through into DONE_LABEL ... 3480 // Intentional fall-through into DONE_LABEL ...
3499 3481
3500 masm.bind (DONE_LABEL) ; 3482 masm.bind (DONE_LABEL) ;
3501 masm.nop () ; // avoid jmp to jmp 3483 masm.nop () ; // avoid jmp to jmp
3502 } 3484 }
3511 Register objReg = as_Register($obj$$reg); 3493 Register objReg = as_Register($obj$$reg);
3512 Register boxReg = as_Register($box$$reg); 3494 Register boxReg = as_Register($box$$reg);
3513 Register tmpReg = as_Register($tmp$$reg); 3495 Register tmpReg = as_Register($tmp$$reg);
3514 MacroAssembler masm(&cbuf); 3496 MacroAssembler masm(&cbuf);
3515 3497
3516 if (EmitSync & 4) { 3498 if (EmitSync & 4) {
3517 masm.cmpptr(rsp, 0) ; 3499 masm.cmpptr(rsp, 0) ;
3518 } else 3500 } else
3519 if (EmitSync & 8) { 3501 if (EmitSync & 8) {
3520 Label DONE_LABEL; 3502 Label DONE_LABEL;
3521 if (UseBiasedLocking) { 3503 if (UseBiasedLocking) {
3522 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3504 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
3539 Label DONE_LABEL, Stacked, CheckSucc ; 3521 Label DONE_LABEL, Stacked, CheckSucc ;
3540 3522
3541 if (UseBiasedLocking && !UseOptoBiasInlining) { 3523 if (UseBiasedLocking && !UseOptoBiasInlining) {
3542 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL); 3524 masm.biased_locking_exit(objReg, tmpReg, DONE_LABEL);
3543 } 3525 }
3544 3526
3545 masm.movptr(tmpReg, Address(objReg, 0)) ; 3527 masm.movptr(tmpReg, Address(objReg, 0)) ;
3546 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ; 3528 masm.cmpptr(Address(boxReg, 0), (int32_t)NULL_WORD) ;
3547 masm.jcc (Assembler::zero, DONE_LABEL) ; 3529 masm.jcc (Assembler::zero, DONE_LABEL) ;
3548 masm.testl (tmpReg, 0x02) ; 3530 masm.testl (tmpReg, 0x02) ;
3549 masm.jcc (Assembler::zero, Stacked) ; 3531 masm.jcc (Assembler::zero, Stacked) ;
3550 3532
3551 // It's inflated 3533 // It's inflated
3552 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ; 3534 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2)) ;
3553 masm.xorptr(boxReg, r15_thread) ; 3535 masm.xorptr(boxReg, r15_thread) ;
3554 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ; 3536 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::recursions_offset_in_bytes()-2)) ;
3555 masm.jcc (Assembler::notZero, DONE_LABEL) ; 3537 masm.jcc (Assembler::notZero, DONE_LABEL) ;
3556 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ; 3538 masm.movptr(boxReg, Address (tmpReg, ObjectMonitor::cxq_offset_in_bytes()-2)) ;
3557 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ; 3539 masm.orptr (boxReg, Address (tmpReg, ObjectMonitor::EntryList_offset_in_bytes()-2)) ;
3558 masm.jcc (Assembler::notZero, CheckSucc) ; 3540 masm.jcc (Assembler::notZero, CheckSucc) ;
3559 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3541 masm.movptr(Address (tmpReg, ObjectMonitor::owner_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3560 masm.jmp (DONE_LABEL) ; 3542 masm.jmp (DONE_LABEL) ;
3561 3543
3562 if ((EmitSync & 65536) == 0) { 3544 if ((EmitSync & 65536) == 0) {
3563 Label LSuccess, LGoSlowPath ; 3545 Label LSuccess, LGoSlowPath ;
3564 masm.bind (CheckSucc) ; 3546 masm.bind (CheckSucc) ;
3565 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ; 3547 masm.cmpptr(Address (tmpReg, ObjectMonitor::succ_offset_in_bytes()-2), (int32_t)NULL_WORD) ;
3566 masm.jcc (Assembler::zero, LGoSlowPath) ; 3548 masm.jcc (Assembler::zero, LGoSlowPath) ;
3567 3549
3589 masm.bind (LSuccess) ; 3571 masm.bind (LSuccess) ;
3590 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success 3572 masm.testl (boxReg, 0) ; // set ICC.ZF=1 to indicate success
3591 masm.jmp (DONE_LABEL) ; 3573 masm.jmp (DONE_LABEL) ;
3592 } 3574 }
3593 3575
3594 masm.bind (Stacked) ; 3576 masm.bind (Stacked) ;
3595 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch 3577 masm.movptr(tmpReg, Address (boxReg, 0)) ; // re-fetch
3596 if (os::is_MP()) { masm.lock(); } 3578 if (os::is_MP()) { masm.lock(); }
3597 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box 3579 masm.cmpxchgptr(tmpReg, Address(objReg, 0)); // Uses RAX which is box
3598 3580
3599 if (EmitSync & 65536) { 3581 if (EmitSync & 65536) {
3600 masm.bind (CheckSucc) ; 3582 masm.bind (CheckSucc) ;
3601 } 3583 }
3911 emit_opcode(cbuf, Assembler::REX_B); 3893 emit_opcode(cbuf, Assembler::REX_B);
3912 } 3894 }
3913 emit_opcode(cbuf, 0x58 | (dstenc & 7)); 3895 emit_opcode(cbuf, 0x58 | (dstenc & 7));
3914 3896
3915 // done: 3897 // done:
3916 %}
3917
3918 // Safepoint Poll. This polls the safepoint page, and causes an
3919 // exception if it is not readable. Unfortunately, it kills
3920 // RFLAGS in the process.
3921 enc_class enc_safepoint_poll
3922 %{
3923 // testl %rax, off(%rip) // Opcode + ModRM + Disp32 == 6 bytes
3924 // XXX reg_mem doesn't support RIP-relative addressing yet
3925 cbuf.set_insts_mark();
3926 cbuf.relocate(cbuf.insts_mark(), relocInfo::poll_type, 0); // XXX
3927 emit_opcode(cbuf, 0x85); // testl
3928 emit_rm(cbuf, 0x0, RAX_enc, 0x5); // 00 rax 101 == 0x5
3929 // cbuf.insts_mark() is beginning of instruction
3930 emit_d32_reloc(cbuf, os::get_polling_page());
3931 // relocInfo::poll_type,
3932 %} 3898 %}
3933 %} 3899 %}
3934 3900
3935 3901
3936 3902
4231 op_cost(5); 4197 op_cost(5);
4232 format %{ %} 4198 format %{ %}
4233 interface(CONST_INTER); 4199 interface(CONST_INTER);
4234 %} 4200 %}
4235 4201
4202 operand immP_poll() %{
4203 predicate(n->get_ptr() != 0 && n->get_ptr() == (intptr_t)os::get_polling_page());
4204 match(ConP);
4205
4206 // formats are generated automatically for constants and base registers
4207 format %{ %}
4208 interface(CONST_INTER);
4209 %}
4210
4236 // Pointer Immediate 4211 // Pointer Immediate
4237 operand immN() %{ 4212 operand immN() %{
4238 match(ConN); 4213 match(ConN);
4239 4214
4240 op_cost(10); 4215 op_cost(10);
4838 format %{ %} 4813 format %{ %}
4839 interface(REG_INTER); 4814 interface(REG_INTER);
4840 %} 4815 %}
4841 4816
4842 // Double register operands 4817 // Double register operands
4843 operand regD() 4818 operand regD()
4844 %{ 4819 %{
4845 constraint(ALLOC_IN_RC(double_reg)); 4820 constraint(ALLOC_IN_RC(double_reg));
4846 match(RegD); 4821 match(RegD);
4847 4822
4848 format %{ %} 4823 format %{ %}
6566 opcode(0x33); /* + rd */ 6541 opcode(0x33); /* + rd */
6567 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst)); 6542 ins_encode(REX_reg_reg(dst, dst), OpcP, reg_reg(dst, dst));
6568 ins_pipe(ialu_reg); 6543 ins_pipe(ialu_reg);
6569 %} 6544 %}
6570 6545
6546 instruct loadConP_poll(rRegP dst, immP_poll src) %{
6547 match(Set dst src);
6548 format %{ "movq $dst, $src\t!ptr" %}
6549 ins_encode %{
6550 AddressLiteral polling_page(os::get_polling_page(), relocInfo::poll_type);
6551 __ lea($dst$$Register, polling_page);
6552 %}
6553 ins_pipe(ialu_reg_fat);
6554 %}
6555
6571 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr) 6556 instruct loadConP31(rRegP dst, immP31 src, rFlagsReg cr)
6572 %{ 6557 %{
6573 match(Set dst src); 6558 match(Set dst src);
6574 effect(KILL cr); 6559 effect(KILL cr);
6575 6560
7239 %} 7224 %}
7240 7225
7241 instruct bytes_reverse_unsigned_short(rRegI dst) %{ 7226 instruct bytes_reverse_unsigned_short(rRegI dst) %{
7242 match(Set dst (ReverseBytesUS dst)); 7227 match(Set dst (ReverseBytesUS dst));
7243 7228
7244 format %{ "bswapl $dst\n\t" 7229 format %{ "bswapl $dst\n\t"
7245 "shrl $dst,16\n\t" %} 7230 "shrl $dst,16\n\t" %}
7246 ins_encode %{ 7231 ins_encode %{
7247 __ bswapl($dst$$Register); 7232 __ bswapl($dst$$Register);
7248 __ shrl($dst$$Register, 16); 7233 __ shrl($dst$$Register, 16);
7249 %} 7234 %}
7250 ins_pipe( ialu_reg ); 7235 ins_pipe( ialu_reg );
7251 %} 7236 %}
7252 7237
7253 instruct bytes_reverse_short(rRegI dst) %{ 7238 instruct bytes_reverse_short(rRegI dst) %{
7254 match(Set dst (ReverseBytesS dst)); 7239 match(Set dst (ReverseBytesS dst));
7255 7240
7256 format %{ "bswapl $dst\n\t" 7241 format %{ "bswapl $dst\n\t"
7257 "sar $dst,16\n\t" %} 7242 "sar $dst,16\n\t" %}
7258 ins_encode %{ 7243 ins_encode %{
7259 __ bswapl($dst$$Register); 7244 __ bswapl($dst$$Register);
7260 __ sarl($dst$$Register, 16); 7245 __ sarl($dst$$Register, 16);
7261 %} 7246 %}
7262 ins_pipe( ialu_reg ); 7247 ins_pipe( ialu_reg );
7263 %} 7248 %}
7264 7249
7265 //---------- Zeros Count Instructions ------------------------------------------ 7250 //---------- Zeros Count Instructions ------------------------------------------
7478 instruct membar_volatile(rFlagsReg cr) %{ 7463 instruct membar_volatile(rFlagsReg cr) %{
7479 match(MemBarVolatile); 7464 match(MemBarVolatile);
7480 effect(KILL cr); 7465 effect(KILL cr);
7481 ins_cost(400); 7466 ins_cost(400);
7482 7467
7483 format %{ 7468 format %{
7484 $$template 7469 $$template
7485 if (os::is_MP()) { 7470 if (os::is_MP()) {
7486 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile" 7471 $$emit$$"lock addl [rsp + #0], 0\t! membar_volatile"
7487 } else { 7472 } else {
7488 $$emit$$"MEMBAR-volatile ! (empty encoding)" 7473 $$emit$$"MEMBAR-volatile ! (empty encoding)"
8289 instruct storePConditional(memory heap_top_ptr, 8274 instruct storePConditional(memory heap_top_ptr,
8290 rax_RegP oldval, rRegP newval, 8275 rax_RegP oldval, rRegP newval,
8291 rFlagsReg cr) 8276 rFlagsReg cr)
8292 %{ 8277 %{
8293 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval))); 8278 match(Set cr (StorePConditional heap_top_ptr (Binary oldval newval)));
8294 8279
8295 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) " 8280 format %{ "cmpxchgq $heap_top_ptr, $newval\t# (ptr) "
8296 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %} 8281 "If rax == $heap_top_ptr then store $newval into $heap_top_ptr" %}
8297 opcode(0x0F, 0xB1); 8282 opcode(0x0F, 0xB1);
8298 ins_encode(lock_prefix, 8283 ins_encode(lock_prefix,
8299 REX_reg_mem_wide(newval, heap_top_ptr), 8284 REX_reg_mem_wide(newval, heap_top_ptr),
9852 ins_pipe(ialu_reg_reg); 9837 ins_pipe(ialu_reg_reg);
9853 %} 9838 %}
9854 9839
9855 // Xor Register with Immediate -1 9840 // Xor Register with Immediate -1
9856 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{ 9841 instruct xorI_rReg_im1(rRegI dst, immI_M1 imm) %{
9857 match(Set dst (XorI dst imm)); 9842 match(Set dst (XorI dst imm));
9858 9843
9859 format %{ "not $dst" %} 9844 format %{ "not $dst" %}
9860 ins_encode %{ 9845 ins_encode %{
9861 __ notl($dst$$Register); 9846 __ notl($dst$$Register);
9862 %} 9847 %}
9863 ins_pipe(ialu_reg); 9848 ins_pipe(ialu_reg);
9864 %} 9849 %}
10095 ins_pipe(ialu_reg_reg); 10080 ins_pipe(ialu_reg_reg);
10096 %} 10081 %}
10097 10082
10098 // Xor Register with Immediate -1 10083 // Xor Register with Immediate -1
10099 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{ 10084 instruct xorL_rReg_im1(rRegL dst, immL_M1 imm) %{
10100 match(Set dst (XorL dst imm)); 10085 match(Set dst (XorL dst imm));
10101 10086
10102 format %{ "notq $dst" %} 10087 format %{ "notq $dst" %}
10103 ins_encode %{ 10088 ins_encode %{
10104 __ notq($dst$$Register); 10089 __ notq($dst$$Register);
10105 %} 10090 %}
10106 ins_pipe(ialu_reg); 10091 ins_pipe(ialu_reg);
10107 %} 10092 %}
12471 12456
12472 // ============================================================================ 12457 // ============================================================================
12473 // Safepoint Instructions 12458 // Safepoint Instructions
12474 instruct safePoint_poll(rFlagsReg cr) 12459 instruct safePoint_poll(rFlagsReg cr)
12475 %{ 12460 %{
12461 predicate(!Assembler::is_polling_page_far());
12476 match(SafePoint); 12462 match(SafePoint);
12477 effect(KILL cr); 12463 effect(KILL cr);
12478 12464
12479 format %{ "testl rax, [rip + #offset_to_poll_page]\t" 12465 format %{ "testl rax, [rip + #offset_to_poll_page]\t"
12480 "# Safepoint: poll for GC" %} 12466 "# Safepoint: poll for GC" %}
12481 size(6); // Opcode + ModRM + Disp32 == 6 bytes
12482 ins_cost(125); 12467 ins_cost(125);
12483 ins_encode(enc_safepoint_poll); 12468 ins_encode %{
12469 AddressLiteral addr(os::get_polling_page(), relocInfo::poll_type);
12470 __ testl(rax, addr);
12471 %}
12472 ins_pipe(ialu_reg_mem);
12473 %}
12474
12475 instruct safePoint_poll_far(rFlagsReg cr, rRegP poll)
12476 %{
12477 predicate(Assembler::is_polling_page_far());
12478 match(SafePoint poll);
12479 effect(KILL cr, USE poll);
12480
12481 format %{ "testl rax, [$poll]\t"
12482 "# Safepoint: poll for GC" %}
12483 ins_cost(125);
12484 ins_encode %{
12485 __ relocate(relocInfo::poll_type);
12486 __ testl(rax, Address($poll$$Register, 0));
12487 %}
12484 ins_pipe(ialu_reg_mem); 12488 ins_pipe(ialu_reg_mem);
12485 %} 12489 %}
12486 12490
12487 // ============================================================================ 12491 // ============================================================================
12488 // Procedure Call/Return Instructions 12492 // Procedure Call/Return Instructions