target/mips: Fix MSA instructions LD.<B|H|W|D> on big endian host
Fix the case when the host is a big endian machine, and change the approach toward LD.<B|H|W|D> instruction helpers. Signed-off-by: Mateja Marjanovic <mateja.marjanovic@rt-rk.com> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com> Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com> Message-Id: <1554212605-16457-2-git-send-email-mateja.marjanovic@rt-rk.com>
This commit is contained in:
parent
cf122bf8d2
commit
83be6b5412
@ -4356,31 +4356,179 @@ FOP_CONDN_S(sne, (float32_lt(fst1, fst0, &env->active_fpu.fp_status)
|
||||
#define MEMOP_IDX(DF)
|
||||
#endif
|
||||
|
||||
#define MSA_LD_DF(DF, TYPE, LD_INSN, ...) \
|
||||
void helper_msa_ld_ ## TYPE(CPUMIPSState *env, uint32_t wd, \
|
||||
target_ulong addr) \
|
||||
{ \
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr); \
|
||||
wr_t wx; \
|
||||
int i; \
|
||||
MEMOP_IDX(DF) \
|
||||
for (i = 0; i < DF_ELEMENTS(DF); i++) { \
|
||||
wx.TYPE[i] = LD_INSN(env, addr + (i << DF), ##__VA_ARGS__); \
|
||||
} \
|
||||
memcpy(pwd, &wx, sizeof(wr_t)); \
|
||||
void helper_msa_ld_b(CPUMIPSState *env, uint32_t wd,
|
||||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
MEMOP_IDX(DF_BYTE)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#if !defined(HOST_WORDS_BIGENDIAN)
|
||||
pwd->b[0] = helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[1] = helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[2] = helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[3] = helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[4] = helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[5] = helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[6] = helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[7] = helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[8] = helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[9] = helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[10] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[11] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[12] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[13] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[14] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[15] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
|
||||
#else
|
||||
pwd->b[0] = helper_ret_ldub_mmu(env, addr + (7 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[1] = helper_ret_ldub_mmu(env, addr + (6 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[2] = helper_ret_ldub_mmu(env, addr + (5 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[3] = helper_ret_ldub_mmu(env, addr + (4 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[4] = helper_ret_ldub_mmu(env, addr + (3 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[5] = helper_ret_ldub_mmu(env, addr + (2 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[6] = helper_ret_ldub_mmu(env, addr + (1 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[7] = helper_ret_ldub_mmu(env, addr + (0 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[8] = helper_ret_ldub_mmu(env, addr + (15 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[9] = helper_ret_ldub_mmu(env, addr + (14 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[10] = helper_ret_ldub_mmu(env, addr + (13 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[11] = helper_ret_ldub_mmu(env, addr + (12 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[12] = helper_ret_ldub_mmu(env, addr + (11 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[13] = helper_ret_ldub_mmu(env, addr + (10 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[14] = helper_ret_ldub_mmu(env, addr + (9 << DF_BYTE), oi, GETPC());
|
||||
pwd->b[15] = helper_ret_ldub_mmu(env, addr + (8 << DF_BYTE), oi, GETPC());
|
||||
#endif
|
||||
#else
|
||||
#if !defined(HOST_WORDS_BIGENDIAN)
|
||||
pwd->b[0] = cpu_ldub_data(env, addr + (0 << DF_BYTE));
|
||||
pwd->b[1] = cpu_ldub_data(env, addr + (1 << DF_BYTE));
|
||||
pwd->b[2] = cpu_ldub_data(env, addr + (2 << DF_BYTE));
|
||||
pwd->b[3] = cpu_ldub_data(env, addr + (3 << DF_BYTE));
|
||||
pwd->b[4] = cpu_ldub_data(env, addr + (4 << DF_BYTE));
|
||||
pwd->b[5] = cpu_ldub_data(env, addr + (5 << DF_BYTE));
|
||||
pwd->b[6] = cpu_ldub_data(env, addr + (6 << DF_BYTE));
|
||||
pwd->b[7] = cpu_ldub_data(env, addr + (7 << DF_BYTE));
|
||||
pwd->b[8] = cpu_ldub_data(env, addr + (8 << DF_BYTE));
|
||||
pwd->b[9] = cpu_ldub_data(env, addr + (9 << DF_BYTE));
|
||||
pwd->b[10] = cpu_ldub_data(env, addr + (10 << DF_BYTE));
|
||||
pwd->b[11] = cpu_ldub_data(env, addr + (11 << DF_BYTE));
|
||||
pwd->b[12] = cpu_ldub_data(env, addr + (12 << DF_BYTE));
|
||||
pwd->b[13] = cpu_ldub_data(env, addr + (13 << DF_BYTE));
|
||||
pwd->b[14] = cpu_ldub_data(env, addr + (14 << DF_BYTE));
|
||||
pwd->b[15] = cpu_ldub_data(env, addr + (15 << DF_BYTE));
|
||||
#else
|
||||
pwd->b[0] = cpu_ldub_data(env, addr + (7 << DF_BYTE));
|
||||
pwd->b[1] = cpu_ldub_data(env, addr + (6 << DF_BYTE));
|
||||
pwd->b[2] = cpu_ldub_data(env, addr + (5 << DF_BYTE));
|
||||
pwd->b[3] = cpu_ldub_data(env, addr + (4 << DF_BYTE));
|
||||
pwd->b[4] = cpu_ldub_data(env, addr + (3 << DF_BYTE));
|
||||
pwd->b[5] = cpu_ldub_data(env, addr + (2 << DF_BYTE));
|
||||
pwd->b[6] = cpu_ldub_data(env, addr + (1 << DF_BYTE));
|
||||
pwd->b[7] = cpu_ldub_data(env, addr + (0 << DF_BYTE));
|
||||
pwd->b[8] = cpu_ldub_data(env, addr + (15 << DF_BYTE));
|
||||
pwd->b[9] = cpu_ldub_data(env, addr + (14 << DF_BYTE));
|
||||
pwd->b[10] = cpu_ldub_data(env, addr + (13 << DF_BYTE));
|
||||
pwd->b[11] = cpu_ldub_data(env, addr + (12 << DF_BYTE));
|
||||
pwd->b[12] = cpu_ldub_data(env, addr + (11 << DF_BYTE));
|
||||
pwd->b[13] = cpu_ldub_data(env, addr + (10 << DF_BYTE));
|
||||
pwd->b[14] = cpu_ldub_data(env, addr + (9 << DF_BYTE));
|
||||
pwd->b[15] = cpu_ldub_data(env, addr + (8 << DF_BYTE));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void helper_msa_ld_h(CPUMIPSState *env, uint32_t wd,
|
||||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
MEMOP_IDX(DF_HALF)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
MSA_LD_DF(DF_BYTE, b, helper_ret_ldub_mmu, oi, GETPC())
|
||||
MSA_LD_DF(DF_HALF, h, helper_ret_lduw_mmu, oi, GETPC())
|
||||
MSA_LD_DF(DF_WORD, w, helper_ret_ldul_mmu, oi, GETPC())
|
||||
MSA_LD_DF(DF_DOUBLE, d, helper_ret_ldq_mmu, oi, GETPC())
|
||||
#if !defined(HOST_WORDS_BIGENDIAN)
|
||||
pwd->h[0] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC());
|
||||
pwd->h[1] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC());
|
||||
pwd->h[2] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC());
|
||||
pwd->h[3] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC());
|
||||
pwd->h[4] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC());
|
||||
pwd->h[5] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC());
|
||||
pwd->h[6] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC());
|
||||
pwd->h[7] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC());
|
||||
#else
|
||||
MSA_LD_DF(DF_BYTE, b, cpu_ldub_data)
|
||||
MSA_LD_DF(DF_HALF, h, cpu_lduw_data)
|
||||
MSA_LD_DF(DF_WORD, w, cpu_ldl_data)
|
||||
MSA_LD_DF(DF_DOUBLE, d, cpu_ldq_data)
|
||||
pwd->h[0] = helper_ret_lduw_mmu(env, addr + (3 << DF_HALF), oi, GETPC());
|
||||
pwd->h[1] = helper_ret_lduw_mmu(env, addr + (2 << DF_HALF), oi, GETPC());
|
||||
pwd->h[2] = helper_ret_lduw_mmu(env, addr + (1 << DF_HALF), oi, GETPC());
|
||||
pwd->h[3] = helper_ret_lduw_mmu(env, addr + (0 << DF_HALF), oi, GETPC());
|
||||
pwd->h[4] = helper_ret_lduw_mmu(env, addr + (7 << DF_HALF), oi, GETPC());
|
||||
pwd->h[5] = helper_ret_lduw_mmu(env, addr + (6 << DF_HALF), oi, GETPC());
|
||||
pwd->h[6] = helper_ret_lduw_mmu(env, addr + (5 << DF_HALF), oi, GETPC());
|
||||
pwd->h[7] = helper_ret_lduw_mmu(env, addr + (4 << DF_HALF), oi, GETPC());
|
||||
#endif
|
||||
#else
|
||||
#if !defined(HOST_WORDS_BIGENDIAN)
|
||||
pwd->h[0] = cpu_lduw_data(env, addr + (0 << DF_HALF));
|
||||
pwd->h[1] = cpu_lduw_data(env, addr + (1 << DF_HALF));
|
||||
pwd->h[2] = cpu_lduw_data(env, addr + (2 << DF_HALF));
|
||||
pwd->h[3] = cpu_lduw_data(env, addr + (3 << DF_HALF));
|
||||
pwd->h[4] = cpu_lduw_data(env, addr + (4 << DF_HALF));
|
||||
pwd->h[5] = cpu_lduw_data(env, addr + (5 << DF_HALF));
|
||||
pwd->h[6] = cpu_lduw_data(env, addr + (6 << DF_HALF));
|
||||
pwd->h[7] = cpu_lduw_data(env, addr + (7 << DF_HALF));
|
||||
#else
|
||||
pwd->h[0] = cpu_lduw_data(env, addr + (3 << DF_HALF));
|
||||
pwd->h[1] = cpu_lduw_data(env, addr + (2 << DF_HALF));
|
||||
pwd->h[2] = cpu_lduw_data(env, addr + (1 << DF_HALF));
|
||||
pwd->h[3] = cpu_lduw_data(env, addr + (0 << DF_HALF));
|
||||
pwd->h[4] = cpu_lduw_data(env, addr + (7 << DF_HALF));
|
||||
pwd->h[5] = cpu_lduw_data(env, addr + (6 << DF_HALF));
|
||||
pwd->h[6] = cpu_lduw_data(env, addr + (5 << DF_HALF));
|
||||
pwd->h[7] = cpu_lduw_data(env, addr + (4 << DF_HALF));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void helper_msa_ld_w(CPUMIPSState *env, uint32_t wd,
|
||||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
MEMOP_IDX(DF_WORD)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
#if !defined(HOST_WORDS_BIGENDIAN)
|
||||
pwd->w[0] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC());
|
||||
pwd->w[1] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC());
|
||||
pwd->w[2] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC());
|
||||
pwd->w[3] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC());
|
||||
#else
|
||||
pwd->w[0] = helper_ret_ldul_mmu(env, addr + (1 << DF_WORD), oi, GETPC());
|
||||
pwd->w[1] = helper_ret_ldul_mmu(env, addr + (0 << DF_WORD), oi, GETPC());
|
||||
pwd->w[2] = helper_ret_ldul_mmu(env, addr + (3 << DF_WORD), oi, GETPC());
|
||||
pwd->w[3] = helper_ret_ldul_mmu(env, addr + (2 << DF_WORD), oi, GETPC());
|
||||
#endif
|
||||
#else
|
||||
#if !defined(HOST_WORDS_BIGENDIAN)
|
||||
pwd->w[0] = cpu_ldl_data(env, addr + (0 << DF_WORD));
|
||||
pwd->w[1] = cpu_ldl_data(env, addr + (1 << DF_WORD));
|
||||
pwd->w[2] = cpu_ldl_data(env, addr + (2 << DF_WORD));
|
||||
pwd->w[3] = cpu_ldl_data(env, addr + (3 << DF_WORD));
|
||||
#else
|
||||
pwd->w[0] = cpu_ldl_data(env, addr + (1 << DF_WORD));
|
||||
pwd->w[1] = cpu_ldl_data(env, addr + (0 << DF_WORD));
|
||||
pwd->w[2] = cpu_ldl_data(env, addr + (3 << DF_WORD));
|
||||
pwd->w[3] = cpu_ldl_data(env, addr + (2 << DF_WORD));
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void helper_msa_ld_d(CPUMIPSState *env, uint32_t wd,
|
||||
target_ulong addr)
|
||||
{
|
||||
wr_t *pwd = &(env->active_fpu.fpr[wd].wr);
|
||||
MEMOP_IDX(DF_DOUBLE)
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
pwd->d[0] = helper_ret_ldq_mmu(env, addr + (0 << DF_DOUBLE), oi, GETPC());
|
||||
pwd->d[1] = helper_ret_ldq_mmu(env, addr + (1 << DF_DOUBLE), oi, GETPC());
|
||||
#else
|
||||
pwd->d[0] = cpu_ldq_data(env, addr + (0 << DF_DOUBLE));
|
||||
pwd->d[1] = cpu_ldq_data(env, addr + (1 << DF_DOUBLE));
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MSA_PAGESPAN(x) \
|
||||
((((x) & ~TARGET_PAGE_MASK) + MSA_WRLEN/8 - 1) >= TARGET_PAGE_SIZE)
|
||||
|
Loading…
Reference in New Issue
Block a user