static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi,

                               TCGMemOp opc, int mem_index, bool is_load)

{

    TCGReg base = TCG_AREG0;

    int cmp_off =

        (is_load

         ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)

         : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));

    int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);

    unsigned s_bits = opc & MO_SIZE;

    unsigned a_bits = get_alignment_bits(opc);



    /* V7 generates the following:

     *   ubfx   r0, addrlo, #TARGET_PAGE_BITS, #CPU_TLB_BITS

     *   add    r2, env, #high

     *   add    r2, r2, r0, lsl #CPU_TLB_ENTRY_BITS

     *   ldr    r0, [r2, #cmp]

     *   ldr    r2, [r2, #add]

     *   movw   tmp, #page_align_mask

     *   bic    tmp, addrlo, tmp

     *   cmp    r0, tmp

     *

     * Otherwise we generate:

     *   shr    tmp, addrlo, #TARGET_PAGE_BITS

     *   add    r2, env, #high

     *   and    r0, tmp, #(CPU_TLB_SIZE - 1)

     *   add    r2, r2, r0, lsl #CPU_TLB_ENTRY_BITS

     *   ldr    r0, [r2, #cmp]

     *   ldr    r2, [r2, #add]

     *   tst    addrlo, #s_mask

     *   cmpeq  r0, tmp, lsl #TARGET_PAGE_BITS

     */

    if (use_armv7_instructions) {

        tcg_out_extract(s, COND_AL, TCG_REG_R0, addrlo,

                        TARGET_PAGE_BITS, CPU_TLB_BITS);

    } else {

        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,

                        0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS));

    }



    /* We checked that the offset is contained within 16 bits above.  */

    if (add_off > 0xfff || (use_armv6_instructions && cmp_off > 0xff)) {

        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,

                        (24 << 7) | (cmp_off >> 8));

        base = TCG_REG_R2;

        add_off -= cmp_off & 0xff00;

        cmp_off &= 0xff;

    }

    if (!use_armv7_instructions) {

        tcg_out_dat_imm(s, COND_AL, ARITH_AND,

                        TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1);

    }

    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,

                    TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));



    /* Load the tlb comparator.  Use ldrd if needed and available,

       but due to how the pointer needs setting up, ldm isn't useful.

       Base arm5 doesn't have ldrd, but armv5te does.  */

    if (use_armv6_instructions && TARGET_LONG_BITS == 64) {

        tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);

    } else {

        tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);

        if (TARGET_LONG_BITS == 64) {

            tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, cmp_off + 4);

        }

    }



    /* Load the tlb addend.  */

    tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R2, add_off);



    /* Check alignment.  We don't support inline unaligned acceses,

       but we can easily support overalignment checks.  */

    if (a_bits < s_bits) {

        a_bits = s_bits;

    }



    if (use_armv7_instructions) {

        tcg_target_ulong mask = ~(TARGET_PAGE_MASK | ((1 << a_bits) - 1));

        int rot = encode_imm(mask);



        if (rot >= 0) { 

            tcg_out_dat_imm(s, COND_AL, ARITH_BIC, TCG_REG_TMP, addrlo,

                            rotl(mask, rot) | (rot << 7));

        } else {

            tcg_out_movi32(s, COND_AL, TCG_REG_TMP, mask);

            tcg_out_dat_reg(s, COND_AL, ARITH_BIC, TCG_REG_TMP,

                            addrlo, TCG_REG_TMP, 0);

        }

        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R0, TCG_REG_TMP, 0);

    } else {

        if (a_bits) {

            tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo,

                            (1 << a_bits) - 1);

        }

        tcg_out_dat_reg(s, (a_bits ? COND_EQ : COND_AL), ARITH_CMP,

                        0, TCG_REG_R0, TCG_REG_TMP,

                        SHIFT_IMM_LSL(TARGET_PAGE_BITS));

    }



    if (TARGET_LONG_BITS == 64) {

        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R1, addrhi, 0);

    }



    return TCG_REG_R2;

}

static TCGReg tcg_out_tlb_read(TCGContext *s, TCGReg addrlo, TCGReg addrhi,

                               TCGMemOp opc, int mem_index, bool is_load)

{

    TCGReg base = TCG_AREG0;

    int cmp_off =

        (is_load

         ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)

         : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));

    int add_off = offsetof(CPUArchState, tlb_table[mem_index][0].addend);

    unsigned s_bits = opc & MO_SIZE;

    unsigned a_bits = get_alignment_bits(opc);



    







































    if (use_armv7_instructions) {

        tcg_out_extract(s, COND_AL, TCG_REG_R0, addrlo,

                        TARGET_PAGE_BITS, CPU_TLB_BITS);

    } else {

        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,

                        0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS));

    }



    

    if (add_off > 0xfff || (use_armv6_instructions && cmp_off > 0xff)) {

        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,

                        (24 << 7) | (cmp_off >> 8));

        base = TCG_REG_R2;

        add_off -= cmp_off & 0xff00;

        cmp_off &= 0xff;

    }

    if (!use_armv7_instructions) {

        tcg_out_dat_imm(s, COND_AL, ARITH_AND,

                        TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1);

    }

    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,

                    TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));



    





    if (use_armv6_instructions && TARGET_LONG_BITS == 64) {

        tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);

    } else {

        tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_R2, cmp_off);

        if (TARGET_LONG_BITS == 64) {

            tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, cmp_off + 4);

        }

    }



    

    tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R2, add_off);



    



    if (a_bits < s_bits) {

        a_bits = s_bits;

    }



    if (use_armv7_instructions) {

        tcg_target_ulong mask = ~(TARGET_PAGE_MASK | ((1 << a_bits) - 1));

        int rot = encode_imm(mask);



        if (rot >= 0) { 

            tcg_out_dat_imm(s, COND_AL, ARITH_BIC, TCG_REG_TMP, addrlo,

                            rotl(mask, rot) | (rot << 7));

        } else {

            tcg_out_movi32(s, COND_AL, TCG_REG_TMP, mask);

            tcg_out_dat_reg(s, COND_AL, ARITH_BIC, TCG_REG_TMP,

                            addrlo, TCG_REG_TMP, 0);

        }

        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R0, TCG_REG_TMP, 0);

    } else {

        if (a_bits) {

            tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo,

                            (1 << a_bits) - 1);

        }

        tcg_out_dat_reg(s, (a_bits ? COND_EQ : COND_AL), ARITH_CMP,

                        0, TCG_REG_R0, TCG_REG_TMP,

                        SHIFT_IMM_LSL(TARGET_PAGE_BITS));

    }



    if (TARGET_LONG_BITS == 64) {

        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R1, addrhi, 0);

    }



    return TCG_REG_R2;

}

static TCGReg FUNC_0(TCGContext *s, TCGReg addrlo, TCGReg addrhi,

                               TCGMemOp opc, int mem_index, bool is_load)

{

    TCGReg base = TCG_AREG0;

    int VAR_0 =

        (is_load

         ? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)

         : offsetof(CPUArchState, tlb_table[mem_index][0].addr_write));

    int VAR_1 = offsetof(CPUArchState, tlb_table[mem_index][0].addend);

    unsigned VAR_2 = opc & MO_SIZE;

    unsigned VAR_3 = get_alignment_bits(opc);



    







































    if (use_armv7_instructions) {

        tcg_out_extract(s, COND_AL, TCG_REG_R0, addrlo,

                        TARGET_PAGE_BITS, CPU_TLB_BITS);

    } else {

        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,

                        0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS));

    }



    

    if (VAR_1 > 0xfff || (use_armv6_instructions && VAR_0 > 0xff)) {

        tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,

                        (24 << 7) | (VAR_0 >> 8));

        base = TCG_REG_R2;

        VAR_1 -= VAR_0 & 0xff00;

        VAR_0 &= 0xff;

    }

    if (!use_armv7_instructions) {

        tcg_out_dat_imm(s, COND_AL, ARITH_AND,

                        TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1);

    }

    tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,

                    TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS));



    





    if (use_armv6_instructions && TARGET_LONG_BITS == 64) {

        tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_REG_R2, VAR_0);

    } else {

        tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_R2, VAR_0);

        if (TARGET_LONG_BITS == 64) {

            tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, VAR_0 + 4);

        }

    }



    

    tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R2, VAR_1);



    



    if (VAR_3 < VAR_2) {

        VAR_3 = VAR_2;

    }



    if (use_armv7_instructions) {

        tcg_target_ulong mask = ~(TARGET_PAGE_MASK | ((1 << VAR_3) - 1));

        int VAR_4 = encode_imm(mask);



        if (VAR_4 >= 0) { 

            tcg_out_dat_imm(s, COND_AL, ARITH_BIC, TCG_REG_TMP, addrlo,

                            rotl(mask, VAR_4) | (VAR_4 << 7));

        } else {

            tcg_out_movi32(s, COND_AL, TCG_REG_TMP, mask);

            tcg_out_dat_reg(s, COND_AL, ARITH_BIC, TCG_REG_TMP,

                            addrlo, TCG_REG_TMP, 0);

        }

        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R0, TCG_REG_TMP, 0);

    } else {

        if (VAR_3) {

            tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo,

                            (1 << VAR_3) - 1);

        }

        tcg_out_dat_reg(s, (VAR_3 ? COND_EQ : COND_AL), ARITH_CMP,

                        0, TCG_REG_R0, TCG_REG_TMP,

                        SHIFT_IMM_LSL(TARGET_PAGE_BITS));

    }



    if (TARGET_LONG_BITS == 64) {

        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R1, addrhi, 0);

    }



    return TCG_REG_R2;

}

static TCGReg FUNC_0(TCGContext *s, TCGReg addrlo, TCGReg addrhi,
TCGMemOp opc, int mem_index, bool is_load)
{ TCGReg base = TCG_AREG0; int VAR_0 =
(is_load
? offsetof(CPUArchState, tlb_table[mem_index][0].addr_read)
: offsetof(CPUArchState, tlb_table[mem_index][0].addr_write)); int VAR_1 = offsetof(CPUArchState, tlb_table[mem_index][0].addend); unsigned VAR_2 = opc & MO_SIZE; unsigned VAR_3 = get_alignment_bits(opc); if (use_armv7_instructions) { tcg_out_extract(s, COND_AL, TCG_REG_R0, addrlo,
TARGET_PAGE_BITS, CPU_TLB_BITS); } else { tcg_out_dat_reg(s, COND_AL, ARITH_MOV, TCG_REG_TMP,
0, addrlo, SHIFT_IMM_LSR(TARGET_PAGE_BITS)); } if (VAR_1 > 0xfff || (use_armv6_instructions && VAR_0 > 0xff)) { tcg_out_dat_imm(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
(24 << 7) | (VAR_0 >> 8)); base = TCG_REG_R2; VAR_1 -= VAR_0 & 0xff00; VAR_0 &= 0xff; } if (!use_armv7_instructions) { tcg_out_dat_imm(s, COND_AL, ARITH_AND,
TCG_REG_R0, TCG_REG_TMP, CPU_TLB_SIZE - 1); } tcg_out_dat_reg(s, COND_AL, ARITH_ADD, TCG_REG_R2, base,
TCG_REG_R0, SHIFT_IMM_LSL(CPU_TLB_ENTRY_BITS)); if (use_armv6_instructions && TARGET_LONG_BITS == 64) { tcg_out_ldrd_8(s, COND_AL, TCG_REG_R0, TCG_REG_R2, VAR_0); } else { tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_R2, VAR_0); if (TARGET_LONG_BITS == 64) { tcg_out_ld32_12(s, COND_AL, TCG_REG_R1, TCG_REG_R2, VAR_0 + 4); } } tcg_out_ld32_12(s, COND_AL, TCG_REG_R2, TCG_REG_R2, VAR_1); if (VAR_3 < VAR_2) { VAR_3 = VAR_2; } if (use_armv7_instructions) { tcg_target_ulong mask = ~(TARGET_PAGE_MASK | ((1 << VAR_3) - 1)); int VAR_4 = encode_imm(mask); if (VAR_4 >= 0) { tcg_out_dat_imm(s, COND_AL, ARITH_BIC, TCG_REG_TMP, addrlo,
rotl(mask, VAR_4) | (VAR_4 << 7)); } else { tcg_out_movi32(s, COND_AL, TCG_REG_TMP, mask); tcg_out_dat_reg(s, COND_AL, ARITH_BIC, TCG_REG_TMP,
addrlo, TCG_REG_TMP, 0); } tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0, TCG_REG_R0, TCG_REG_TMP, 0); } else { if (VAR_3) { tcg_out_dat_imm(s, COND_AL, ARITH_TST, 0, addrlo,
(1 << VAR_3) - 1); } tcg_out_dat_reg(s, (VAR_3 ? COND_EQ : COND_AL), ARITH_CMP,
0, TCG_REG_R0, TCG_REG_TMP,
SHIFT_IMM_LSL(TARGET_PAGE_BITS)); } if (TARGET_LONG_BITS == 64) { tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0, TCG_REG_R1, addrhi, 0); } return TCG_REG_R2; }