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