[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 2/9] target-mips: Prepare loads/stores for EVA
From: |
James Hogan |
Subject: |
[Qemu-devel] [PATCH 2/9] target-mips: Prepare loads/stores for EVA |
Date: |
Tue, 6 Sep 2016 12:03:37 +0100 |
EVA load and store instructions access the user mode address map, so
they need to use mem_idx of MIPS_HFLAG_UM. Update the various utility
functions to allow mem_idx to be more easily overridden from the
decoding logic.
Specifically we add a mem_idx argument to the op_ld/st_* helpers used
for atomics, and a mem_idx local variable to gen_ld(), gen_st(), and
gen_st_cond().
Signed-off-by: James Hogan <address@hidden>
Cc: Leon Alrae <address@hidden>
Cc: Aurelien Jarno <address@hidden>
---
target-mips/translate.c | 77 ++++++++++++++++++++++--------------------
1 file changed, 42 insertions(+), 35 deletions(-)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index e224c2f09af4..df2befbd5294 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -2028,7 +2028,8 @@ FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
/* load/store instructions. */
#ifdef CONFIG_USER_ONLY
#define OP_LD_ATOMIC(insn,fname) \
-static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
+ DisasContext *ctx) \
{ \
TCGv t0 = tcg_temp_new(); \
tcg_gen_mov_tl(t0, arg1); \
@@ -2039,9 +2040,10 @@ static inline void op_ld_##insn(TCGv ret, TCGv arg1,
DisasContext *ctx) \
}
#else
#define OP_LD_ATOMIC(insn,fname) \
-static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
+static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx, \
+ DisasContext *ctx) \
{ \
- gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx); \
+ gen_helper_1e1i(insn, ret, arg1, mem_idx); \
}
#endif
OP_LD_ATOMIC(ll,ld32s);
@@ -2052,7 +2054,8 @@ OP_LD_ATOMIC(lld,ld64);
#ifdef CONFIG_USER_ONLY
#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext
*ctx) \
+static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
+ DisasContext *ctx) \
{ \
TCGv t0 = tcg_temp_new(); \
TCGLabel *l1 = gen_new_label(); \
@@ -2076,10 +2079,11 @@ static inline void op_st_##insn(TCGv arg1, TCGv arg2,
int rt, DisasContext *ctx)
}
#else
#define OP_ST_ATOMIC(insn,fname,ldname,almask) \
-static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext
*ctx) \
+static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx, \
+ DisasContext *ctx) \
{ \
TCGv t0 = tcg_temp_new(); \
- gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx); \
+ gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx); \
gen_store_gpr(t0, rt); \
tcg_temp_free(t0); \
}
@@ -2122,6 +2126,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
int rt, int base, int16_t offset)
{
TCGv t0, t1, t2;
+ int mem_idx = ctx->mem_idx;
if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
/* Loongson CPU uses a load to zero register for prefetch.
@@ -2136,32 +2141,32 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
switch (opc) {
#if defined(TARGET_MIPS64)
case OPC_LWU:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL |
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
ctx->default_tcg_memop_mask);
gen_store_gpr(t0, rt);
break;
case OPC_LD:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
ctx->default_tcg_memop_mask);
gen_store_gpr(t0, rt);
break;
case OPC_LLD:
case R6_OPC_LLD:
- op_ld_lld(t0, t0, ctx);
+ op_ld_lld(t0, t0, mem_idx, ctx);
gen_store_gpr(t0, rt);
break;
case OPC_LDL:
t1 = tcg_temp_new();
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 7);
#ifndef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 7);
#endif
tcg_gen_shli_tl(t1, t1, 3);
tcg_gen_andi_tl(t0, t0, ~7);
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
tcg_gen_shl_tl(t0, t0, t1);
t2 = tcg_const_tl(-1);
tcg_gen_shl_tl(t2, t2, t1);
@@ -2176,14 +2181,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
t1 = tcg_temp_new();
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 7);
#ifdef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 7);
#endif
tcg_gen_shli_tl(t1, t1, 3);
tcg_gen_andi_tl(t0, t0, ~7);
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
tcg_gen_shr_tl(t0, t0, t1);
tcg_gen_xori_tl(t1, t1, 63);
t2 = tcg_const_tl(0xfffffffffffffffeull);
@@ -2199,7 +2204,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
t1 = tcg_const_tl(pc_relative_pc(ctx));
gen_op_addr_add(ctx, t0, t0, t1);
tcg_temp_free(t1);
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
gen_store_gpr(t0, rt);
break;
#endif
@@ -2207,44 +2212,44 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
t1 = tcg_const_tl(pc_relative_pc(ctx));
gen_op_addr_add(ctx, t0, t0, t1);
tcg_temp_free(t1);
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
gen_store_gpr(t0, rt);
break;
case OPC_LW:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
ctx->default_tcg_memop_mask);
gen_store_gpr(t0, rt);
break;
case OPC_LH:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
ctx->default_tcg_memop_mask);
gen_store_gpr(t0, rt);
break;
case OPC_LHU:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUW |
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
ctx->default_tcg_memop_mask);
gen_store_gpr(t0, rt);
break;
case OPC_LB:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
gen_store_gpr(t0, rt);
break;
case OPC_LBU:
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
gen_store_gpr(t0, rt);
break;
case OPC_LWL:
t1 = tcg_temp_new();
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 3);
#ifndef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 3);
#endif
tcg_gen_shli_tl(t1, t1, 3);
tcg_gen_andi_tl(t0, t0, ~3);
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
tcg_gen_shl_tl(t0, t0, t1);
t2 = tcg_const_tl(-1);
tcg_gen_shl_tl(t2, t2, t1);
@@ -2260,14 +2265,14 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
t1 = tcg_temp_new();
/* Do a byte access to possibly trigger a page
fault with the unaligned address. */
- tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
+ tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
tcg_gen_andi_tl(t1, t0, 3);
#ifdef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 3);
#endif
tcg_gen_shli_tl(t1, t1, 3);
tcg_gen_andi_tl(t0, t0, ~3);
- tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
+ tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
tcg_gen_shr_tl(t0, t0, t1);
tcg_gen_xori_tl(t1, t1, 31);
t2 = tcg_const_tl(0xfffffffeull);
@@ -2282,7 +2287,7 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break;
case OPC_LL:
case R6_OPC_LL:
- op_ld_ll(t0, t0, ctx);
+ op_ld_ll(t0, t0, mem_idx, ctx);
gen_store_gpr(t0, rt);
break;
}
@@ -2295,38 +2300,39 @@ static void gen_st (DisasContext *ctx, uint32_t opc,
int rt,
{
TCGv t0 = tcg_temp_new();
TCGv t1 = tcg_temp_new();
+ int mem_idx = ctx->mem_idx;
gen_base_offset_addr(ctx, t0, base, offset);
gen_load_gpr(t1, rt);
switch (opc) {
#if defined(TARGET_MIPS64)
case OPC_SD:
- tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
ctx->default_tcg_memop_mask);
break;
case OPC_SDL:
- gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
+ gen_helper_0e2i(sdl, t1, t0, mem_idx);
break;
case OPC_SDR:
- gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
+ gen_helper_0e2i(sdr, t1, t0, mem_idx);
break;
#endif
case OPC_SW:
- tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
ctx->default_tcg_memop_mask);
break;
case OPC_SH:
- tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
ctx->default_tcg_memop_mask);
break;
case OPC_SB:
- tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_8);
+ tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
break;
case OPC_SWL:
- gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
+ gen_helper_0e2i(swl, t1, t0, mem_idx);
break;
case OPC_SWR:
- gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
+ gen_helper_0e2i(swr, t1, t0, mem_idx);
break;
}
tcg_temp_free(t0);
@@ -2339,6 +2345,7 @@ static void gen_st_cond (DisasContext *ctx, uint32_t opc,
int rt,
int base, int16_t offset)
{
TCGv t0, t1;
+ int mem_idx = ctx->mem_idx;
#ifdef CONFIG_USER_ONLY
t0 = tcg_temp_local_new();
@@ -2353,12 +2360,12 @@ static void gen_st_cond (DisasContext *ctx, uint32_t
opc, int rt,
#if defined(TARGET_MIPS64)
case OPC_SCD:
case R6_OPC_SCD:
- op_st_scd(t1, t0, rt, ctx);
+ op_st_scd(t1, t0, rt, mem_idx, ctx);
break;
#endif
case OPC_SC:
case R6_OPC_SC:
- op_st_sc(t1, t0, rt, ctx);
+ op_st_sc(t1, t0, rt, mem_idx, ctx);
break;
}
tcg_temp_free(t1);
--
git-series 0.8.10
- [Qemu-devel] [PATCH 0/9] target-mips: Add Enhanced Virtual Addressing (EVA) support, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 5/9] target-mips: Abstract mmu_idx from hflags, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 4/9] target-mips: Check memory permissions with mem_idx, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 1/9] target-mips: Add CP0_Ebase.WG (write gate) support, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 6/9] target-mips: Add an MMU mode for ERL, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 2/9] target-mips: Prepare loads/stores for EVA,
James Hogan <=
- [Qemu-devel] [PATCH 7/9] target-mips: Add segmentation control registers, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 9/9] target-mips: Add EVA support to P5600, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 8/9] target-mips: Implement segmentation control, James Hogan, 2016/09/06
- [Qemu-devel] [PATCH 3/9] target-mips: Decode EVA load & store instructions, James Hogan, 2016/09/06
- Re: [Qemu-devel] [PATCH 0/9] target-mips: Add Enhanced Virtual Addressing (EVA) support, no-reply, 2016/09/06