716 Unimplemented(); |
716 Unimplemented(); |
717 } |
717 } |
718 } |
718 } |
719 |
719 |
720 |
720 |
721 void LIRGenerator::do_AttemptUpdate(Intrinsic* x) { |
|
722 assert(x->number_of_arguments() == 3, "wrong type"); |
|
723 LIRItem obj (x->argument_at(0), this); // AtomicLong object |
|
724 LIRItem cmp_value (x->argument_at(1), this); // value to compare with field |
|
725 LIRItem new_value (x->argument_at(2), this); // replace field with new_value if it matches cmp_value |
|
726 |
|
727 // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction |
|
728 cmp_value.load_item_force(FrameMap::long0_opr); |
|
729 |
|
730 // new value must be in rcx,ebx (hi,lo) |
|
731 new_value.load_item_force(FrameMap::long1_opr); |
|
732 |
|
733 // object pointer register is overwritten with field address |
|
734 obj.load_item(); |
|
735 |
|
736 // generate compare-and-swap; produces zero condition if swap occurs |
|
737 int value_offset = sun_misc_AtomicLongCSImpl::value_offset(); |
|
738 LIR_Opr addr = new_pointer_register(); |
|
739 __ leal(LIR_OprFact::address(new LIR_Address(obj.result(), value_offset, T_LONG)), addr); |
|
740 LIR_Opr t1 = LIR_OprFact::illegalOpr; // no temp needed |
|
741 LIR_Opr t2 = LIR_OprFact::illegalOpr; // no temp needed |
|
742 __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2); |
|
743 |
|
744 // generate conditional move of boolean result |
|
745 LIR_Opr result = rlock_result(x); |
|
746 __ cmove(lir_cond_equal, LIR_OprFact::intConst(1), LIR_OprFact::intConst(0), result, T_LONG); |
|
747 } |
|
748 |
|
749 |
|
750 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { |
721 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) { |
751 assert(x->number_of_arguments() == 4, "wrong type"); |
722 assert(x->number_of_arguments() == 4, "wrong type"); |
752 LIRItem obj (x->argument_at(0), this); // object |
723 LIRItem obj (x->argument_at(0), this); // object |
753 LIRItem offset(x->argument_at(1), this); // offset of field |
724 LIRItem offset(x->argument_at(1), this); // offset of field |
754 LIRItem cmp (x->argument_at(2), this); // value to compare with field |
725 LIRItem cmp (x->argument_at(2), this); // value to compare with field |