Loading configure +0 −6 Original line number Diff line number Diff line Loading @@ -1280,28 +1280,22 @@ case "$target_cpu" in ;; mips|mipsel) echo "TARGET_ARCH=mips" >> $config_mak echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mips\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_ABI_MIPSO32 1" >> $config_h echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; mipsn32|mipsn32el) echo "TARGET_ARCH=mipsn32" >> $config_mak echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mipsn32\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_ABI_MIPSN32 1" >> $config_h echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; mips64|mips64el) echo "TARGET_ARCH=mips64" >> $config_mak echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mips64\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_MIPS64 1" >> $config_h echo "#define TARGET_ABI_MIPSN64 1" >> $config_h echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; ppc) echo "TARGET_ARCH=ppc" >> $config_mak Loading target-mips/helper.h +11 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,17 @@ DEF_HELPER(void, do_raise_exception_err, (int excp, int err)) DEF_HELPER(void, do_raise_exception, (int excp)) DEF_HELPER(void, do_interrupt_restart, (void)) #ifdef TARGET_MIPS64 DEF_HELPER(void, do_ldl, (int mem_idx)) DEF_HELPER(void, do_ldr, (int mem_idx)) DEF_HELPER(void, do_sdl, (int mem_idx)) DEF_HELPER(void, do_sdr, (int mem_idx)) #endif DEF_HELPER(void, do_lwl, (int mem_idx)) DEF_HELPER(void, do_lwr, (int mem_idx)) DEF_HELPER(void, do_swl, (int mem_idx)) DEF_HELPER(void, do_swr, (int mem_idx)) DEF_HELPER(void, do_clo, (void)) DEF_HELPER(void, do_clz, (void)) #ifdef TARGET_MIPS64 Loading target-mips/op.c +0 −26 Original line number Diff line number Diff line Loading @@ -19,29 +19,3 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "exec.h" #include "host-utils.h" #ifndef CALL_FROM_TB0 #define CALL_FROM_TB0(func) func() #endif /* Load and store */ #define MEMSUFFIX _raw #include "op_mem.c" #undef MEMSUFFIX #if !defined(CONFIG_USER_ONLY) #define MEMSUFFIX _user #include "op_mem.c" #undef MEMSUFFIX #define MEMSUFFIX _super #include "op_mem.c" #undef MEMSUFFIX #define MEMSUFFIX _kernel #include "op_mem.c" #undef MEMSUFFIX #endif target-mips/op_helper.c +337 −0 Original line number Diff line number Diff line Loading @@ -308,6 +308,343 @@ void do_dmultu (void) } #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 void do_lwl(int mem_idx) { target_ulong tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else int (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0x00FFFFFF) | (tmp << 24); if (GET_LMASK(T0) <= 2) { tmp = ldfun(GET_OFFSET(T0, 1)); T1 = (T1 & 0xFF00FFFF) | (tmp << 16); } if (GET_LMASK(T0) <= 1) { tmp = ldfun(GET_OFFSET(T0, 2)); T1 = (T1 & 0xFFFF00FF) | (tmp << 8); } if (GET_LMASK(T0) == 0) { tmp = ldfun(GET_OFFSET(T0, 3)); T1 = (T1 & 0xFFFFFF00) | tmp; } T1 = (int32_t)T1; } void do_lwr(int mem_idx) { target_ulong tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else int (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0xFFFFFF00) | tmp; if (GET_LMASK(T0) >= 1) { tmp = ldfun(GET_OFFSET(T0, -1)); T1 = (T1 & 0xFFFF00FF) | (tmp << 8); } if (GET_LMASK(T0) >= 2) { tmp = ldfun(GET_OFFSET(T0, -2)); T1 = (T1 & 0xFF00FFFF) | (tmp << 16); } if (GET_LMASK(T0) == 3) { tmp = ldfun(GET_OFFSET(T0, -3)); T1 = (T1 & 0x00FFFFFF) | (tmp << 24); } T1 = (int32_t)T1; } void do_swl(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)(T1 >> 24)); if (GET_LMASK(T0) <= 2) stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); if (GET_LMASK(T0) <= 1) stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); if (GET_LMASK(T0) == 0) stfun(GET_OFFSET(T0, 3), (uint8_t)T1); } void do_swr(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)T1); if (GET_LMASK(T0) >= 1) stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); if (GET_LMASK(T0) >= 2) stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); if (GET_LMASK(T0) == 3) stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); } #if defined(TARGET_MIPS64) /* "half" load and stores. We must do the memory access inline, or fault handling won't work. */ #ifdef TARGET_WORDS_BIGENDIAN #define GET_LMASK64(v) ((v) & 7) #else #define GET_LMASK64(v) (((v) & 7) ^ 7) #endif void do_ldl(int mem_idx) { uint64_t tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else target_ulong (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); if (GET_LMASK64(T0) <= 6) { tmp = ldfun(GET_OFFSET(T0, 1)); T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); } if (GET_LMASK64(T0) <= 5) { tmp = ldfun(GET_OFFSET(T0, 2)); T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); } if (GET_LMASK64(T0) <= 4) { tmp = ldfun(GET_OFFSET(T0, 3)); T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); } if (GET_LMASK64(T0) <= 3) { tmp = ldfun(GET_OFFSET(T0, 4)); T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); } if (GET_LMASK64(T0) <= 2) { tmp = ldfun(GET_OFFSET(T0, 5)); T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); } if (GET_LMASK64(T0) <= 1) { tmp = ldfun(GET_OFFSET(T0, 6)); T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); } if (GET_LMASK64(T0) == 0) { tmp = ldfun(GET_OFFSET(T0, 7)); T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; } } void do_ldr(int mem_idx) { uint64_t tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else target_ulong (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; if (GET_LMASK64(T0) >= 1) { tmp = ldfun(GET_OFFSET(T0, -1)); T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); } if (GET_LMASK64(T0) >= 2) { tmp = ldfun(GET_OFFSET(T0, -2)); T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); } if (GET_LMASK64(T0) >= 3) { tmp = ldfun(GET_OFFSET(T0, -3)); T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); } if (GET_LMASK64(T0) >= 4) { tmp = ldfun(GET_OFFSET(T0, -4)); T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); } if (GET_LMASK64(T0) >= 5) { tmp = ldfun(GET_OFFSET(T0, -5)); T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); } if (GET_LMASK64(T0) >= 6) { tmp = ldfun(GET_OFFSET(T0, -6)); T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); } if (GET_LMASK64(T0) == 7) { tmp = ldfun(GET_OFFSET(T0, -7)); T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); } } void do_sdl(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)(T1 >> 56)); if (GET_LMASK64(T0) <= 6) stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); if (GET_LMASK64(T0) <= 5) stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); if (GET_LMASK64(T0) <= 4) stfun(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); if (GET_LMASK64(T0) <= 3) stfun(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); if (GET_LMASK64(T0) <= 2) stfun(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); if (GET_LMASK64(T0) <= 1) stfun(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); if (GET_LMASK64(T0) <= 0) stfun(GET_OFFSET(T0, 7), (uint8_t)T1); } void do_sdr(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)T1); if (GET_LMASK64(T0) >= 1) stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); if (GET_LMASK64(T0) >= 2) stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); if (GET_LMASK64(T0) >= 3) stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); if (GET_LMASK64(T0) >= 4) stfun(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); if (GET_LMASK64(T0) >= 5) stfun(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); if (GET_LMASK64(T0) >= 6) stfun(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); if (GET_LMASK64(T0) == 7) stfun(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); } #endif /* TARGET_MIPS64 */ #ifdef CONFIG_USER_ONLY void do_mfc0_random (void) { Loading target-mips/translate.c +16 −39 Original line number Diff line number Diff line Loading @@ -945,37 +945,6 @@ static always_inline void check_mips_64(DisasContext *ctx) } /* load/store instructions. */ #if defined(CONFIG_USER_ONLY) #define op_ldst(name) gen_op_##name##_raw() #define OP_LD_TABLE(width) #define OP_ST_TABLE(width) #else #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])() #define OP_LD_TABLE(width) \ static GenOpFunc *gen_op_l##width[] = { \ &gen_op_l##width##_kernel, \ &gen_op_l##width##_super, \ &gen_op_l##width##_user, \ } #define OP_ST_TABLE(width) \ static GenOpFunc *gen_op_s##width[] = { \ &gen_op_s##width##_kernel, \ &gen_op_s##width##_super, \ &gen_op_s##width##_user, \ } #endif #if defined(TARGET_MIPS64) OP_LD_TABLE(dl); OP_LD_TABLE(dr); OP_ST_TABLE(dl); OP_ST_TABLE(dr); #endif OP_LD_TABLE(wl); OP_LD_TABLE(wr); OP_ST_TABLE(wl); OP_ST_TABLE(wr); #define OP_LD(insn,fname) \ void inline op_ldst_##insn(DisasContext *ctx) \ { \ Loading Loading @@ -1094,25 +1063,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, opn = "scd"; break; case OPC_LDL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(ldl); tcg_gen_helper_0_1i(do_ldl, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldl"; break; case OPC_SDL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(sdl); tcg_gen_helper_0_1i(do_sdl, ctx->mem_idx); opn = "sdl"; break; case OPC_LDR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(ldr); tcg_gen_helper_0_1i(do_ldr, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldr"; break; case OPC_SDR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(sdr); tcg_gen_helper_0_1i(do_sdr, ctx->mem_idx); opn = "sdr"; break; #endif Loading Loading @@ -1157,25 +1130,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, opn = "lbu"; break; case OPC_LWL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(lwl); tcg_gen_helper_0_1i(do_lwl, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwl"; break; case OPC_SWL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(swl); tcg_gen_helper_0_1i(do_swl, ctx->mem_idx); opn = "swr"; break; case OPC_LWR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(lwr); tcg_gen_helper_0_1i(do_lwr, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwr"; break; case OPC_SWR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(swr); tcg_gen_helper_0_1i(do_swr, ctx->mem_idx); opn = "swr"; break; case OPC_LL: Loading Loading
configure +0 −6 Original line number Diff line number Diff line Loading @@ -1280,28 +1280,22 @@ case "$target_cpu" in ;; mips|mipsel) echo "TARGET_ARCH=mips" >> $config_mak echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mips\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_ABI_MIPSO32 1" >> $config_h echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; mipsn32|mipsn32el) echo "TARGET_ARCH=mipsn32" >> $config_mak echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mipsn32\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_ABI_MIPSN32 1" >> $config_h echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; mips64|mips64el) echo "TARGET_ARCH=mips64" >> $config_mak echo "CONFIG_DYNGEN_OP=yes" >> $config_mak echo "#define TARGET_ARCH \"mips64\"" >> $config_h echo "#define TARGET_MIPS 1" >> $config_h echo "#define TARGET_MIPS64 1" >> $config_h echo "#define TARGET_ABI_MIPSN64 1" >> $config_h echo "#define CONFIG_DYNGEN_OP 1" >> $config_h ;; ppc) echo "TARGET_ARCH=ppc" >> $config_mak Loading
target-mips/helper.h +11 −0 Original line number Diff line number Diff line Loading @@ -6,6 +6,17 @@ DEF_HELPER(void, do_raise_exception_err, (int excp, int err)) DEF_HELPER(void, do_raise_exception, (int excp)) DEF_HELPER(void, do_interrupt_restart, (void)) #ifdef TARGET_MIPS64 DEF_HELPER(void, do_ldl, (int mem_idx)) DEF_HELPER(void, do_ldr, (int mem_idx)) DEF_HELPER(void, do_sdl, (int mem_idx)) DEF_HELPER(void, do_sdr, (int mem_idx)) #endif DEF_HELPER(void, do_lwl, (int mem_idx)) DEF_HELPER(void, do_lwr, (int mem_idx)) DEF_HELPER(void, do_swl, (int mem_idx)) DEF_HELPER(void, do_swr, (int mem_idx)) DEF_HELPER(void, do_clo, (void)) DEF_HELPER(void, do_clz, (void)) #ifdef TARGET_MIPS64 Loading
target-mips/op.c +0 −26 Original line number Diff line number Diff line Loading @@ -19,29 +19,3 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include "exec.h" #include "host-utils.h" #ifndef CALL_FROM_TB0 #define CALL_FROM_TB0(func) func() #endif /* Load and store */ #define MEMSUFFIX _raw #include "op_mem.c" #undef MEMSUFFIX #if !defined(CONFIG_USER_ONLY) #define MEMSUFFIX _user #include "op_mem.c" #undef MEMSUFFIX #define MEMSUFFIX _super #include "op_mem.c" #undef MEMSUFFIX #define MEMSUFFIX _kernel #include "op_mem.c" #undef MEMSUFFIX #endif
target-mips/op_helper.c +337 −0 Original line number Diff line number Diff line Loading @@ -308,6 +308,343 @@ void do_dmultu (void) } #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 void do_lwl(int mem_idx) { target_ulong tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else int (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0x00FFFFFF) | (tmp << 24); if (GET_LMASK(T0) <= 2) { tmp = ldfun(GET_OFFSET(T0, 1)); T1 = (T1 & 0xFF00FFFF) | (tmp << 16); } if (GET_LMASK(T0) <= 1) { tmp = ldfun(GET_OFFSET(T0, 2)); T1 = (T1 & 0xFFFF00FF) | (tmp << 8); } if (GET_LMASK(T0) == 0) { tmp = ldfun(GET_OFFSET(T0, 3)); T1 = (T1 & 0xFFFFFF00) | tmp; } T1 = (int32_t)T1; } void do_lwr(int mem_idx) { target_ulong tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else int (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0xFFFFFF00) | tmp; if (GET_LMASK(T0) >= 1) { tmp = ldfun(GET_OFFSET(T0, -1)); T1 = (T1 & 0xFFFF00FF) | (tmp << 8); } if (GET_LMASK(T0) >= 2) { tmp = ldfun(GET_OFFSET(T0, -2)); T1 = (T1 & 0xFF00FFFF) | (tmp << 16); } if (GET_LMASK(T0) == 3) { tmp = ldfun(GET_OFFSET(T0, -3)); T1 = (T1 & 0x00FFFFFF) | (tmp << 24); } T1 = (int32_t)T1; } void do_swl(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)(T1 >> 24)); if (GET_LMASK(T0) <= 2) stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 16)); if (GET_LMASK(T0) <= 1) stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 8)); if (GET_LMASK(T0) == 0) stfun(GET_OFFSET(T0, 3), (uint8_t)T1); } void do_swr(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)T1); if (GET_LMASK(T0) >= 1) stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); if (GET_LMASK(T0) >= 2) stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); if (GET_LMASK(T0) == 3) stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); } #if defined(TARGET_MIPS64) /* "half" load and stores. We must do the memory access inline, or fault handling won't work. */ #ifdef TARGET_WORDS_BIGENDIAN #define GET_LMASK64(v) ((v) & 7) #else #define GET_LMASK64(v) (((v) & 7) ^ 7) #endif void do_ldl(int mem_idx) { uint64_t tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else target_ulong (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); if (GET_LMASK64(T0) <= 6) { tmp = ldfun(GET_OFFSET(T0, 1)); T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); } if (GET_LMASK64(T0) <= 5) { tmp = ldfun(GET_OFFSET(T0, 2)); T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); } if (GET_LMASK64(T0) <= 4) { tmp = ldfun(GET_OFFSET(T0, 3)); T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); } if (GET_LMASK64(T0) <= 3) { tmp = ldfun(GET_OFFSET(T0, 4)); T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); } if (GET_LMASK64(T0) <= 2) { tmp = ldfun(GET_OFFSET(T0, 5)); T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); } if (GET_LMASK64(T0) <= 1) { tmp = ldfun(GET_OFFSET(T0, 6)); T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); } if (GET_LMASK64(T0) == 0) { tmp = ldfun(GET_OFFSET(T0, 7)); T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; } } void do_ldr(int mem_idx) { uint64_t tmp; #ifdef CONFIG_USER_ONLY #define ldfun ldub_raw #else target_ulong (*ldfun)(target_ulong); switch (mem_idx) { case 0: ldfun = ldub_kernel; break; case 1: ldfun = ldub_super; break; default: case 2: ldfun = ldub_user; break; } #endif tmp = ldfun(T0); T1 = (T1 & 0xFFFFFFFFFFFFFF00ULL) | tmp; if (GET_LMASK64(T0) >= 1) { tmp = ldfun(GET_OFFSET(T0, -1)); T1 = (T1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8); } if (GET_LMASK64(T0) >= 2) { tmp = ldfun(GET_OFFSET(T0, -2)); T1 = (T1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16); } if (GET_LMASK64(T0) >= 3) { tmp = ldfun(GET_OFFSET(T0, -3)); T1 = (T1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24); } if (GET_LMASK64(T0) >= 4) { tmp = ldfun(GET_OFFSET(T0, -4)); T1 = (T1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32); } if (GET_LMASK64(T0) >= 5) { tmp = ldfun(GET_OFFSET(T0, -5)); T1 = (T1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40); } if (GET_LMASK64(T0) >= 6) { tmp = ldfun(GET_OFFSET(T0, -6)); T1 = (T1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48); } if (GET_LMASK64(T0) == 7) { tmp = ldfun(GET_OFFSET(T0, -7)); T1 = (T1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56); } } void do_sdl(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)(T1 >> 56)); if (GET_LMASK64(T0) <= 6) stfun(GET_OFFSET(T0, 1), (uint8_t)(T1 >> 48)); if (GET_LMASK64(T0) <= 5) stfun(GET_OFFSET(T0, 2), (uint8_t)(T1 >> 40)); if (GET_LMASK64(T0) <= 4) stfun(GET_OFFSET(T0, 3), (uint8_t)(T1 >> 32)); if (GET_LMASK64(T0) <= 3) stfun(GET_OFFSET(T0, 4), (uint8_t)(T1 >> 24)); if (GET_LMASK64(T0) <= 2) stfun(GET_OFFSET(T0, 5), (uint8_t)(T1 >> 16)); if (GET_LMASK64(T0) <= 1) stfun(GET_OFFSET(T0, 6), (uint8_t)(T1 >> 8)); if (GET_LMASK64(T0) <= 0) stfun(GET_OFFSET(T0, 7), (uint8_t)T1); } void do_sdr(int mem_idx) { #ifdef CONFIG_USER_ONLY #define stfun stb_raw #else void (*stfun)(target_ulong, int); switch (mem_idx) { case 0: stfun = stb_kernel; break; case 1: stfun = stb_super; break; default: case 2: stfun = stb_user; break; } #endif stfun(T0, (uint8_t)T1); if (GET_LMASK64(T0) >= 1) stfun(GET_OFFSET(T0, -1), (uint8_t)(T1 >> 8)); if (GET_LMASK64(T0) >= 2) stfun(GET_OFFSET(T0, -2), (uint8_t)(T1 >> 16)); if (GET_LMASK64(T0) >= 3) stfun(GET_OFFSET(T0, -3), (uint8_t)(T1 >> 24)); if (GET_LMASK64(T0) >= 4) stfun(GET_OFFSET(T0, -4), (uint8_t)(T1 >> 32)); if (GET_LMASK64(T0) >= 5) stfun(GET_OFFSET(T0, -5), (uint8_t)(T1 >> 40)); if (GET_LMASK64(T0) >= 6) stfun(GET_OFFSET(T0, -6), (uint8_t)(T1 >> 48)); if (GET_LMASK64(T0) == 7) stfun(GET_OFFSET(T0, -7), (uint8_t)(T1 >> 56)); } #endif /* TARGET_MIPS64 */ #ifdef CONFIG_USER_ONLY void do_mfc0_random (void) { Loading
target-mips/translate.c +16 −39 Original line number Diff line number Diff line Loading @@ -945,37 +945,6 @@ static always_inline void check_mips_64(DisasContext *ctx) } /* load/store instructions. */ #if defined(CONFIG_USER_ONLY) #define op_ldst(name) gen_op_##name##_raw() #define OP_LD_TABLE(width) #define OP_ST_TABLE(width) #else #define op_ldst(name) (*gen_op_##name[ctx->mem_idx])() #define OP_LD_TABLE(width) \ static GenOpFunc *gen_op_l##width[] = { \ &gen_op_l##width##_kernel, \ &gen_op_l##width##_super, \ &gen_op_l##width##_user, \ } #define OP_ST_TABLE(width) \ static GenOpFunc *gen_op_s##width[] = { \ &gen_op_s##width##_kernel, \ &gen_op_s##width##_super, \ &gen_op_s##width##_user, \ } #endif #if defined(TARGET_MIPS64) OP_LD_TABLE(dl); OP_LD_TABLE(dr); OP_ST_TABLE(dl); OP_ST_TABLE(dr); #endif OP_LD_TABLE(wl); OP_LD_TABLE(wr); OP_ST_TABLE(wl); OP_ST_TABLE(wr); #define OP_LD(insn,fname) \ void inline op_ldst_##insn(DisasContext *ctx) \ { \ Loading Loading @@ -1094,25 +1063,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, opn = "scd"; break; case OPC_LDL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(ldl); tcg_gen_helper_0_1i(do_ldl, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldl"; break; case OPC_SDL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(sdl); tcg_gen_helper_0_1i(do_sdl, ctx->mem_idx); opn = "sdl"; break; case OPC_LDR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(ldr); tcg_gen_helper_0_1i(do_ldr, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "ldr"; break; case OPC_SDR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(sdr); tcg_gen_helper_0_1i(do_sdr, ctx->mem_idx); opn = "sdr"; break; #endif Loading Loading @@ -1157,25 +1130,29 @@ static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt, opn = "lbu"; break; case OPC_LWL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(lwl); tcg_gen_helper_0_1i(do_lwl, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwl"; break; case OPC_SWL: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(swl); tcg_gen_helper_0_1i(do_swl, ctx->mem_idx); opn = "swr"; break; case OPC_LWR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(lwr); tcg_gen_helper_0_1i(do_lwr, ctx->mem_idx); gen_store_gpr(cpu_T[1], rt); opn = "lwr"; break; case OPC_SWR: save_cpu_state(ctx, 1); gen_load_gpr(cpu_T[1], rt); op_ldst(swr); tcg_gen_helper_0_1i(do_swr, ctx->mem_idx); opn = "swr"; break; case OPC_LL: Loading