Exemplo n.º 1
2
/*
 *   Allocates a data or addressing register (whichever is free).
 *   Otherwise allocates the first register which matches flags.
 */
ADDRESS *temp_reg P1 (FLAGS, flags)
{
    if (is_free_data () && (flags & F_DREG)) {
        return data_register ();
    }
    if (is_free_addr () && (flags & F_AREG)) {
        return address_register ();
    }
    if (flags & F_DREG) {
        return data_register ();
    }
    if (flags & F_AREG) {
        return address_register ();
    }
#ifdef FLOAT_IEEE
    if (flags & F_FREG) {
        return float_register ();
    }
#endif /* FLOAT_IEEE */
    return NIL_ADDRESS;
}
Exemplo n.º 2
0
Assembler::Address2 MemoryAddress::address_2_for(jint address_offset) {
  if (!has_address_register()) {
    // Try to do direct access
    jint fixed_offset;
    if (has_fixed_offset(fixed_offset)) {
      jint offset = fixed_offset + base_offset() + address_offset;
      if (-(1 << 12) < offset && offset < (1 << 12)) {
        return Assembler::imm_index(fixed_register(), offset);
      }
    }
    create_and_initialize_address_register();
  }
  GUARANTEE(has_address_register(), "We must have address register by now");
  int xbase_offset =            // base_offset or 0
      address_register_includes_base_offset() ? 0 : base_offset();
  if (address_offset == 0 && xbase_offset != 0) {
      // Update the address_register so that it includes the base_offset
      set_address_register_includes_base_offset();
      return Assembler::imm_index(address_register(), xbase_offset,
                                  Assembler::pre_indexed);
  } else {
      return Assembler::imm_index(address_register(),
                                  address_offset + xbase_offset);
  }
}
Exemplo n.º 3
0
void MemoryAddress::prepare_preindexed_address(jint address_offset,
                                               Assembler::Register& reg,
                                               jint& offset){
  offset = 0;

  if (!has_address_register()) {
    // Try to do direct access
    jint fixed_offset;
    if (has_fixed_offset(fixed_offset)) {
      offset = fixed_offset + base_offset() + address_offset;
      reg = fixed_register();
      return;
    }
    create_and_initialize_address_register();
  }

  GUARANTEE(has_address_register(), "We must have address register by now");

  reg = address_register();

  int xbase_offset =            // base_offset or 0
    address_register_includes_base_offset() ? 0 : base_offset();
  if (address_offset == 0 && xbase_offset != 0) {
    // Update the address_register so that it includes the base_offset
    set_address_register_includes_base_offset();
    code_generator()->add(address_register(), address_register(), xbase_offset);
    offset = 0;
  } else {
    offset = (address_offset + xbase_offset);
  }
}
Exemplo n.º 4
0
void HeapAddress::write_barrier_epilog() {
  GUARANTEE(stack_type() == T_OBJECT, "write barrier should not be updated for non-object stores");
  GUARANTEE(has_address_register(),   "cannot update write barrier without proper register");

  // update the bit vector
  code_generator()->shrl(address_register(), LogBytesPerWord);
  code_generator()->bts(BinaryAssembler::Address((int) _bitvector_base), address_register());

  // dereference the allocated register and clear the cache
  RegisterAllocator::dereference(address_register());
  clear_address_register();
}
Exemplo n.º 5
0
void IndexedAddress::fill_in_address_register() {
  if (index()->is_immediate()) {
    MemoryAddress::fill_in_address_register();
  } else {
    if (index_shift() != 0) {
      code_generator()->lsl_imm5(address_register(), index()->lo_register(),
                                 index_shift());
      code_generator()->add(address_register(), fixed_register(),
                                 address_register());
    } else {
      code_generator()->add(address_register(), fixed_register(),
                                 index()->lo_register());
    }
  }
}
Exemplo n.º 6
0
void MemoryAddress::fill_in_address_register() {
  // In all cases exception for variable arrays indices, we are looking at
  // at fixed offset into the object.
  jint fixed_offset;
  if (has_fixed_offset(fixed_offset)) {
    code_generator()->mov(address_register(), fixed_offset + base_offset());
    code_generator()->add(address_register(), fixed_register(),
                          address_register());
    set_address_register_includes_base_offset();
  } else {
    // This is a virtual method, and in this case, we better be calling
    // an overriding definition.
    SHOULD_NOT_REACH_HERE();
  }
}
Exemplo n.º 7
0
void HeapAddress::write_barrier_epilog() {
  GUARANTEE(has_address_register(),
            "write barrier must have an address register");

  GUARANTEE(base_offset() == 0 || address_register_includes_base_offset() ,
            "write_barrier_epilog() must follow address_2_for(0)");

  // This is almost always the last thing we do with an address, so it
  // is okay to steal its temporary register.  This saves us one or two
  // instructions in many cases.
  Assembler::Register dst = address_register();
  clear_address_register();
#if ENABLE_ARM_V7
  if (UseHandlers) {
    if (RegisterAllocator::references(dst) > 1) {
      Assembler::Register tmp = RegisterAllocator::allocate();
      code_generator()->mov(tmp, dst);
      code_generator()->hbl(CodeGenerator::write_barrier_handler_r0 + (int)tmp);
      RegisterAllocator::dereference(tmp);
    } else {
      code_generator()->hbl(CodeGenerator::write_barrier_handler_r0 + (int)dst);
    }
  } else
#endif
  {
    Assembler::Register tmp1 = RegisterAllocator::allocate();
    Assembler::Register tmp2 = RegisterAllocator::allocate();
    Assembler::Register tmp3 = Assembler::r12;
    code_generator()->oop_write_barrier(dst, tmp1, tmp2, tmp3, false);
    RegisterAllocator::dereference(tmp1);
    RegisterAllocator::dereference(tmp2);
  }
  RegisterAllocator::dereference(dst);
}
Exemplo n.º 8
0
void HeapAddress::write_barrier_epilog() {
  GUARANTEE(has_address_register(),
            "write barrier must have an address register");

  // allocate the necessary temporary registers
  Assembler::Register tmp0;

  GUARANTEE(base_offset() == 0 || address_register_includes_base_offset(),
            "write_barrier_epilog() must follow address_2_for(0)");

  // This is almost always the last thing we do with an address, so it
  // is okay to steal its temporary register.  This saves us one or two
  // instructions in many cases.
  tmp0 = address_register();
  clear_address_register();

  Assembler::Register tmp1 = RegisterAllocator::allocate();
  Assembler::Register tmp2 = RegisterAllocator::allocate();
  Assembler::Register tmp3 = RegisterAllocator::allocate();

  // update the write barrier
  code_generator()->oop_write_barrier(tmp0, tmp1, tmp2, tmp3, false);

  // dereference the allocated registers
  RegisterAllocator::dereference(tmp0);
  RegisterAllocator::dereference(tmp1);
  RegisterAllocator::dereference(tmp2);
  RegisterAllocator::dereference(tmp3);
}
Exemplo n.º 9
0
BinaryAssembler::Address HeapAddress::address_for(jint address_offset) {
  // use the address register if available
  if (has_address_register()) {
    GUARANTEE(address_offset == lo_offset(), "the address register holds the address for the low offset");
    return BinaryAssembler::Address(address_register());
  }

  // return the computed address
  return compute_address_for(address_offset);
}
Exemplo n.º 10
0
void HeapAddress::write_barrier_prolog() {
  GUARANTEE(stack_type() == T_OBJECT, "write barrier should not be updated for non-object stores");

  // allocate an address register for the write barrier implementation
  set_address_register(RegisterAllocator::allocate());

  // compute the effective address and store it in the address register
  BinaryAssembler::Address address = compute_address_for(lo_offset());
  code_generator()->leal(address_register(), address);
}
Exemplo n.º 11
0
void IndexedAddress::fill_in_address_register() {
  if (index()->is_immediate()) { 
    MemoryAddress::fill_in_address_register();
  } else { 
    code_generator()->add(address_register(), 
                          fixed_register(),
                          Assembler::imm_shift(index()->lo_register(),
                                               Assembler::lsl, index_shift()));
  }
}
Exemplo n.º 12
0
Assembler::Address5 MemoryAddress::address_5_for(jint address_offset) {
  if (!has_address_register()) {
    // Try to do direct access
    jint fixed_offset;
    if (has_fixed_offset(fixed_offset)) {
      const jint offset = fixed_offset + base_offset() + address_offset;
      if (-(1 << 10) < offset && offset < (1 << 10)) {
        return Assembler::imm_index5(fixed_register(), offset);
      }
    }
    create_and_initialize_address_register();
  }
  GUARANTEE(has_address_register(), "We must have address register by now");
  const int xbase_offset =            // base_offset or 0
    address_register_includes_base_offset() ? 0 : base_offset();
  return Assembler::imm_index5(address_register(),
                               address_offset + xbase_offset);
}
Exemplo n.º 13
0
Assembler::Address3 MemoryAddress::address_3_for(jint address_offset) {
  if (!has_address_register()) {
    jint fixed_offset;
    if (has_fixed_offset(fixed_offset)) {
      jint offset = fixed_offset + base_offset() + address_offset;
      if (-(1 << 8) < offset && offset < (1 << 8)) {
        return Assembler::imm_index3(fixed_register(), offset);
      }
    }
    // We have to allocate an address register and fill it in
    create_and_initialize_address_register();
  }
  GUARANTEE(has_address_register(), "We must have address register by now");

  if (!address_register_includes_base_offset()) {
    address_offset += base_offset();
  }
  // Unlike Address2, we have nothing to gain by using pre_indexed mode.
  // This is not used for modifying objects, longs, or doubles.
  return Assembler::imm_index3(address_register(), address_offset);
}
Exemplo n.º 14
0
void MemoryAddress::prepare_indexed_address(jint address_offset,
                                            Assembler::Register& reg,
                                            jint& offset){
  if (!has_address_register()) {
    jint fixed_offset;
    if (has_fixed_offset(fixed_offset)) {
      offset = fixed_offset + base_offset() + address_offset;
      reg = fixed_register();
      return;
    }
    // We have to allocate an address register and fill it in
    create_and_initialize_address_register();
  }
  GUARANTEE(has_address_register(), "We must have address register by now");

  offset = address_offset;

  if (!address_register_includes_base_offset()) {
    offset += base_offset();
  }

  reg = address_register();
  return;
}
Exemplo n.º 15
0
MemoryAddress::~MemoryAddress() {
  // dereference any allocated address registers
  if (has_address_register()) {
      RegisterAllocator::dereference(address_register());
  }
}