void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
    assert_different_registers(Rmark, Roop, Rbox);

    Label done;

    Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
    assert(mark_addr.disp() == 0, "cas must take a zero displacement");

    if (UseBiasedLocking) {
        // load the object out of the BasicObjectLock
        ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
        verify_oop(Roop);
        biased_locking_exit(mark_addr, Rmark, done);
    }
    // Test first it it is a fast recursive unlock
    ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark);
    br_null_short(Rmark, Assembler::pt, done);
    if (!UseBiasedLocking) {
        // load object
        ld_ptr(Rbox, BasicObjectLock::obj_offset_in_bytes(), Roop);
        verify_oop(Roop);
    }

    // Check if it is still a light weight lock, this is is true if we see
    // the stack address of the basicLock in the markOop of the object
    cas_ptr(mark_addr.base(), Rbox, Rmark);
    cmp(Rbox, Rmark);

    brx(Assembler::notEqual, false, Assembler::pn, slow_case);
    delayed()->nop();
    // Done
    bind(done);
}
void C1_MacroAssembler::lock_object(Register Rmark, Register Roop, Register Rbox, Register Rscratch, Label& slow_case) {
    assert_different_registers(Rmark, Roop, Rbox, Rscratch);

    Label done;

    Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());

    // The following move must be the first instruction of emitted since debug
    // information may be generated for it.
    // Load object header
    ld_ptr(mark_addr, Rmark);

    verify_oop(Roop);

    // save object being locked into the BasicObjectLock
    st_ptr(Roop, Rbox, BasicObjectLock::obj_offset_in_bytes());

    if (UseBiasedLocking) {
        biased_locking_enter(Roop, Rmark, Rscratch, done, &slow_case);
    }

    // Save Rbox in Rscratch to be used for the cas operation
    mov(Rbox, Rscratch);

    // and mark it unlocked
    or3(Rmark, markOopDesc::unlocked_value, Rmark);

    // save unlocked object header into the displaced header location on the stack
    st_ptr(Rmark, Rbox, BasicLock::displaced_header_offset_in_bytes());

    // compare object markOop with Rmark and if equal exchange Rscratch with object markOop
    assert(mark_addr.disp() == 0, "cas must take a zero displacement");
    cas_ptr(mark_addr.base(), Rmark, Rscratch);
    // if compare/exchange succeeded we found an unlocked object and we now have locked it
    // hence we are done
    cmp(Rmark, Rscratch);
    brx(Assembler::equal, false, Assembler::pt, done);
    delayed()->sub(Rscratch, SP, Rscratch);  //pull next instruction into delay slot
    // we did not find an unlocked object so see if this is a recursive case
    // sub(Rscratch, SP, Rscratch);
    assert(os::vm_page_size() > 0xfff, "page size too small - change the constant");
    andcc(Rscratch, 0xfffff003, Rscratch);
    brx(Assembler::notZero, false, Assembler::pn, slow_case);
    delayed()->st_ptr(Rscratch, Rbox, BasicLock::displaced_header_offset_in_bytes());
    bind(done);
}
void C1_MacroAssembler::unlock_object(Register Rmark, Register Roop, Register Rbox, Label& slow_case) {
  assert_different_registers(Rmark, Roop, Rbox);

  Label slow_int, done;

  Address mark_addr(Roop, oopDesc::mark_offset_in_bytes());
  assert(mark_addr.disp() == 0, "cas must take a zero displacement");

  if (UseBiasedLocking) {
    // Load the object out of the BasicObjectLock.
    ld(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);
    verify_oop(Roop);
    biased_locking_exit(CCR0, Roop, R0, done);
  }
  // Test first it it is a fast recursive unlock.
  ld(Rmark, BasicLock::displaced_header_offset_in_bytes(), Rbox);
  cmpdi(CCR0, Rmark, 0);
  beq(CCR0, done);
  if (!UseBiasedLocking) {
    // Load object.
    ld(Roop, BasicObjectLock::obj_offset_in_bytes(), Rbox);
    verify_oop(Roop);
  }

  // Check if it is still a light weight lock, this is is true if we see
  // the stack address of the basicLock in the markOop of the object.
  cmpxchgd(/*flag=*/CCR0,
           /*current_value=*/R0,
           /*compare_value=*/Rbox,
           /*exchange_value=*/Rmark,
           /*where=*/Roop,
           MacroAssembler::MemBarRel,
           MacroAssembler::cmpxchgx_hint_release_lock(),
           noreg,
           &slow_int);
  b(done);
  bind(slow_int);
  b(slow_case); // far

  // Done
  bind(done);
}