aboutsummaryrefslogtreecommitdiff
path: root/target-mips
diff options
context:
space:
mode:
Diffstat (limited to 'target-mips')
-rw-r--r--target-mips/op_helper.c252
1 files changed, 100 insertions, 152 deletions
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 52d687d337..fe1c9160d5 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -66,6 +66,58 @@ static void do_restore_state (void *pc_ptr)
}
#endif
+#if defined(CONFIG_USER_ONLY)
+#define HELPER_LD(name, insn, type) \
+static inline type do_##name(target_ulong addr, int mem_idx) \
+{ \
+ return (type) insn##_raw(addr); \
+}
+#else
+#define HELPER_LD(name, insn, type) \
+static inline type do_##name(target_ulong addr, int mem_idx) \
+{ \
+ switch (mem_idx) \
+ { \
+ case 0: return (type) insn##_kernel(addr); break; \
+ case 1: return (type) insn##_super(addr); break; \
+ default: \
+ case 2: return (type) insn##_user(addr); break; \
+ } \
+}
+#endif
+HELPER_LD(lbu, ldub, uint8_t)
+HELPER_LD(lw, ldl, int32_t)
+#ifdef TARGET_MIPS64
+HELPER_LD(ld, ldq, int64_t)
+#endif
+#undef HELPER_LD
+
+#if defined(CONFIG_USER_ONLY)
+#define HELPER_ST(name, insn, type) \
+static inline void do_##name(target_ulong addr, type val, int mem_idx) \
+{ \
+ insn##_raw(addr, val); \
+}
+#else
+#define HELPER_ST(name, insn, type) \
+static inline void do_##name(target_ulong addr, type val, int mem_idx) \
+{ \
+ switch (mem_idx) \
+ { \
+ case 0: insn##_kernel(addr, val); break; \
+ case 1: insn##_super(addr, val); break; \
+ default: \
+ case 2: insn##_user(addr, val); break; \
+ } \
+}
+#endif
+HELPER_ST(sb, stb, uint8_t)
+HELPER_ST(sw, stl, uint32_t)
+#ifdef TARGET_MIPS64
+HELPER_ST(sd, stq, uint64_t)
+#endif
+#undef HELPER_ST
+
target_ulong helper_clo (target_ulong arg1)
{
return clo32(arg1);
@@ -235,34 +287,21 @@ target_ulong helper_lwl(target_ulong arg1, target_ulong arg2, 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(arg2);
+ tmp = do_lbu(arg2, mem_idx);
arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
if (GET_LMASK(arg2) <= 2) {
- tmp = ldfun(GET_OFFSET(arg2, 1));
+ tmp = do_lbu(GET_OFFSET(arg2, 1), mem_idx);
arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
}
if (GET_LMASK(arg2) <= 1) {
- tmp = ldfun(GET_OFFSET(arg2, 2));
+ tmp = do_lbu(GET_OFFSET(arg2, 2), mem_idx);
arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
}
if (GET_LMASK(arg2) == 0) {
- tmp = ldfun(GET_OFFSET(arg2, 3));
+ tmp = do_lbu(GET_OFFSET(arg2, 3), mem_idx);
arg1 = (arg1 & 0xFFFFFF00) | tmp;
}
return (int32_t)arg1;
@@ -272,34 +311,21 @@ target_ulong helper_lwr(target_ulong arg1, target_ulong arg2, 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(arg2);
+ tmp = do_lbu(arg2, mem_idx);
arg1 = (arg1 & 0xFFFFFF00) | tmp;
if (GET_LMASK(arg2) >= 1) {
- tmp = ldfun(GET_OFFSET(arg2, -1));
+ tmp = do_lbu(GET_OFFSET(arg2, -1), mem_idx);
arg1 = (arg1 & 0xFFFF00FF) | (tmp << 8);
}
if (GET_LMASK(arg2) >= 2) {
- tmp = ldfun(GET_OFFSET(arg2, -2));
+ tmp = do_lbu(GET_OFFSET(arg2, -2), mem_idx);
arg1 = (arg1 & 0xFF00FFFF) | (tmp << 16);
}
if (GET_LMASK(arg2) == 3) {
- tmp = ldfun(GET_OFFSET(arg2, -3));
+ tmp = do_lbu(GET_OFFSET(arg2, -3), mem_idx);
arg1 = (arg1 & 0x00FFFFFF) | (tmp << 24);
}
return (int32_t)arg1;
@@ -307,56 +333,30 @@ target_ulong helper_lwr(target_ulong arg1, target_ulong arg2, int mem_idx)
void helper_swl(target_ulong arg1, target_ulong arg2, 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(arg2, (uint8_t)(arg1 >> 24));
+ do_sb(arg2, (uint8_t)(arg1 >> 24), mem_idx);
if (GET_LMASK(arg2) <= 2)
- stfun(GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16));
+ do_sb(GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK(arg2) <= 1)
- stfun(GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8));
+ do_sb(GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK(arg2) == 0)
- stfun(GET_OFFSET(arg2, 3), (uint8_t)arg1);
+ do_sb(GET_OFFSET(arg2, 3), (uint8_t)arg1, mem_idx);
}
void helper_swr(target_ulong arg1, target_ulong arg2, 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(arg2, (uint8_t)arg1);
+ do_sb(arg2, (uint8_t)arg1, mem_idx);
if (GET_LMASK(arg2) >= 1)
- stfun(GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8));
+ do_sb(GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK(arg2) >= 2)
- stfun(GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16));
+ do_sb(GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK(arg2) == 3)
- stfun(GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24));
+ do_sb(GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
}
#if defined(TARGET_MIPS64)
@@ -373,54 +373,41 @@ target_ulong helper_ldl(target_ulong arg1, target_ulong arg2, int mem_idx)
{
uint64_t 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(arg2);
+ tmp = do_lbu(arg2, mem_idx);
arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
if (GET_LMASK64(arg2) <= 6) {
- tmp = ldfun(GET_OFFSET(arg2, 1));
+ tmp = do_lbu(GET_OFFSET(arg2, 1), mem_idx);
arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
}
if (GET_LMASK64(arg2) <= 5) {
- tmp = ldfun(GET_OFFSET(arg2, 2));
+ tmp = do_lbu(GET_OFFSET(arg2, 2), mem_idx);
arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
}
if (GET_LMASK64(arg2) <= 4) {
- tmp = ldfun(GET_OFFSET(arg2, 3));
+ tmp = do_lbu(GET_OFFSET(arg2, 3), mem_idx);
arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
}
if (GET_LMASK64(arg2) <= 3) {
- tmp = ldfun(GET_OFFSET(arg2, 4));
+ tmp = do_lbu(GET_OFFSET(arg2, 4), mem_idx);
arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
}
if (GET_LMASK64(arg2) <= 2) {
- tmp = ldfun(GET_OFFSET(arg2, 5));
+ tmp = do_lbu(GET_OFFSET(arg2, 5), mem_idx);
arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
}
if (GET_LMASK64(arg2) <= 1) {
- tmp = ldfun(GET_OFFSET(arg2, 6));
+ tmp = do_lbu(GET_OFFSET(arg2, 6), mem_idx);
arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
}
if (GET_LMASK64(arg2) == 0) {
- tmp = ldfun(GET_OFFSET(arg2, 7));
+ tmp = do_lbu(GET_OFFSET(arg2, 7), mem_idx);
arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
}
@@ -431,54 +418,41 @@ target_ulong helper_ldr(target_ulong arg1, target_ulong arg2, int mem_idx)
{
uint64_t 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(arg2);
+ tmp = do_lbu(arg2, mem_idx);
arg1 = (arg1 & 0xFFFFFFFFFFFFFF00ULL) | tmp;
if (GET_LMASK64(arg2) >= 1) {
- tmp = ldfun(GET_OFFSET(arg2, -1));
+ tmp = do_lbu(GET_OFFSET(arg2, -1), mem_idx);
arg1 = (arg1 & 0xFFFFFFFFFFFF00FFULL) | (tmp << 8);
}
if (GET_LMASK64(arg2) >= 2) {
- tmp = ldfun(GET_OFFSET(arg2, -2));
+ tmp = do_lbu(GET_OFFSET(arg2, -2), mem_idx);
arg1 = (arg1 & 0xFFFFFFFFFF00FFFFULL) | (tmp << 16);
}
if (GET_LMASK64(arg2) >= 3) {
- tmp = ldfun(GET_OFFSET(arg2, -3));
+ tmp = do_lbu(GET_OFFSET(arg2, -3), mem_idx);
arg1 = (arg1 & 0xFFFFFFFF00FFFFFFULL) | (tmp << 24);
}
if (GET_LMASK64(arg2) >= 4) {
- tmp = ldfun(GET_OFFSET(arg2, -4));
+ tmp = do_lbu(GET_OFFSET(arg2, -4), mem_idx);
arg1 = (arg1 & 0xFFFFFF00FFFFFFFFULL) | (tmp << 32);
}
if (GET_LMASK64(arg2) >= 5) {
- tmp = ldfun(GET_OFFSET(arg2, -5));
+ tmp = do_lbu(GET_OFFSET(arg2, -5), mem_idx);
arg1 = (arg1 & 0xFFFF00FFFFFFFFFFULL) | (tmp << 40);
}
if (GET_LMASK64(arg2) >= 6) {
- tmp = ldfun(GET_OFFSET(arg2, -6));
+ tmp = do_lbu(GET_OFFSET(arg2, -6), mem_idx);
arg1 = (arg1 & 0xFF00FFFFFFFFFFFFULL) | (tmp << 48);
}
if (GET_LMASK64(arg2) == 7) {
- tmp = ldfun(GET_OFFSET(arg2, -7));
+ tmp = do_lbu(GET_OFFSET(arg2, -7), mem_idx);
arg1 = (arg1 & 0x00FFFFFFFFFFFFFFULL) | (tmp << 56);
}
@@ -487,80 +461,54 @@ target_ulong helper_ldr(target_ulong arg1, target_ulong arg2, int mem_idx)
void helper_sdl(target_ulong arg1, target_ulong arg2, 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(arg2, (uint8_t)(arg1 >> 56));
+ do_sb(arg2, (uint8_t)(arg1 >> 56), mem_idx);
if (GET_LMASK64(arg2) <= 6)
- stfun(GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48));
+ do_sb(GET_OFFSET(arg2, 1), (uint8_t)(arg1 >> 48), mem_idx);
if (GET_LMASK64(arg2) <= 5)
- stfun(GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40));
+ do_sb(GET_OFFSET(arg2, 2), (uint8_t)(arg1 >> 40), mem_idx);
if (GET_LMASK64(arg2) <= 4)
- stfun(GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32));
+ do_sb(GET_OFFSET(arg2, 3), (uint8_t)(arg1 >> 32), mem_idx);
if (GET_LMASK64(arg2) <= 3)
- stfun(GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24));
+ do_sb(GET_OFFSET(arg2, 4), (uint8_t)(arg1 >> 24), mem_idx);
if (GET_LMASK64(arg2) <= 2)
- stfun(GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16));
+ do_sb(GET_OFFSET(arg2, 5), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK64(arg2) <= 1)
- stfun(GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8));
+ do_sb(GET_OFFSET(arg2, 6), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK64(arg2) <= 0)
- stfun(GET_OFFSET(arg2, 7), (uint8_t)arg1);
+ do_sb(GET_OFFSET(arg2, 7), (uint8_t)arg1, mem_idx);
}
void helper_sdr(target_ulong arg1, target_ulong arg2, 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(arg2, (uint8_t)arg1);
+ do_sb(arg2, (uint8_t)arg1, mem_idx);
if (GET_LMASK64(arg2) >= 1)
- stfun(GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8));
+ do_sb(GET_OFFSET(arg2, -1), (uint8_t)(arg1 >> 8), mem_idx);
if (GET_LMASK64(arg2) >= 2)
- stfun(GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16));
+ do_sb(GET_OFFSET(arg2, -2), (uint8_t)(arg1 >> 16), mem_idx);
if (GET_LMASK64(arg2) >= 3)
- stfun(GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24));
+ do_sb(GET_OFFSET(arg2, -3), (uint8_t)(arg1 >> 24), mem_idx);
if (GET_LMASK64(arg2) >= 4)
- stfun(GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32));
+ do_sb(GET_OFFSET(arg2, -4), (uint8_t)(arg1 >> 32), mem_idx);
if (GET_LMASK64(arg2) >= 5)
- stfun(GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40));
+ do_sb(GET_OFFSET(arg2, -5), (uint8_t)(arg1 >> 40), mem_idx);
if (GET_LMASK64(arg2) >= 6)
- stfun(GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48));
+ do_sb(GET_OFFSET(arg2, -6), (uint8_t)(arg1 >> 48), mem_idx);
if (GET_LMASK64(arg2) == 7)
- stfun(GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56));
+ do_sb(GET_OFFSET(arg2, -7), (uint8_t)(arg1 >> 56), mem_idx);
}
#endif /* TARGET_MIPS64 */