inline bool MacroAssembler::is_calculate_address_from_global_toc_at(address a, address bound) { const address inst2_addr = a; const int inst2 = *(int *) a; // The relocation points to the second instruction, the addi. if (!is_addi(inst2)) return false; // The addi reads and writes the same register dst. const int dst = inv_rt_field(inst2); if (inv_ra_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_addis(inst1) && inv_rt_field(inst1) == dst) { // stop, found the addis which writes dst break; } inst1_addr -= BytesPerInstWord; } if (!(inst1 == 0 || inv_ra_field(inst1) == 29 /* R29 */)) return false; return is_addis(inst1); }
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; }