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; }
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); }
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]); }
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; }