inline bool MacroAssembler::is_load_const_at(address a) {
  const int* p_inst = (int *) a;
  bool b = is_lis(*p_inst++);
  if (is_ori(*p_inst)) {
    p_inst++;
    b = b && is_rldicr(*p_inst++); // TODO: could be made more precise: `sldi'!
    b = b && is_oris(*p_inst++);
    b = b && is_ori(*p_inst);
  } else if (is_lis(*p_inst)) {
    p_inst++;
    b = b && is_ori(*p_inst++);
    b = b && is_ori(*p_inst);
    // TODO: could enhance reliability by adding is_insrdi
  } else return false;
  return b;
}
Пример #2
0
int32 immediate_pair_target(inst_t* instp) {
  // find out if instp points to lis followed by ori/addi/load/store
  inst_t i2 = instp[1];
  return   is_ori(i2)
             ?    SI(instp[0]) << si_bits  |  UI(i2)
             :    SI(instp[0]) << si_bits  +  SI(i2);
}
Пример #3
0
void set_immediate_pair_target(inst_t *instp, int32 nv) {
  int32 lo, hi;
  inst_t i0 = instp[0];
  inst_t i1 = instp[1];
  if ( is_ori(i1) )   Assembler::break_up_word_for_oring (nv, lo, hi);
  else                Assembler::break_up_word_for_adding(nv, lo, hi);
  instp[0] = i0 & ~si_mask  |  hi;
  instp[1] = i1 & ~si_mask  |  lo;  assert(si_mask == ui_mask, "");
  MachineCache::flush_instruction_cache_range(&instp[0], &instp[2]);
}
Пример #4
0
bool is_immediate_pair(inst_t* instp) {
  // find out if instp points to lis followed by ori/addi/load/store
  inst_t i1 = instp[0];
  if (!is_lis(i1)) return false;
  fint reg = RT(i1);
  inst_t i2 = instp[1];
  return
       is_ori(i2)                    &&  RA(i2) == reg  &&  RS(i2) == reg 
  ||   is_addi(i2)                   &&  RT(i2) == reg  &&  RS(i2) == reg
  ||   is_load_store_immediate(i2)   &&  RA(i2) == reg;
}
// Detect narrow oop constants.
inline bool MacroAssembler::is_set_narrow_oop(address a, address bound) {
  const address inst2_addr = a;
  const int inst2 = *(int *)a;
  // The relocation points to the second instruction, the ori.
  if (!is_ori(inst2)) return false;

  // The ori reads and writes the same register dst.
  const int dst = inv_rta_field(inst2);
  if (inv_rs_field(inst2) != dst) return false;

  // Now, find the preceding addis which writes to dst.
  int inst1 = 0;
  address inst1_addr = inst2_addr - BytesPerInstWord;
  while (inst1_addr >= bound) {
    inst1 = *(int *) inst1_addr;
    if (is_lis(inst1) && inv_rs_field(inst1) == dst) return true;
    inst1_addr -= BytesPerInstWord;
  }
  return false;
}