static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,

                               TCGMemOp s_bits, int which)

{

    const TCGReg r0 = TCG_REG_O0;

    const TCGReg r1 = TCG_REG_O1;

    const TCGReg r2 = TCG_REG_O2;

    int tlb_ofs;



    /* Shift the page number down.  */

    tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);



    /* Mask out the page offset, except for the required alignment.  */

    tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,

                 TARGET_PAGE_MASK | ((1 << s_bits) - 1));



    /* Mask the tlb index.  */

    tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);

    

    /* Mask page, part 2.  */

    tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);



    /* Shift the tlb index into place.  */

    tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);



    /* Relative to the current ENV.  */

    tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);



    /* Find a base address that can load both tlb comparator and addend.  */

    tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);

    if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {

        tcg_out_addi(s, r1, tlb_ofs & ~0x3ff);

        tlb_ofs &= 0x3ff;

    }



    /* Load the tlb comparator and the addend.  */

    tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);

    tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));



    /* subcc arg0, arg2, %g0 */

    tcg_out_cmp(s, r0, r2, 0);



    /* If the guest address must be zero-extended, do so now.  */

    if (SPARC64 && TARGET_LONG_BITS == 32) {

        tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);

        return r0;

    }

    return addr;

}

static TCGReg tcg_out_tlb_load(TCGContext *s, TCGReg addr, int mem_index,

                               TCGMemOp s_bits, int which)

{

    const TCGReg r0 = TCG_REG_O0;

    const TCGReg r1 = TCG_REG_O1;

    const TCGReg r2 = TCG_REG_O2;

    int tlb_ofs;



    

    tcg_out_arithi(s, r1, addr, TARGET_PAGE_BITS, SHIFT_SRL);



    

    tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,

                 TARGET_PAGE_MASK | ((1 << s_bits) - 1));



    

    tcg_out_arithi(s, r1, r1, CPU_TLB_SIZE - 1, ARITH_AND);

    

    

    tcg_out_arith(s, r0, addr, TCG_REG_T1, ARITH_AND);



    

    tcg_out_arithi(s, r1, r1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);



    

    tcg_out_arith(s, r1, TCG_AREG0, r1, ARITH_ADD);



    

    tlb_ofs = offsetof(CPUArchState, tlb_table[mem_index][0]);

    if (!check_fit_tl(tlb_ofs + sizeof(CPUTLBEntry), 13)) {

        tcg_out_addi(s, r1, tlb_ofs & ~0x3ff);

        tlb_ofs &= 0x3ff;

    }



    

    tcg_out_ld(s, TCG_TYPE_TL, r2, r1, tlb_ofs + which);

    tcg_out_ld(s, TCG_TYPE_PTR, r1, r1, tlb_ofs+offsetof(CPUTLBEntry, addend));



    

    tcg_out_cmp(s, r0, r2, 0);



    

    if (SPARC64 && TARGET_LONG_BITS == 32) {

        tcg_out_arithi(s, r0, addr, 0, SHIFT_SRL);

        return r0;

    }

    return addr;

}

static TCGReg FUNC_0(TCGContext *s, TCGReg addr, int mem_index,

                               TCGMemOp s_bits, int which)

{

    const TCGReg VAR_0 = TCG_REG_O0;

    const TCGReg VAR_1 = TCG_REG_O1;

    const TCGReg VAR_2 = TCG_REG_O2;

    int VAR_3;



    

    tcg_out_arithi(s, VAR_1, addr, TARGET_PAGE_BITS, SHIFT_SRL);



    

    tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,

                 TARGET_PAGE_MASK | ((1 << s_bits) - 1));



    

    tcg_out_arithi(s, VAR_1, VAR_1, CPU_TLB_SIZE - 1, ARITH_AND);

    

    

    tcg_out_arith(s, VAR_0, addr, TCG_REG_T1, ARITH_AND);



    

    tcg_out_arithi(s, VAR_1, VAR_1, CPU_TLB_ENTRY_BITS, SHIFT_SLL);



    

    tcg_out_arith(s, VAR_1, TCG_AREG0, VAR_1, ARITH_ADD);



    

    VAR_3 = offsetof(CPUArchState, tlb_table[mem_index][0]);

    if (!check_fit_tl(VAR_3 + sizeof(CPUTLBEntry), 13)) {

        tcg_out_addi(s, VAR_1, VAR_3 & ~0x3ff);

        VAR_3 &= 0x3ff;

    }



    

    tcg_out_ld(s, TCG_TYPE_TL, VAR_2, VAR_1, VAR_3 + which);

    tcg_out_ld(s, TCG_TYPE_PTR, VAR_1, VAR_1, VAR_3+offsetof(CPUTLBEntry, addend));



    

    tcg_out_cmp(s, VAR_0, VAR_2, 0);



    

    if (SPARC64 && TARGET_LONG_BITS == 32) {

        tcg_out_arithi(s, VAR_0, addr, 0, SHIFT_SRL);

        return VAR_0;

    }

    return addr;

}

static TCGReg FUNC_0(TCGContext *s, TCGReg addr, int mem_index,
TCGMemOp s_bits, int which)
{ const TCGReg VAR_0 = TCG_REG_O0; const TCGReg VAR_1 = TCG_REG_O1; const TCGReg VAR_2 = TCG_REG_O2; int VAR_3; tcg_out_arithi(s, VAR_1, addr, TARGET_PAGE_BITS, SHIFT_SRL); tcg_out_movi(s, TCG_TYPE_TL, TCG_REG_T1,
TARGET_PAGE_MASK | ((1 << s_bits) - 1)); tcg_out_arithi(s, VAR_1, VAR_1, CPU_TLB_SIZE - 1, ARITH_AND); tcg_out_arith(s, VAR_0, addr, TCG_REG_T1, ARITH_AND); tcg_out_arithi(s, VAR_1, VAR_1, CPU_TLB_ENTRY_BITS, SHIFT_SLL); tcg_out_arith(s, VAR_1, TCG_AREG0, VAR_1, ARITH_ADD); VAR_3 = offsetof(CPUArchState, tlb_table[mem_index][0]); if (!check_fit_tl(VAR_3 + sizeof(CPUTLBEntry), 13)) { tcg_out_addi(s, VAR_1, VAR_3 & ~0x3ff); VAR_3 &= 0x3ff; } tcg_out_ld(s, TCG_TYPE_TL, VAR_2, VAR_1, VAR_3 + which); tcg_out_ld(s, TCG_TYPE_PTR, VAR_1, VAR_1, VAR_3+offsetof(CPUTLBEntry, addend)); tcg_out_cmp(s, VAR_0, VAR_2, 0); if (SPARC64 && TARGET_LONG_BITS == 32) { tcg_out_arithi(s, VAR_0, addr, 0, SHIFT_SRL); return VAR_0; } return addr; }