void emit_call_with_gp(Merced_Code_Emitter& emitter, void **proc_ptr, bool flushrs, int saved_gp_reg) { void *new_gp = proc_ptr[1]; void *vm_gp = get_vm_gp_value(); // Set the gp according to the IPF software conventions. if (new_gp != vm_gp) { if (saved_gp_reg != 0) emitter.ipf_mov(saved_gp_reg, GP_REG); emit_mov_imm_compactor(emitter, GP_REG, (uint64)new_gp); } uint64 branch_target = (uint64)(*proc_ptr); emit_mov_imm_compactor(emitter, SCRATCH_GENERAL_REG, branch_target, 0); if (flushrs) { emitter.ipf_mtbr(BRANCH_CALL_REG, SCRATCH_GENERAL_REG); emit_mov_imm_compactor(emitter, SCRATCH_GENERAL_REG, (uint64)m2n_gen_flush_and_call(), 0); } emitter.ipf_mtbr(SCRATCH_BRANCH_REG, SCRATCH_GENERAL_REG); emitter.ipf_bricall(br_few, br_sptk, br_none, BRANCH_RETURN_LINK_REG, SCRATCH_BRANCH_REG); // Restore the saved GP. if (new_gp != vm_gp && saved_gp_reg != 0) emitter.ipf_mov(GP_REG, saved_gp_reg); } //emit_call_with_gp
void emit_dealloc_for_single_call(Merced_Code_Emitter& emitter, int save_pfs_reg, int save_b0_reg, int save_gp_reg, int pred) { if (save_gp_reg != 0) emitter.ipf_mov(GP_REG, save_gp_reg, pred); emitter.ipf_mtap(AR_pfs, save_pfs_reg, pred); emitter.ipf_mtbr(BRANCH_RETURN_LINK_REG, save_b0_reg, pred); }
void emit_branch_with_gp(Merced_Code_Emitter& emitter, void **proc_ptr) { void *new_gp = proc_ptr[1]; void *vm_gp = get_vm_gp_value(); // Set the gp according to the IPF software conventions. if (new_gp != vm_gp) { emit_mov_imm_compactor(emitter, GP_REG, (uint64)new_gp); } uint64 branch_target = (uint64)(*proc_ptr); emit_mov_imm_compactor(emitter, SCRATCH_GENERAL_REG, branch_target, 0); emitter.ipf_mtbr(SCRATCH_BRANCH_REG, SCRATCH_GENERAL_REG); emitter.ipf_bri(br_cond, br_few, br_sptk, br_none, SCRATCH_BRANCH_REG); // someone else will restore the gp, according to the software conventions } //emit_branch_with_gp