static void render_memory_region(FlatView *view,

                                 MemoryRegion *mr,

                                 target_phys_addr_t base,

                                 AddrRange clip)

{

    MemoryRegion *subregion;

    unsigned i;

    target_phys_addr_t offset_in_region;

    uint64_t remain;

    uint64_t now;

    FlatRange fr;

    AddrRange tmp;



    base += mr->addr;



    tmp = addrrange_make(base, mr->size);



    if (!addrrange_intersects(tmp, clip)) {

        return;

    }



    clip = addrrange_intersection(tmp, clip);



    if (mr->alias) {

        base -= mr->alias->addr;

        base -= mr->alias_offset;

        render_memory_region(view, mr->alias, base, clip);

        return;

    }



    /* Render subregions in priority order. */

    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {

        render_memory_region(view, subregion, base, clip);

    }



    if (!mr->terminates) {

        return;

    }



    offset_in_region = clip.start - base;

    base = clip.start;

    remain = clip.size;



    /* Render the region itself into any gaps left by the current view. */

    for (i = 0; i < view->nr && remain; ++i) {

        if (base >= addrrange_end(view->ranges[i].addr)) {

            continue;

        }

        if (base < view->ranges[i].addr.start) {

            now = MIN(remain, view->ranges[i].addr.start - base);

            fr.mr = mr;

            fr.offset_in_region = offset_in_region;

            fr.addr = addrrange_make(base, now);

            fr.dirty_log_mask = mr->dirty_log_mask;

            flatview_insert(view, i, &fr);

            ++i;

            base += now;

            offset_in_region += now;

            remain -= now;

        }

        if (base == view->ranges[i].addr.start) {

            now = MIN(remain, view->ranges[i].addr.size);

            base += now;

            offset_in_region += now;

            remain -= now;

        }

    }

    if (remain) {

        fr.mr = mr;

        fr.offset_in_region = offset_in_region;

        fr.addr = addrrange_make(base, remain);

        fr.dirty_log_mask = mr->dirty_log_mask;

        flatview_insert(view, i, &fr);

    }

}

static void render_memory_region(FlatView *view,

                                 MemoryRegion *mr,

                                 target_phys_addr_t base,

                                 AddrRange clip)

{

    MemoryRegion *subregion;

    unsigned i;

    target_phys_addr_t offset_in_region;

    uint64_t remain;

    uint64_t now;

    FlatRange fr;

    AddrRange tmp;



    base += mr->addr;



    tmp = addrrange_make(base, mr->size);



    if (!addrrange_intersects(tmp, clip)) {

        return;

    }



    clip = addrrange_intersection(tmp, clip);



    if (mr->alias) {

        base -= mr->alias->addr;

        base -= mr->alias_offset;

        render_memory_region(view, mr->alias, base, clip);

        return;

    }



    

    QTAILQ_FOREACH(subregion, &mr->subregions, subregions_link) {

        render_memory_region(view, subregion, base, clip);

    }



    if (!mr->terminates) {

        return;

    }



    offset_in_region = clip.start - base;

    base = clip.start;

    remain = clip.size;



    

    for (i = 0; i < view->nr && remain; ++i) {

        if (base >= addrrange_end(view->ranges[i].addr)) {

            continue;

        }

        if (base < view->ranges[i].addr.start) {

            now = MIN(remain, view->ranges[i].addr.start - base);

            fr.mr = mr;

            fr.offset_in_region = offset_in_region;

            fr.addr = addrrange_make(base, now);

            fr.dirty_log_mask = mr->dirty_log_mask;

            flatview_insert(view, i, &fr);

            ++i;

            base += now;

            offset_in_region += now;

            remain -= now;

        }

        if (base == view->ranges[i].addr.start) {

            now = MIN(remain, view->ranges[i].addr.size);

            base += now;

            offset_in_region += now;

            remain -= now;

        }

    }

    if (remain) {

        fr.mr = mr;

        fr.offset_in_region = offset_in_region;

        fr.addr = addrrange_make(base, remain);

        fr.dirty_log_mask = mr->dirty_log_mask;

        flatview_insert(view, i, &fr);

    }

}

    uint64_t remain;     uint64_t now;
static void FUNC_0(FlatView *VAR_0,

                                 MemoryRegion *VAR_1,

                                 target_phys_addr_t VAR_2,

                                 AddrRange VAR_3)

{

    MemoryRegion *subregion;

    unsigned VAR_4;

    target_phys_addr_t offset_in_region;

    uint64_t remain;

    uint64_t now;

    FlatRange fr;

    AddrRange tmp;



    VAR_2 += VAR_1->addr;



    tmp = addrrange_make(VAR_2, VAR_1->size);



    if (!addrrange_intersects(tmp, VAR_3)) {

        return;

    }



    VAR_3 = addrrange_intersection(tmp, VAR_3);



    if (VAR_1->alias) {

        VAR_2 -= VAR_1->alias->addr;

        VAR_2 -= VAR_1->alias_offset;

        FUNC_0(VAR_0, VAR_1->alias, VAR_2, VAR_3);

        return;

    }



    

    QTAILQ_FOREACH(subregion, &VAR_1->subregions, subregions_link) {

        FUNC_0(VAR_0, subregion, VAR_2, VAR_3);

    }



    if (!VAR_1->terminates) {

        return;

    }



    offset_in_region = VAR_3.start - VAR_2;

    VAR_2 = VAR_3.start;

    remain = VAR_3.size;



    

    for (VAR_4 = 0; VAR_4 < VAR_0->nr && remain; ++VAR_4) {

        if (VAR_2 >= addrrange_end(VAR_0->ranges[VAR_4].addr)) {

            continue;

        }

        if (VAR_2 < VAR_0->ranges[VAR_4].addr.start) {

            now = MIN(remain, VAR_0->ranges[VAR_4].addr.start - VAR_2);

            fr.VAR_1 = VAR_1;

            fr.offset_in_region = offset_in_region;

            fr.addr = addrrange_make(VAR_2, now);

            fr.dirty_log_mask = VAR_1->dirty_log_mask;

            flatview_insert(VAR_0, VAR_4, &fr);

            ++VAR_4;

            VAR_2 += now;

            offset_in_region += now;

            remain -= now;

        }

        if (VAR_2 == VAR_0->ranges[VAR_4].addr.start) {

            now = MIN(remain, VAR_0->ranges[VAR_4].addr.size);

            VAR_2 += now;

            offset_in_region += now;

            remain -= now;

        }

    }

    if (remain) {

        fr.VAR_1 = VAR_1;

        fr.offset_in_region = offset_in_region;

        fr.addr = addrrange_make(VAR_2, remain);

        fr.dirty_log_mask = VAR_1->dirty_log_mask;

        flatview_insert(VAR_0, VAR_4, &fr);

    }

}

static void FUNC_0(FlatView *VAR_0,
MemoryRegion *VAR_1,
target_phys_addr_t VAR_2,
AddrRange VAR_3)
{ MemoryRegion *subregion; unsigned VAR_4; target_phys_addr_t offset_in_region; uint64_t remain; uint64_t now; FlatRange fr; AddrRange tmp; VAR_2 += VAR_1->addr; tmp = addrrange_make(VAR_2, VAR_1->size); if (!addrrange_intersects(tmp, VAR_3)) { return; } VAR_3 = addrrange_intersection(tmp, VAR_3); if (VAR_1->alias) { VAR_2 -= VAR_1->alias->addr; VAR_2 -= VAR_1->alias_offset; FUNC_0(VAR_0, VAR_1->alias, VAR_2, VAR_3); return; } QTAILQ_FOREACH(subregion, &VAR_1->subregions, subregions_link) { FUNC_0(VAR_0, subregion, VAR_2, VAR_3); } if (!VAR_1->terminates) { return; } offset_in_region = VAR_3.start - VAR_2; VAR_2 = VAR_3.start; remain = VAR_3.size; for (VAR_4 = 0; VAR_4 < VAR_0->nr && remain; ++VAR_4) { if (VAR_2 >= addrrange_end(VAR_0->ranges[VAR_4].addr)) { continue; } if (VAR_2 < VAR_0->ranges[VAR_4].addr.start) { now = MIN(remain, VAR_0->ranges[VAR_4].addr.start - VAR_2); fr.VAR_1 = VAR_1; fr.offset_in_region = offset_in_region; fr.addr = addrrange_make(VAR_2, now); fr.dirty_log_mask = VAR_1->dirty_log_mask; flatview_insert(VAR_0, VAR_4, &fr); ++VAR_4; VAR_2 += now; offset_in_region += now; remain -= now; } if (VAR_2 == VAR_0->ranges[VAR_4].addr.start) { now = MIN(remain, VAR_0->ranges[VAR_4].addr.size); VAR_2 += now; offset_in_region += now; remain -= now; } } if (remain) { fr.VAR_1 = VAR_1; fr.offset_in_region = offset_in_region; fr.addr = addrrange_make(VAR_2, remain); fr.dirty_log_mask = VAR_1->dirty_log_mask; flatview_insert(VAR_0, VAR_4, &fr); } }