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