static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr,

                                uint64_t asc, uint64_t entry, int level,

                                target_ulong *raddr, int *flags, int rw,

                                bool exc)

{

    CPUState *cs = CPU(s390_env_get_cpu(env));

    uint64_t origin, offs, new_entry;

    const int pchks[4] = {

        PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS,

        PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS

    };



    PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, entry);



    origin = entry & _REGION_ENTRY_ORIGIN;

    offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8;



    new_entry = ldq_phys(cs->as, origin + offs);

    PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",

                __func__, origin, offs, new_entry);



    if ((new_entry & _REGION_ENTRY_INV) != 0) {

        /* XXX different regions have different faults */

        DPRINTF("%s: invalid region\n", __func__);

        trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw, exc);

        return -1;

    }



    if ((new_entry & _REGION_ENTRY_TYPE_MASK) != level) {

        trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc);

        return -1;

    }



    /* XXX region protection flags */

    /* *flags &= ~PAGE_WRITE */



    if (level == _ASCE_TYPE_SEGMENT) {

        return mmu_translate_segment(env, vaddr, asc, new_entry, raddr, flags,

                                     rw, exc);

    }



    /* Check region table offset and length */

    offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3;

    if (offs < ((new_entry & _REGION_ENTRY_TF) >> 6)

        || offs > (new_entry & _REGION_ENTRY_LENGTH)) {

        DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry);

        trigger_page_fault(env, vaddr, pchks[level / 4 - 1], asc, rw, exc);

        return -1;

    }



    /* yet another region */

    return mmu_translate_region(env, vaddr, asc, new_entry, level - 4,

                                raddr, flags, rw, exc);

}

static int mmu_translate_region(CPUS390XState *env, target_ulong vaddr,

                                uint64_t asc, uint64_t entry, int level,

                                target_ulong *raddr, int *flags, int rw,

                                bool exc)

{

    CPUState *cs = CPU(s390_env_get_cpu(env));

    uint64_t origin, offs, new_entry;

    const int pchks[4] = {

        PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS,

        PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS

    };



    PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, entry);



    origin = entry & _REGION_ENTRY_ORIGIN;

    offs = (vaddr >> (17 + 11 * level / 4)) & 0x3ff8;



    new_entry = ldq_phys(cs->as, origin + offs);

    PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",

                __func__, origin, offs, new_entry);



    if ((new_entry & _REGION_ENTRY_INV) != 0) {

        

        DPRINTF("%s: invalid region\n", __func__);

        trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw, exc);

        return -1;

    }



    if ((new_entry & _REGION_ENTRY_TYPE_MASK) != level) {

        trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw, exc);

        return -1;

    }



    

    



    if (level == _ASCE_TYPE_SEGMENT) {

        return mmu_translate_segment(env, vaddr, asc, new_entry, raddr, flags,

                                     rw, exc);

    }



    

    offs = (vaddr >> (28 + 11 * (level - 4) / 4)) & 3;

    if (offs < ((new_entry & _REGION_ENTRY_TF) >> 6)

        || offs > (new_entry & _REGION_ENTRY_LENGTH)) {

        DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry);

        trigger_page_fault(env, vaddr, pchks[level / 4 - 1], asc, rw, exc);

        return -1;

    }



    

    return mmu_translate_region(env, vaddr, asc, new_entry, level - 4,

                                raddr, flags, rw, exc);

}

        trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw, exc);
static int FUNC_0(CPUS390XState *VAR_0, target_ulong VAR_1,

                                uint64_t VAR_2, uint64_t VAR_3, int VAR_4,

                                target_ulong *VAR_5, int *VAR_6, int VAR_7,

                                bool VAR_8)

{

    CPUState *cs = CPU(s390_env_get_cpu(VAR_0));

    uint64_t origin, offs, new_entry;

    const int VAR_9[4] = {

        PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS,

        PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS

    };



    PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, VAR_3);



    origin = VAR_3 & _REGION_ENTRY_ORIGIN;

    offs = (VAR_1 >> (17 + 11 * VAR_4 / 4)) & 0x3ff8;



    new_entry = ldq_phys(cs->as, origin + offs);

    PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",

                __func__, origin, offs, new_entry);



    if ((new_entry & _REGION_ENTRY_INV) != 0) {

        

        DPRINTF("%s: invalid region\n", __func__);

        trigger_page_fault(VAR_0, VAR_1, PGM_SEGMENT_TRANS, VAR_2, VAR_7, VAR_8);

        return -1;

    }



    if ((new_entry & _REGION_ENTRY_TYPE_MASK) != VAR_4) {

        trigger_page_fault(VAR_0, VAR_1, PGM_TRANS_SPEC, VAR_2, VAR_7, VAR_8);

        return -1;

    }



    

    



    if (VAR_4 == _ASCE_TYPE_SEGMENT) {

        return mmu_translate_segment(VAR_0, VAR_1, VAR_2, new_entry, VAR_5, VAR_6,

                                     VAR_7, VAR_8);

    }



    

    offs = (VAR_1 >> (28 + 11 * (VAR_4 - 4) / 4)) & 3;

    if (offs < ((new_entry & _REGION_ENTRY_TF) >> 6)

        || offs > (new_entry & _REGION_ENTRY_LENGTH)) {

        DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry);

        trigger_page_fault(VAR_0, VAR_1, VAR_9[VAR_4 / 4 - 1], VAR_2, VAR_7, VAR_8);

        return -1;

    }



    

    return FUNC_0(VAR_0, VAR_1, VAR_2, new_entry, VAR_4 - 4,

                                VAR_5, VAR_6, VAR_7, VAR_8);

}

static int FUNC_0(CPUS390XState *VAR_0, target_ulong VAR_1,
uint64_t VAR_2, uint64_t VAR_3, int VAR_4,
target_ulong *VAR_5, int *VAR_6, int VAR_7,
bool VAR_8)
{ CPUState *cs = CPU(s390_env_get_cpu(VAR_0)); uint64_t origin, offs, new_entry; const int VAR_9[4] = { PGM_SEGMENT_TRANS, PGM_REG_THIRD_TRANS,
PGM_REG_SEC_TRANS, PGM_REG_FIRST_TRANS
}; PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, VAR_3); origin = VAR_3 & _REGION_ENTRY_ORIGIN; offs = (VAR_1 >> (17 + 11 * VAR_4 / 4)) & 0x3ff8; new_entry = ldq_phys(cs->as, origin + offs); PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n",
__func__, origin, offs, new_entry); if ((new_entry & _REGION_ENTRY_INV) != 0) { DPRINTF("%s: invalid region\n", __func__); trigger_page_fault(VAR_0, VAR_1, PGM_SEGMENT_TRANS, VAR_2, VAR_7, VAR_8); return -1; } if ((new_entry & _REGION_ENTRY_TYPE_MASK) != VAR_4) { trigger_page_fault(VAR_0, VAR_1, PGM_TRANS_SPEC, VAR_2, VAR_7, VAR_8); return -1; } if (VAR_4 == _ASCE_TYPE_SEGMENT) { return mmu_translate_segment(VAR_0, VAR_1, VAR_2, new_entry, VAR_5, VAR_6,
VAR_7, VAR_8); } offs = (VAR_1 >> (28 + 11 * (VAR_4 - 4) / 4)) & 3; if (offs < ((new_entry & _REGION_ENTRY_TF) >> 6)
|| offs > (new_entry & _REGION_ENTRY_LENGTH)) { DPRINTF("%s: invalid offset or len (%lx)\n", __func__, new_entry); trigger_page_fault(VAR_0, VAR_1, VAR_9[VAR_4 / 4 - 1], VAR_2, VAR_7, VAR_8); return -1; } return FUNC_0(VAR_0, VAR_1, VAR_2, new_entry, VAR_4 - 4,
VAR_5, VAR_6, VAR_7, VAR_8); }