HELPER_LD_ATOMIC(ll, lw)

#ifdef TARGET_MIPS64

HELPER_LD_ATOMIC(lld, ld)

#endif

#undef HELPER_LD_ATOMIC



#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask)                      \

target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \

                           target_ulong arg2, int mem_idx)                    \

{                                                                             \

    target_long tmp;                                                          \

                                                                              \

    if (arg2 & almask) {                                                      \

        env->CP0_BadVAddr = arg2;                                             \

        helper_raise_exception(env, EXCP_AdES);                               \

    }                                                                         \

    if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \

        tmp = do_##ld_insn(env, arg2, mem_idx);                               \

        if (tmp == env->llval) {                                              \

            do_##st_insn(env, arg2, arg1, mem_idx);                           \

            return 1;                                                         \

        }                                                                     \

    }                                                                         \

    return 0;                                                                 \

}

HELPER_ST_ATOMIC(sc, lw, sw, 0x3)

#ifdef TARGET_MIPS64

HELPER_ST_ATOMIC(scd, ld, sd, 0x7)

#endif

#undef HELPER_ST_ATOMIC

#endif



#ifdef TARGET_WORDS_BIGENDIAN

#define GET_LMASK(v) ((v) & 3)

#define GET_OFFSET(addr, offset) (addr + (offset))

#else

#define GET_LMASK(v) (((v) & 3) ^ 3)

#define GET_OFFSET(addr, offset) (addr - (offset))

#endif



target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1,

                        target_ulong arg2, int mem_idx)

{

    target_ulong tmp;



    tmp = do_lbu(env, arg2, mem_idx);

    arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);



    if (GET_LMASK(arg2) <= 2) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);

        arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);

    }



    if (GET_LMASK(arg2) <= 1) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);

        arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);

    }



    if (GET_LMASK(arg2) == 0) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);

        arg1 = (arg1 & 0xFFFFFF00) | tmp;

    }

    return (int32_t)arg1;

}

HELPER_LD_ATOMIC(ll, lw)

#ifdef TARGET_MIPS64

HELPER_LD_ATOMIC(lld, ld)

#endif

#undef HELPER_LD_ATOMIC



#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask)                      \

target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \

                           target_ulong arg2, int mem_idx)                    \

{                                                                             \

    target_long tmp;                                                          \

                                                                              \

    if (arg2 & almask) {                                                      \

        env->CP0_BadVAddr = arg2;                                             \

        helper_raise_exception(env, EXCP_AdES);                               \

    }                                                                         \

    if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \

        tmp = do_##ld_insn(env, arg2, mem_idx);                               \

        if (tmp == env->llval) {                                              \

            do_##st_insn(env, arg2, arg1, mem_idx);                           \

            return 1;                                                         \

        }                                                                     \

    }                                                                         \

    return 0;                                                                 \

}

HELPER_ST_ATOMIC(sc, lw, sw, 0x3)

#ifdef TARGET_MIPS64

HELPER_ST_ATOMIC(scd, ld, sd, 0x7)

#endif

#undef HELPER_ST_ATOMIC

#endif



#ifdef TARGET_WORDS_BIGENDIAN

#define GET_LMASK(v) ((v) & 3)

#define GET_OFFSET(addr, offset) (addr + (offset))

#else

#define GET_LMASK(v) (((v) & 3) ^ 3)

#define GET_OFFSET(addr, offset) (addr - (offset))

#endif



target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1,

                        target_ulong arg2, int mem_idx)

{

    target_ulong tmp;



    tmp = do_lbu(env, arg2, mem_idx);

    arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);



    if (GET_LMASK(arg2) <= 2) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);

        arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);

    }



    if (GET_LMASK(arg2) <= 1) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);

        arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);

    }



    if (GET_LMASK(arg2) == 0) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);

        arg1 = (arg1 & 0xFFFFFF00) | tmp;

    }

    return (int32_t)arg1;

}

target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1,                         target_ulong arg2, int mem_idx)     target_ulong tmp;     tmp = do_lbu(env, arg2, mem_idx);     arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);     if (GET_LMASK(arg2) <= 2) {         tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);         arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);     if (GET_LMASK(arg2) <= 1) {         tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);         arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);     if (GET_LMASK(arg2) == 0) {         tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);         arg1 = (arg1 & 0xFFFFFF00) | tmp;     return (int32_t)arg1;                         target_ulong arg2, int mem_idx)     target_ulong tmp;     tmp = do_lbu(env, arg2, mem_idx);         arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);         arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);     return (int32_t)arg1;                         target_ulong arg2, int mem_idx)     tmp = do_lbu(env, arg2, mem_idx);         tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);         tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);         tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);                         target_ulong arg2, int mem_idx)     tmp = do_lbu(env, arg2, mem_idx);
HELPER_LD_ATOMIC(ll, lw)

#ifdef TARGET_MIPS64

HELPER_LD_ATOMIC(lld, ld)

#endif

#undef HELPER_LD_ATOMIC



#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask)                      \

target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \

                           target_ulong arg2, int mem_idx)                    \

{                                                                             \

    target_long tmp;                                                          \

                                                                              \

    if (arg2 & almask) {                                                      \

        env->CP0_BadVAddr = arg2;                                             \

        helper_raise_exception(env, EXCP_AdES);                               \

    }                                                                         \

    if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \

        tmp = do_##ld_insn(env, arg2, mem_idx);                               \

        if (tmp == env->llval) {                                              \

            do_##st_insn(env, arg2, arg1, mem_idx);                           \

            return 1;                                                         \

        }                                                                     \

    }                                                                         \

    return 0;                                                                 \

}

HELPER_ST_ATOMIC(sc, lw, sw, 0x3)

#ifdef TARGET_MIPS64

HELPER_ST_ATOMIC(scd, ld, sd, 0x7)

#endif

#undef HELPER_ST_ATOMIC

#endif



#ifdef TARGET_WORDS_BIGENDIAN

#define GET_LMASK(v) ((v) & 3)

#define GET_OFFSET(addr, offset) (addr + (offset))

#else

#define GET_LMASK(v) (((v) & 3) ^ 3)

#define GET_OFFSET(addr, offset) (addr - (offset))

#endif



target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1,

                        target_ulong arg2, int mem_idx)

{

    target_ulong tmp;



    tmp = do_lbu(env, arg2, mem_idx);

    arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);



    if (GET_LMASK(arg2) <= 2) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx);

        arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);

    }



    if (GET_LMASK(arg2) <= 1) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx);

        arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);

    }



    if (GET_LMASK(arg2) == 0) {

        tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx);

        arg1 = (arg1 & 0xFFFFFF00) | tmp;

    }

    return (int32_t)arg1;

}

HELPER_LD_ATOMIC(ll, lw)
#ifdef TARGET_MIPS64
HELPER_LD_ATOMIC(lld, ld)
#endif
#undef HELPER_LD_ATOMIC
#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask)                      \
target_ulong helper_##name(CPUMIPSState *env, target_ulong arg1,              \
target_ulong arg2, int mem_idx)                    \
{                                                                             \ target_long tmp;                                                          \ \
if (arg2 & almask) {                                                      \ env->CP0_BadVAddr = arg2;                                             \ helper_raise_exception(env, EXCP_AdES);                               \ }                                                                         \ if (do_translate_address(env, arg2, 1) == env->lladdr) {                  \ tmp = do_##ld_insn(env, arg2, mem_idx);                               \ if (tmp == env->llval) {                                              \ do_##st_insn(env, arg2, arg1, mem_idx);                           \ return 1;                                                         \ }                                                                     \ }                                                                         \ return 0;                                                                 \ } HELPER_ST_ATOMIC(sc, lw, sw, 0x3)
#ifdef TARGET_MIPS64
HELPER_ST_ATOMIC(scd, ld, sd, 0x7)
#endif
#undef HELPER_ST_ATOMIC
#endif
#ifdef TARGET_WORDS_BIGENDIAN
#define GET_LMASK(v) ((v) & 3)
#define GET_OFFSET(addr, offset) (addr + (offset))
#else
#define GET_LMASK(v) (((v) & 3) ^ 3)
#define GET_OFFSET(addr, offset) (addr - (offset))
#endif
target_ulong helper_lwl(CPUMIPSState *env, target_ulong arg1,
target_ulong arg2, int mem_idx)
{ target_ulong tmp; tmp = do_lbu(env, arg2, mem_idx); arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24); if (GET_LMASK(arg2) <= 2) { tmp = do_lbu(env, GET_OFFSET(arg2, 1), mem_idx); arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16); } if (GET_LMASK(arg2) <= 1) { tmp = do_lbu(env, GET_OFFSET(arg2, 2), mem_idx); arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8); } if (GET_LMASK(arg2) == 0) { tmp = do_lbu(env, GET_OFFSET(arg2, 3), mem_idx); arg1 = (arg1 & 0xFFFFFF00) | tmp; } return (int32_t)arg1; }