mirror of https://github.com/xemu-project/xemu.git
Cleanup alpha memory ops prior to prctl PR_SET_UNALIGN
-----BEGIN PGP SIGNATURE----- iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmFnGJIdHHJpY2hhcmQu aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV8I2Qf/UOROm5TIvhKeZN8H t6zJCl+hcbCa9nsYHq38b+6+BNF2IAqMM+OJfGLfpSM+0QJJOsw8647qJUx4WVB6 VrOJ3HqRZnqk2rG1VUsnUjcg9r/C5VTFV1KE69d+M0WdW1lxw/ro3O0MW4trms6o X/TI1vI1lXF/MT4higfERYZTK6bRMpYllbkHYVq0u1lFSNvT+vfK9P/v4vPV5tNX GQfyvSDkGhxKYI/ZKosJflLBO3W67LubqVQUb8f+skowO2DLwnfqC0sDKd+q/Ar0 plF8vckI6sPUi1YxGwYAxxb/9lqTnshSH7BGBobLZWo/4vPJol7BHvisj82rmRXO C5iY7g== =3V2o -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-axp-20211013' into staging Cleanup alpha memory ops prior to prctl PR_SET_UNALIGN # gpg: Signature made Wed 13 Oct 2021 10:34:10 AM PDT # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate] * remotes/rth/tags/pull-axp-20211013: target/alpha: Reorg integer memory operations target/alpha: Reorg fp memory operations Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
commit
984b2b5049
|
@ -267,51 +267,51 @@ static inline DisasJumpType gen_invalid(DisasContext *ctx)
|
||||||
return gen_excp(ctx, EXCP_OPCDEC, 0);
|
return gen_excp(ctx, EXCP_OPCDEC, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_ldf(TCGv t0, TCGv t1, int flags)
|
static void gen_ldf(DisasContext *ctx, TCGv dest, TCGv addr)
|
||||||
{
|
{
|
||||||
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
||||||
tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
|
tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL);
|
||||||
gen_helper_memory_to_f(t0, tmp32);
|
gen_helper_memory_to_f(dest, tmp32);
|
||||||
tcg_temp_free_i32(tmp32);
|
tcg_temp_free_i32(tmp32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_ldg(TCGv t0, TCGv t1, int flags)
|
static void gen_ldg(DisasContext *ctx, TCGv dest, TCGv addr)
|
||||||
{
|
{
|
||||||
TCGv tmp = tcg_temp_new();
|
TCGv tmp = tcg_temp_new();
|
||||||
tcg_gen_qemu_ld_i64(tmp, t1, flags, MO_LEQ);
|
tcg_gen_qemu_ld_i64(tmp, addr, ctx->mem_idx, MO_LEQ);
|
||||||
gen_helper_memory_to_g(t0, tmp);
|
gen_helper_memory_to_g(dest, tmp);
|
||||||
tcg_temp_free(tmp);
|
tcg_temp_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_lds(TCGv t0, TCGv t1, int flags)
|
static void gen_lds(DisasContext *ctx, TCGv dest, TCGv addr)
|
||||||
{
|
{
|
||||||
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
||||||
tcg_gen_qemu_ld_i32(tmp32, t1, flags, MO_LEUL);
|
tcg_gen_qemu_ld_i32(tmp32, addr, ctx->mem_idx, MO_LEUL);
|
||||||
gen_helper_memory_to_s(t0, tmp32);
|
gen_helper_memory_to_s(dest, tmp32);
|
||||||
tcg_temp_free_i32(tmp32);
|
tcg_temp_free_i32(tmp32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_ldl_l(TCGv t0, TCGv t1, int flags)
|
static void gen_ldt(DisasContext *ctx, TCGv dest, TCGv addr)
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LESL);
|
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, MO_LEQ);
|
||||||
tcg_gen_mov_i64(cpu_lock_addr, t1);
|
|
||||||
tcg_gen_mov_i64(cpu_lock_value, t0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_ldq_l(TCGv t0, TCGv t1, int flags)
|
static void gen_load_fp(DisasContext *ctx, int ra, int rb, int32_t disp16,
|
||||||
|
void (*func)(DisasContext *, TCGv, TCGv))
|
||||||
{
|
{
|
||||||
tcg_gen_qemu_ld_i64(t0, t1, flags, MO_LEQ);
|
/* Loads to $f31 are prefetches, which we can treat as nops. */
|
||||||
tcg_gen_mov_i64(cpu_lock_addr, t1);
|
if (likely(ra != 31)) {
|
||||||
tcg_gen_mov_i64(cpu_lock_value, t0);
|
TCGv addr = tcg_temp_new();
|
||||||
|
tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
|
||||||
|
func(ctx, cpu_fir[ra], addr);
|
||||||
|
tcg_temp_free(addr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_load_mem(DisasContext *ctx,
|
static void gen_load_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
|
||||||
void (*tcg_gen_qemu_load)(TCGv t0, TCGv t1,
|
MemOp op, bool clear, bool locked)
|
||||||
int flags),
|
|
||||||
int ra, int rb, int32_t disp16, bool fp,
|
|
||||||
bool clear)
|
|
||||||
{
|
{
|
||||||
TCGv tmp, addr, va;
|
TCGv addr, dest;
|
||||||
|
|
||||||
/* LDQ_U with ra $31 is UNOP. Other various loads are forms of
|
/* LDQ_U with ra $31 is UNOP. Other various loads are forms of
|
||||||
prefetches, which we can treat as nops. No worries about
|
prefetches, which we can treat as nops. No worries about
|
||||||
|
@ -320,72 +320,75 @@ static inline void gen_load_mem(DisasContext *ctx,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = tcg_temp_new();
|
addr = tcg_temp_new();
|
||||||
addr = load_gpr(ctx, rb);
|
tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
|
||||||
|
|
||||||
if (disp16) {
|
|
||||||
tcg_gen_addi_i64(tmp, addr, disp16);
|
|
||||||
addr = tmp;
|
|
||||||
}
|
|
||||||
if (clear) {
|
if (clear) {
|
||||||
tcg_gen_andi_i64(tmp, addr, ~0x7);
|
tcg_gen_andi_i64(addr, addr, ~0x7);
|
||||||
addr = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
va = (fp ? cpu_fir[ra] : ctx->ir[ra]);
|
dest = ctx->ir[ra];
|
||||||
tcg_gen_qemu_load(va, addr, ctx->mem_idx);
|
tcg_gen_qemu_ld_i64(dest, addr, ctx->mem_idx, op);
|
||||||
|
|
||||||
tcg_temp_free(tmp);
|
if (locked) {
|
||||||
|
tcg_gen_mov_i64(cpu_lock_addr, addr);
|
||||||
|
tcg_gen_mov_i64(cpu_lock_value, dest);
|
||||||
|
}
|
||||||
|
tcg_temp_free(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_stf(TCGv t0, TCGv t1, int flags)
|
static void gen_stf(DisasContext *ctx, TCGv src, TCGv addr)
|
||||||
{
|
{
|
||||||
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
||||||
gen_helper_f_to_memory(tmp32, t0);
|
gen_helper_f_to_memory(tmp32, addr);
|
||||||
tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
|
tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL);
|
||||||
tcg_temp_free_i32(tmp32);
|
tcg_temp_free_i32(tmp32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_stg(TCGv t0, TCGv t1, int flags)
|
static void gen_stg(DisasContext *ctx, TCGv src, TCGv addr)
|
||||||
{
|
{
|
||||||
TCGv tmp = tcg_temp_new();
|
TCGv tmp = tcg_temp_new();
|
||||||
gen_helper_g_to_memory(tmp, t0);
|
gen_helper_g_to_memory(tmp, src);
|
||||||
tcg_gen_qemu_st_i64(tmp, t1, flags, MO_LEQ);
|
tcg_gen_qemu_st_i64(tmp, addr, ctx->mem_idx, MO_LEQ);
|
||||||
tcg_temp_free(tmp);
|
tcg_temp_free(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_qemu_sts(TCGv t0, TCGv t1, int flags)
|
static void gen_sts(DisasContext *ctx, TCGv src, TCGv addr)
|
||||||
{
|
{
|
||||||
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
TCGv_i32 tmp32 = tcg_temp_new_i32();
|
||||||
gen_helper_s_to_memory(tmp32, t0);
|
gen_helper_s_to_memory(tmp32, src);
|
||||||
tcg_gen_qemu_st_i32(tmp32, t1, flags, MO_LEUL);
|
tcg_gen_qemu_st_i32(tmp32, addr, ctx->mem_idx, MO_LEUL);
|
||||||
tcg_temp_free_i32(tmp32);
|
tcg_temp_free_i32(tmp32);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_store_mem(DisasContext *ctx,
|
static void gen_stt(DisasContext *ctx, TCGv src, TCGv addr)
|
||||||
void (*tcg_gen_qemu_store)(TCGv t0, TCGv t1,
|
|
||||||
int flags),
|
|
||||||
int ra, int rb, int32_t disp16, bool fp,
|
|
||||||
bool clear)
|
|
||||||
{
|
{
|
||||||
TCGv tmp, addr, va;
|
tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, MO_LEQ);
|
||||||
|
}
|
||||||
|
|
||||||
tmp = tcg_temp_new();
|
static void gen_store_fp(DisasContext *ctx, int ra, int rb, int32_t disp16,
|
||||||
addr = load_gpr(ctx, rb);
|
void (*func)(DisasContext *, TCGv, TCGv))
|
||||||
|
{
|
||||||
|
TCGv addr = tcg_temp_new();
|
||||||
|
tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
|
||||||
|
func(ctx, load_fpr(ctx, ra), addr);
|
||||||
|
tcg_temp_free(addr);
|
||||||
|
}
|
||||||
|
|
||||||
if (disp16) {
|
static void gen_store_int(DisasContext *ctx, int ra, int rb, int32_t disp16,
|
||||||
tcg_gen_addi_i64(tmp, addr, disp16);
|
MemOp op, bool clear)
|
||||||
addr = tmp;
|
{
|
||||||
}
|
TCGv addr, src;
|
||||||
|
|
||||||
|
addr = tcg_temp_new();
|
||||||
|
tcg_gen_addi_i64(addr, load_gpr(ctx, rb), disp16);
|
||||||
if (clear) {
|
if (clear) {
|
||||||
tcg_gen_andi_i64(tmp, addr, ~0x7);
|
tcg_gen_andi_i64(addr, addr, ~0x7);
|
||||||
addr = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
va = (fp ? load_fpr(ctx, ra) : load_gpr(ctx, ra));
|
src = load_gpr(ctx, ra);
|
||||||
tcg_gen_qemu_store(va, addr, ctx->mem_idx);
|
tcg_gen_qemu_st_i64(src, addr, ctx->mem_idx, op);
|
||||||
|
|
||||||
tcg_temp_free(tmp);
|
tcg_temp_free(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb,
|
static DisasJumpType gen_store_conditional(DisasContext *ctx, int ra, int rb,
|
||||||
|
@ -1480,30 +1483,30 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
|
||||||
case 0x0A:
|
case 0x0A:
|
||||||
/* LDBU */
|
/* LDBU */
|
||||||
REQUIRE_AMASK(BWX);
|
REQUIRE_AMASK(BWX);
|
||||||
gen_load_mem(ctx, &tcg_gen_qemu_ld8u, ra, rb, disp16, 0, 0);
|
gen_load_int(ctx, ra, rb, disp16, MO_UB, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0B:
|
case 0x0B:
|
||||||
/* LDQ_U */
|
/* LDQ_U */
|
||||||
gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 1);
|
gen_load_int(ctx, ra, rb, disp16, MO_LEQ, 1, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0C:
|
case 0x0C:
|
||||||
/* LDWU */
|
/* LDWU */
|
||||||
REQUIRE_AMASK(BWX);
|
REQUIRE_AMASK(BWX);
|
||||||
gen_load_mem(ctx, &tcg_gen_qemu_ld16u, ra, rb, disp16, 0, 0);
|
gen_load_int(ctx, ra, rb, disp16, MO_LEUW, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0D:
|
case 0x0D:
|
||||||
/* STW */
|
/* STW */
|
||||||
REQUIRE_AMASK(BWX);
|
REQUIRE_AMASK(BWX);
|
||||||
gen_store_mem(ctx, &tcg_gen_qemu_st16, ra, rb, disp16, 0, 0);
|
gen_store_int(ctx, ra, rb, disp16, MO_LEUW, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0E:
|
case 0x0E:
|
||||||
/* STB */
|
/* STB */
|
||||||
REQUIRE_AMASK(BWX);
|
REQUIRE_AMASK(BWX);
|
||||||
gen_store_mem(ctx, &tcg_gen_qemu_st8, ra, rb, disp16, 0, 0);
|
gen_store_int(ctx, ra, rb, disp16, MO_UB, 0);
|
||||||
break;
|
break;
|
||||||
case 0x0F:
|
case 0x0F:
|
||||||
/* STQ_U */
|
/* STQ_U */
|
||||||
gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 1);
|
gen_store_int(ctx, ra, rb, disp16, MO_LEQ, 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10:
|
case 0x10:
|
||||||
|
@ -2458,11 +2461,15 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
|
||||||
break;
|
break;
|
||||||
case 0x2:
|
case 0x2:
|
||||||
/* Longword physical access with lock (hw_ldl_l/p) */
|
/* Longword physical access with lock (hw_ldl_l/p) */
|
||||||
gen_qemu_ldl_l(va, addr, MMU_PHYS_IDX);
|
tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LESL);
|
||||||
|
tcg_gen_mov_i64(cpu_lock_addr, addr);
|
||||||
|
tcg_gen_mov_i64(cpu_lock_value, va);
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
/* Quadword physical access with lock (hw_ldq_l/p) */
|
/* Quadword physical access with lock (hw_ldq_l/p) */
|
||||||
gen_qemu_ldq_l(va, addr, MMU_PHYS_IDX);
|
tcg_gen_qemu_ld_i64(va, addr, MMU_PHYS_IDX, MO_LEQ);
|
||||||
|
tcg_gen_mov_i64(cpu_lock_addr, addr);
|
||||||
|
tcg_gen_mov_i64(cpu_lock_value, va);
|
||||||
break;
|
break;
|
||||||
case 0x4:
|
case 0x4:
|
||||||
/* Longword virtual PTE fetch (hw_ldl/v) */
|
/* Longword virtual PTE fetch (hw_ldl/v) */
|
||||||
|
@ -2776,66 +2783,66 @@ static DisasJumpType translate_one(DisasContext *ctx, uint32_t insn)
|
||||||
case 0x20:
|
case 0x20:
|
||||||
/* LDF */
|
/* LDF */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_load_mem(ctx, &gen_qemu_ldf, ra, rb, disp16, 1, 0);
|
gen_load_fp(ctx, ra, rb, disp16, gen_ldf);
|
||||||
break;
|
break;
|
||||||
case 0x21:
|
case 0x21:
|
||||||
/* LDG */
|
/* LDG */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_load_mem(ctx, &gen_qemu_ldg, ra, rb, disp16, 1, 0);
|
gen_load_fp(ctx, ra, rb, disp16, gen_ldg);
|
||||||
break;
|
break;
|
||||||
case 0x22:
|
case 0x22:
|
||||||
/* LDS */
|
/* LDS */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_load_mem(ctx, &gen_qemu_lds, ra, rb, disp16, 1, 0);
|
gen_load_fp(ctx, ra, rb, disp16, gen_lds);
|
||||||
break;
|
break;
|
||||||
case 0x23:
|
case 0x23:
|
||||||
/* LDT */
|
/* LDT */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 1, 0);
|
gen_load_fp(ctx, ra, rb, disp16, gen_ldt);
|
||||||
break;
|
break;
|
||||||
case 0x24:
|
case 0x24:
|
||||||
/* STF */
|
/* STF */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_store_mem(ctx, &gen_qemu_stf, ra, rb, disp16, 1, 0);
|
gen_store_fp(ctx, ra, rb, disp16, gen_stf);
|
||||||
break;
|
break;
|
||||||
case 0x25:
|
case 0x25:
|
||||||
/* STG */
|
/* STG */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_store_mem(ctx, &gen_qemu_stg, ra, rb, disp16, 1, 0);
|
gen_store_fp(ctx, ra, rb, disp16, gen_stg);
|
||||||
break;
|
break;
|
||||||
case 0x26:
|
case 0x26:
|
||||||
/* STS */
|
/* STS */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_store_mem(ctx, &gen_qemu_sts, ra, rb, disp16, 1, 0);
|
gen_store_fp(ctx, ra, rb, disp16, gen_sts);
|
||||||
break;
|
break;
|
||||||
case 0x27:
|
case 0x27:
|
||||||
/* STT */
|
/* STT */
|
||||||
REQUIRE_FEN;
|
REQUIRE_FEN;
|
||||||
gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 1, 0);
|
gen_store_fp(ctx, ra, rb, disp16, gen_stt);
|
||||||
break;
|
break;
|
||||||
case 0x28:
|
case 0x28:
|
||||||
/* LDL */
|
/* LDL */
|
||||||
gen_load_mem(ctx, &tcg_gen_qemu_ld32s, ra, rb, disp16, 0, 0);
|
gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 0x29:
|
case 0x29:
|
||||||
/* LDQ */
|
/* LDQ */
|
||||||
gen_load_mem(ctx, &tcg_gen_qemu_ld64, ra, rb, disp16, 0, 0);
|
gen_load_int(ctx, ra, rb, disp16, MO_LEQ, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 0x2A:
|
case 0x2A:
|
||||||
/* LDL_L */
|
/* LDL_L */
|
||||||
gen_load_mem(ctx, &gen_qemu_ldl_l, ra, rb, disp16, 0, 0);
|
gen_load_int(ctx, ra, rb, disp16, MO_LESL, 0, 1);
|
||||||
break;
|
break;
|
||||||
case 0x2B:
|
case 0x2B:
|
||||||
/* LDQ_L */
|
/* LDQ_L */
|
||||||
gen_load_mem(ctx, &gen_qemu_ldq_l, ra, rb, disp16, 0, 0);
|
gen_load_int(ctx, ra, rb, disp16, MO_LEQ, 0, 1);
|
||||||
break;
|
break;
|
||||||
case 0x2C:
|
case 0x2C:
|
||||||
/* STL */
|
/* STL */
|
||||||
gen_store_mem(ctx, &tcg_gen_qemu_st32, ra, rb, disp16, 0, 0);
|
gen_store_int(ctx, ra, rb, disp16, MO_LEUL, 0);
|
||||||
break;
|
break;
|
||||||
case 0x2D:
|
case 0x2D:
|
||||||
/* STQ */
|
/* STQ */
|
||||||
gen_store_mem(ctx, &tcg_gen_qemu_st64, ra, rb, disp16, 0, 0);
|
gen_store_int(ctx, ra, rb, disp16, MO_LEQ, 0);
|
||||||
break;
|
break;
|
||||||
case 0x2E:
|
case 0x2E:
|
||||||
/* STL_C */
|
/* STL_C */
|
||||||
|
|
Loading…
Reference in New Issue