static void render_memory_region(FlatView *view,

                                 MemoryRegion *mr,

                                 Int128 base,

                                 AddrRange clip,

                                 bool readonly)

{

    MemoryRegion *subregion;

    unsigned i;

    hwaddr offset_in_region;

    Int128 remain;

    Int128 now;

    FlatRange fr;

    AddrRange tmp;



    if (!mr->enabled) {

        return;

    }



    int128_addto(&base, int128_make64(mr->addr));

    readonly |= mr->readonly;



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



    if (!addrrange_intersects(tmp, clip)) {

        return;

    }



    clip = addrrange_intersection(tmp, clip);



    if (mr->alias) {

        int128_subfrom(&base, int128_make64(mr->alias->addr));

        int128_subfrom(&base, int128_make64(mr->alias_offset));

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

        return;

    }



    /* Render subregions in priority order. */

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

        render_memory_region(view, subregion, base, clip, readonly);

    }



    if (!mr->terminates) {

        return;

    }



    offset_in_region = int128_get64(int128_sub(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 && int128_nz(remain); ++i) {

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

            continue;

        }

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

            now = int128_min(remain,

                             int128_sub(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;

            fr.romd_mode = mr->romd_mode;

            fr.readonly = readonly;

            flatview_insert(view, i, &fr);

            ++i;

            int128_addto(&base, now);

            offset_in_region += int128_get64(now);

            int128_subfrom(&remain, now);

        }

        now = int128_sub(int128_min(int128_add(base, remain),

                                    addrrange_end(view->ranges[i].addr)),

                         base);

        int128_addto(&base, now);

        offset_in_region += int128_get64(now);

        int128_subfrom(&remain, now);

    }

    if (int128_nz(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;

        fr.romd_mode = mr->romd_mode;

        fr.readonly = readonly;

        flatview_insert(view, i, &fr);

    }

}

static void render_memory_region(FlatView *view,

                                 MemoryRegion *mr,

                                 Int128 base,

                                 AddrRange clip,

                                 bool readonly)

{

    MemoryRegion *subregion;

    unsigned i;

    hwaddr offset_in_region;

    Int128 remain;

    Int128 now;

    FlatRange fr;

    AddrRange tmp;



    if (!mr->enabled) {

        return;

    }



    int128_addto(&base, int128_make64(mr->addr));

    readonly |= mr->readonly;



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



    if (!addrrange_intersects(tmp, clip)) {

        return;

    }



    clip = addrrange_intersection(tmp, clip);



    if (mr->alias) {

        int128_subfrom(&base, int128_make64(mr->alias->addr));

        int128_subfrom(&base, int128_make64(mr->alias_offset));

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

        return;

    }



    

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

        render_memory_region(view, subregion, base, clip, readonly);

    }



    if (!mr->terminates) {

        return;

    }



    offset_in_region = int128_get64(int128_sub(clip.start, base));

    base = clip.start;

    remain = clip.size;



    

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

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

            continue;

        }

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

            now = int128_min(remain,

                             int128_sub(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;

            fr.romd_mode = mr->romd_mode;

            fr.readonly = readonly;

            flatview_insert(view, i, &fr);

            ++i;

            int128_addto(&base, now);

            offset_in_region += int128_get64(now);

            int128_subfrom(&remain, now);

        }

        now = int128_sub(int128_min(int128_add(base, remain),

                                    addrrange_end(view->ranges[i].addr)),

                         base);

        int128_addto(&base, now);

        offset_in_region += int128_get64(now);

        int128_subfrom(&remain, now);

    }

    if (int128_nz(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;

        fr.romd_mode = mr->romd_mode;

        fr.readonly = readonly;

        flatview_insert(view, i, &fr);

    }

}

static void FUNC_0(FlatView *VAR_0,

                                 MemoryRegion *VAR_1,

                                 Int128 VAR_2,

                                 AddrRange VAR_3,

                                 bool VAR_4)

{

    MemoryRegion *subregion;

    unsigned VAR_5;

    hwaddr offset_in_region;

    Int128 remain;

    Int128 now;

    FlatRange fr;

    AddrRange tmp;



    if (!VAR_1->enabled) {

        return;

    }



    int128_addto(&VAR_2, int128_make64(VAR_1->addr));

    VAR_4 |= VAR_1->VAR_4;



    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) {

        int128_subfrom(&VAR_2, int128_make64(VAR_1->alias->addr));

        int128_subfrom(&VAR_2, int128_make64(VAR_1->alias_offset));

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

        return;

    }



    

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

        FUNC_0(VAR_0, subregion, VAR_2, VAR_3, VAR_4);

    }



    if (!VAR_1->terminates) {

        return;

    }



    offset_in_region = int128_get64(int128_sub(VAR_3.start, VAR_2));

    VAR_2 = VAR_3.start;

    remain = VAR_3.size;



    

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

        if (int128_ge(VAR_2, addrrange_end(VAR_0->ranges[VAR_5].addr))) {

            continue;

        }

        if (int128_lt(VAR_2, VAR_0->ranges[VAR_5].addr.start)) {

            now = int128_min(remain,

                             int128_sub(VAR_0->ranges[VAR_5].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;

            fr.romd_mode = VAR_1->romd_mode;

            fr.VAR_4 = VAR_4;

            flatview_insert(VAR_0, VAR_5, &fr);

            ++VAR_5;

            int128_addto(&VAR_2, now);

            offset_in_region += int128_get64(now);

            int128_subfrom(&remain, now);

        }

        now = int128_sub(int128_min(int128_add(VAR_2, remain),

                                    addrrange_end(VAR_0->ranges[VAR_5].addr)),

                         VAR_2);

        int128_addto(&VAR_2, now);

        offset_in_region += int128_get64(now);

        int128_subfrom(&remain, now);

    }

    if (int128_nz(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;

        fr.romd_mode = VAR_1->romd_mode;

        fr.VAR_4 = VAR_4;

        flatview_insert(VAR_0, VAR_5, &fr);

    }

}

static void FUNC_0(FlatView *VAR_0,
MemoryRegion *VAR_1,
Int128 VAR_2,
AddrRange VAR_3,
bool VAR_4)
{ MemoryRegion *subregion; unsigned VAR_5; hwaddr offset_in_region; Int128 remain; Int128 now; FlatRange fr; AddrRange tmp; if (!VAR_1->enabled) { return; } int128_addto(&VAR_2, int128_make64(VAR_1->addr)); VAR_4 |= VAR_1->VAR_4; 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) { int128_subfrom(&VAR_2, int128_make64(VAR_1->alias->addr)); int128_subfrom(&VAR_2, int128_make64(VAR_1->alias_offset)); FUNC_0(VAR_0, VAR_1->alias, VAR_2, VAR_3, VAR_4); return; } QTAILQ_FOREACH(subregion, &VAR_1->subregions, subregions_link) { FUNC_0(VAR_0, subregion, VAR_2, VAR_3, VAR_4); } if (!VAR_1->terminates) { return; } offset_in_region = int128_get64(int128_sub(VAR_3.start, VAR_2)); VAR_2 = VAR_3.start; remain = VAR_3.size; for (VAR_5 = 0; VAR_5 < VAR_0->nr && int128_nz(remain); ++VAR_5) { if (int128_ge(VAR_2, addrrange_end(VAR_0->ranges[VAR_5].addr))) { continue; } if (int128_lt(VAR_2, VAR_0->ranges[VAR_5].addr.start)) { now = int128_min(remain,
int128_sub(VAR_0->ranges[VAR_5].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; fr.romd_mode = VAR_1->romd_mode; fr.VAR_4 = VAR_4; flatview_insert(VAR_0, VAR_5, &fr); ++VAR_5; int128_addto(&VAR_2, now); offset_in_region += int128_get64(now); int128_subfrom(&remain, now); } now = int128_sub(int128_min(int128_add(VAR_2, remain),
addrrange_end(VAR_0->ranges[VAR_5].addr)),
VAR_2); int128_addto(&VAR_2, now); offset_in_region += int128_get64(now); int128_subfrom(&remain, now); } if (int128_nz(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; fr.romd_mode = VAR_1->romd_mode; fr.VAR_4 = VAR_4; flatview_insert(VAR_0, VAR_5, &fr); } }