mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-09-09 00:07:57 -06:00
target-ppc: convert load/store multiple instructions to TCG
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5825 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
931ff27258
commit
ff4a62cd81
6 changed files with 78 additions and 142 deletions
|
@ -7,6 +7,9 @@ DEF_HELPER_3(tw, void, tl, tl, i32)
|
||||||
DEF_HELPER_3(td, void, tl, tl, i32)
|
DEF_HELPER_3(td, void, tl, tl, i32)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
DEF_HELPER_2(lmw, void, tl, i32)
|
||||||
|
DEF_HELPER_2(stmw, void, tl, i32)
|
||||||
|
|
||||||
DEF_HELPER_2(fcmpo, i32, i64, i64)
|
DEF_HELPER_2(fcmpo, i32, i64, i64)
|
||||||
DEF_HELPER_2(fcmpu, i32, i64, i64)
|
DEF_HELPER_2(fcmpu, i32, i64, i64)
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,69 @@ void ppc_store_dump_spr (int sprn, target_ulong val)
|
||||||
env->spr[sprn] = val;
|
env->spr[sprn] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Memory load and stores */
|
||||||
|
|
||||||
|
static always_inline target_ulong get_addr(target_ulong addr)
|
||||||
|
{
|
||||||
|
#if defined(TARGET_PPC64)
|
||||||
|
if (msr_sf)
|
||||||
|
return addr;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
return (uint32_t)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_lmw (target_ulong addr, uint32_t reg)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
#define ldfun ldl_raw
|
||||||
|
#else
|
||||||
|
int (*ldfun)(target_ulong);
|
||||||
|
|
||||||
|
switch (env->mmu_idx) {
|
||||||
|
default:
|
||||||
|
case 0: ldfun = ldl_user;
|
||||||
|
break;
|
||||||
|
case 1: ldfun = ldl_kernel;
|
||||||
|
break;
|
||||||
|
case 2: ldfun = ldl_hypv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (; reg < 32; reg++, addr += 4) {
|
||||||
|
if (msr_le)
|
||||||
|
env->gpr[reg] = bswap32(ldfun(get_addr(addr)));
|
||||||
|
else
|
||||||
|
env->gpr[reg] = ldfun(get_addr(addr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void helper_stmw (target_ulong addr, uint32_t reg)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_USER_ONLY
|
||||||
|
#define stfun stl_raw
|
||||||
|
#else
|
||||||
|
void (*stfun)(target_ulong, int);
|
||||||
|
|
||||||
|
switch (env->mmu_idx) {
|
||||||
|
default:
|
||||||
|
case 0: stfun = stl_user;
|
||||||
|
break;
|
||||||
|
case 1: stfun = stl_kernel;
|
||||||
|
break;
|
||||||
|
case 2: stfun = stl_hypv;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (; reg < 32; reg++, addr += 4) {
|
||||||
|
if (msr_le)
|
||||||
|
stfun(get_addr(addr), bswap32((uint32_t)env->gpr[reg]));
|
||||||
|
else
|
||||||
|
stfun(get_addr(addr), (uint32_t)env->gpr[reg]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Fixed point operations helpers */
|
/* Fixed point operations helpers */
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
|
|
|
@ -23,10 +23,6 @@
|
||||||
/* Memory load/store helpers */
|
/* Memory load/store helpers */
|
||||||
void glue(do_lsw, MEMSUFFIX) (int dst);
|
void glue(do_lsw, MEMSUFFIX) (int dst);
|
||||||
void glue(do_stsw, MEMSUFFIX) (int src);
|
void glue(do_stsw, MEMSUFFIX) (int src);
|
||||||
void glue(do_lmw, MEMSUFFIX) (int dst);
|
|
||||||
void glue(do_lmw_le, MEMSUFFIX) (int dst);
|
|
||||||
void glue(do_stmw, MEMSUFFIX) (int src);
|
|
||||||
void glue(do_stmw_le, MEMSUFFIX) (int src);
|
|
||||||
void glue(do_icbi, MEMSUFFIX) (void);
|
void glue(do_icbi, MEMSUFFIX) (void);
|
||||||
void glue(do_dcbz, MEMSUFFIX) (void);
|
void glue(do_dcbz, MEMSUFFIX) (void);
|
||||||
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
|
void glue(do_POWER_lscbx, MEMSUFFIX) (int dest, int ra, int rb);
|
||||||
|
@ -38,10 +34,6 @@ void glue(do_POWER2_stfq_le, MEMSUFFIX) (void);
|
||||||
#if defined(TARGET_PPC64)
|
#if defined(TARGET_PPC64)
|
||||||
void glue(do_lsw_64, MEMSUFFIX) (int dst);
|
void glue(do_lsw_64, MEMSUFFIX) (int dst);
|
||||||
void glue(do_stsw_64, MEMSUFFIX) (int src);
|
void glue(do_stsw_64, MEMSUFFIX) (int src);
|
||||||
void glue(do_lmw_64, MEMSUFFIX) (int dst);
|
|
||||||
void glue(do_lmw_le_64, MEMSUFFIX) (int dst);
|
|
||||||
void glue(do_stmw_64, MEMSUFFIX) (int src);
|
|
||||||
void glue(do_stmw_le_64, MEMSUFFIX) (int src);
|
|
||||||
void glue(do_icbi_64, MEMSUFFIX) (void);
|
void glue(do_icbi_64, MEMSUFFIX) (void);
|
||||||
void glue(do_dcbz_64, MEMSUFFIX) (void);
|
void glue(do_dcbz_64, MEMSUFFIX) (void);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,71 +20,6 @@
|
||||||
|
|
||||||
#include "op_mem_access.h"
|
#include "op_mem_access.h"
|
||||||
|
|
||||||
/* Multiple word / string load and store */
|
|
||||||
void glue(do_lmw, MEMSUFFIX) (int dst)
|
|
||||||
{
|
|
||||||
for (; dst < 32; dst++, T0 += 4) {
|
|
||||||
env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint32_t)T0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void glue(do_lmw_64, MEMSUFFIX) (int dst)
|
|
||||||
{
|
|
||||||
for (; dst < 32; dst++, T0 += 4) {
|
|
||||||
env->gpr[dst] = glue(ldu32, MEMSUFFIX)((uint64_t)T0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void glue(do_stmw, MEMSUFFIX) (int src)
|
|
||||||
{
|
|
||||||
for (; src < 32; src++, T0 += 4) {
|
|
||||||
glue(st32, MEMSUFFIX)((uint32_t)T0, env->gpr[src]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void glue(do_stmw_64, MEMSUFFIX) (int src)
|
|
||||||
{
|
|
||||||
for (; src < 32; src++, T0 += 4) {
|
|
||||||
glue(st32, MEMSUFFIX)((uint64_t)T0, env->gpr[src]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void glue(do_lmw_le, MEMSUFFIX) (int dst)
|
|
||||||
{
|
|
||||||
for (; dst < 32; dst++, T0 += 4) {
|
|
||||||
env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint32_t)T0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void glue(do_lmw_le_64, MEMSUFFIX) (int dst)
|
|
||||||
{
|
|
||||||
for (; dst < 32; dst++, T0 += 4) {
|
|
||||||
env->gpr[dst] = glue(ldu32r, MEMSUFFIX)((uint64_t)T0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void glue(do_stmw_le, MEMSUFFIX) (int src)
|
|
||||||
{
|
|
||||||
for (; src < 32; src++, T0 += 4) {
|
|
||||||
glue(st32r, MEMSUFFIX)((uint32_t)T0, env->gpr[src]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void glue(do_stmw_le_64, MEMSUFFIX) (int src)
|
|
||||||
{
|
|
||||||
for (; src < 32; src++, T0 += 4) {
|
|
||||||
glue(st32r, MEMSUFFIX)((uint64_t)T0, env->gpr[src]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void glue(do_lsw, MEMSUFFIX) (int dst)
|
void glue(do_lsw, MEMSUFFIX) (int dst)
|
||||||
{
|
{
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
|
@ -20,63 +20,6 @@
|
||||||
|
|
||||||
#include "op_mem_access.h"
|
#include "op_mem_access.h"
|
||||||
|
|
||||||
/*** Integer load and store multiple ***/
|
|
||||||
void OPPROTO glue(op_lmw, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_lmw, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO glue(op_lmw_64, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_lmw_64, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OPPROTO glue(op_lmw_le, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_lmw_le, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO glue(op_lmw_le_64, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_lmw_le_64, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OPPROTO glue(op_stmw, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_stmw, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO glue(op_stmw_64, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_stmw_64, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void OPPROTO glue(op_stmw_le, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_stmw_le, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(TARGET_PPC64)
|
|
||||||
void OPPROTO glue(op_stmw_le_64, MEMSUFFIX) (void)
|
|
||||||
{
|
|
||||||
glue(do_stmw_le_64, MEMSUFFIX)(PARAM1);
|
|
||||||
RETURN();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*** Integer load and store strings ***/
|
/*** Integer load and store strings ***/
|
||||||
void OPPROTO glue(op_lswi, MEMSUFFIX) (void)
|
void OPPROTO glue(op_lswi, MEMSUFFIX) (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -3092,30 +3092,30 @@ void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
|
||||||
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
|
GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
|
||||||
|
|
||||||
/*** Integer load and store multiple ***/
|
/*** Integer load and store multiple ***/
|
||||||
#define op_ldstm(name, reg) (*gen_op_##name[ctx->mem_idx])(reg)
|
|
||||||
static GenOpFunc1 *gen_op_lmw[NB_MEM_FUNCS] = {
|
|
||||||
GEN_MEM_FUNCS(lmw),
|
|
||||||
};
|
|
||||||
static GenOpFunc1 *gen_op_stmw[NB_MEM_FUNCS] = {
|
|
||||||
GEN_MEM_FUNCS(stmw),
|
|
||||||
};
|
|
||||||
|
|
||||||
/* lmw */
|
/* lmw */
|
||||||
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(lmw, 0x2E, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
|
TCGv t0 = tcg_temp_new();
|
||||||
|
TCGv_i32 t1 = tcg_const_i32(rD(ctx->opcode));
|
||||||
/* NIP cannot be restored if the memory exception comes from an helper */
|
/* NIP cannot be restored if the memory exception comes from an helper */
|
||||||
gen_update_nip(ctx, ctx->nip - 4);
|
gen_update_nip(ctx, ctx->nip - 4);
|
||||||
gen_addr_imm_index(cpu_T[0], ctx, 0);
|
gen_addr_imm_index(t0, ctx, 0);
|
||||||
op_ldstm(lmw, rD(ctx->opcode));
|
gen_helper_lmw(t0, t1);
|
||||||
|
tcg_temp_free(t0);
|
||||||
|
tcg_temp_free_i32(t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* stmw */
|
/* stmw */
|
||||||
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
GEN_HANDLER(stmw, 0x2F, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
|
||||||
{
|
{
|
||||||
|
TCGv t0 = tcg_temp_new();
|
||||||
|
TCGv_i32 t1 = tcg_const_i32(rS(ctx->opcode));
|
||||||
/* NIP cannot be restored if the memory exception comes from an helper */
|
/* NIP cannot be restored if the memory exception comes from an helper */
|
||||||
gen_update_nip(ctx, ctx->nip - 4);
|
gen_update_nip(ctx, ctx->nip - 4);
|
||||||
gen_addr_imm_index(cpu_T[0], ctx, 0);
|
gen_addr_imm_index(t0, ctx, 0);
|
||||||
op_ldstm(stmw, rS(ctx->opcode));
|
gen_helper_stmw(t0, t1);
|
||||||
|
tcg_temp_free(t0);
|
||||||
|
tcg_temp_free_i32(t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Integer load and store strings ***/
|
/*** Integer load and store strings ***/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue