target/ppc: Move load and store floating point instructions to decodetree
Move load floating point instructions (lfs, lfsu, lfsx, lfsux, lfd, lfdu, lfdx, lfdux) and store floating point instructions(stfs, stfsu, stfsx, stfsux, stfd, stfdu, stfdx, stfdux) from legacy system to decodetree. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Fernando Eckhardt Valle <fernando.valle@eldorado.org.br> Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br> Message-Id: <20211029202424.175401-4-matheus.ferst@eldorado.org.br> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
725b2d4dac
commit
fbd2e60ef1
@ -114,6 +114,30 @@ ADDPCIS 010011 ..... ..... .......... 00010 . @DX
|
||||
|
||||
CFUGED 011111 ..... ..... ..... 0011011100 - @X
|
||||
|
||||
### Float-Point Load Instructions
|
||||
|
||||
LFS 110000 ..... ..... ................ @D
|
||||
LFSU 110001 ..... ..... ................ @D
|
||||
LFSX 011111 ..... ..... ..... 1000010111 - @X
|
||||
LFSUX 011111 ..... ..... ..... 1000110111 - @X
|
||||
|
||||
LFD 110010 ..... ..... ................ @D
|
||||
LFDU 110011 ..... ..... ................ @D
|
||||
LFDX 011111 ..... ..... ..... 1001010111 - @X
|
||||
LFDUX 011111 ..... ..... ..... 1001110111 - @X
|
||||
|
||||
### Float-Point Store Instructions
|
||||
|
||||
STFS 110100 ..... ...... ............... @D
|
||||
STFSU 110101 ..... ...... ............... @D
|
||||
STFSX 011111 ..... ...... .... 1010010111 - @X
|
||||
STFSUX 011111 ..... ...... .... 1010110111 - @X
|
||||
|
||||
STFD 110110 ..... ...... ............... @D
|
||||
STFDU 110111 ..... ...... ............... @D
|
||||
STFDX 011111 ..... ...... .... 1011010111 - @X
|
||||
STFDUX 011111 ..... ...... .... 1011110111 - @X
|
||||
|
||||
### Move To/From System Register Instructions
|
||||
|
||||
SETBC 011111 ..... ..... ----- 0110000000 - @X_bi
|
||||
|
@ -854,99 +854,6 @@ static void gen_mtfsfi(DisasContext *ctx)
|
||||
gen_helper_float_check_status(cpu_env);
|
||||
}
|
||||
|
||||
/*** Floating-point load ***/
|
||||
#define GEN_LDF(name, ldop, opc, type) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
gen_addr_imm_index(ctx, EA, 0); \
|
||||
gen_qemu_##ldop(ctx, t0, EA); \
|
||||
set_fpr(rD(ctx->opcode), t0); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_LDUF(name, ldop, opc, type) \
|
||||
static void glue(gen_, name##u)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
if (unlikely(rA(ctx->opcode) == 0)) { \
|
||||
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
gen_addr_imm_index(ctx, EA, 0); \
|
||||
gen_qemu_##ldop(ctx, t0, EA); \
|
||||
set_fpr(rD(ctx->opcode), t0); \
|
||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_LDUXF(name, ldop, opc, type) \
|
||||
static void glue(gen_, name##ux)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
if (unlikely(rA(ctx->opcode) == 0)) { \
|
||||
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
gen_addr_reg_index(ctx, EA); \
|
||||
gen_qemu_##ldop(ctx, t0, EA); \
|
||||
set_fpr(rD(ctx->opcode), t0); \
|
||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_LDXF(name, ldop, opc2, opc3, type) \
|
||||
static void glue(gen_, name##x)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
gen_addr_reg_index(ctx, EA); \
|
||||
gen_qemu_##ldop(ctx, t0, EA); \
|
||||
set_fpr(rD(ctx->opcode), t0); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_LDFS(name, ldop, op, type) \
|
||||
GEN_LDF(name, ldop, op | 0x20, type); \
|
||||
GEN_LDUF(name, ldop, op | 0x21, type); \
|
||||
GEN_LDUXF(name, ldop, op | 0x01, type); \
|
||||
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
|
||||
|
||||
static void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 dest, TCGv addr)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_temp_new_i32();
|
||||
@ -955,11 +862,6 @@ static void gen_qemu_ld32fs(DisasContext *ctx, TCGv_i64 dest, TCGv addr)
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
/* lfd lfdu lfdux lfdx */
|
||||
GEN_LDFS(lfd, ld64_i64, 0x12, PPC_FLOAT);
|
||||
/* lfs lfsu lfsux lfsx */
|
||||
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT);
|
||||
|
||||
/* lfdepx (external PID lfdx) */
|
||||
static void gen_lfdepx(DisasContext *ctx)
|
||||
{
|
||||
@ -1089,73 +991,6 @@ static void gen_lfiwzx(DisasContext *ctx)
|
||||
tcg_temp_free(EA);
|
||||
tcg_temp_free_i64(t0);
|
||||
}
|
||||
/*** Floating-point store ***/
|
||||
#define GEN_STF(name, stop, opc, type) \
|
||||
static void glue(gen_, name)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
gen_addr_imm_index(ctx, EA, 0); \
|
||||
get_fpr(t0, rS(ctx->opcode)); \
|
||||
gen_qemu_##stop(ctx, t0, EA); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_STUF(name, stop, opc, type) \
|
||||
static void glue(gen_, name##u)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
if (unlikely(rA(ctx->opcode) == 0)) { \
|
||||
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
gen_addr_imm_index(ctx, EA, 0); \
|
||||
get_fpr(t0, rS(ctx->opcode)); \
|
||||
gen_qemu_##stop(ctx, t0, EA); \
|
||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_STUXF(name, stop, opc, type) \
|
||||
static void glue(gen_, name##ux)(DisasContext *ctx) \
|
||||
{ \
|
||||
TCGv EA; \
|
||||
TCGv_i64 t0; \
|
||||
if (unlikely(!ctx->fpu_enabled)) { \
|
||||
gen_exception(ctx, POWERPC_EXCP_FPU); \
|
||||
return; \
|
||||
} \
|
||||
if (unlikely(rA(ctx->opcode) == 0)) { \
|
||||
gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL); \
|
||||
return; \
|
||||
} \
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT); \
|
||||
EA = tcg_temp_new(); \
|
||||
t0 = tcg_temp_new_i64(); \
|
||||
gen_addr_reg_index(ctx, EA); \
|
||||
get_fpr(t0, rS(ctx->opcode)); \
|
||||
gen_qemu_##stop(ctx, t0, EA); \
|
||||
tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA); \
|
||||
tcg_temp_free(EA); \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_STXF(name, stop, opc2, opc3, type) \
|
||||
static void glue(gen_, name##x)(DisasContext *ctx) \
|
||||
@ -1176,12 +1011,6 @@ static void glue(gen_, name##x)(DisasContext *ctx) \
|
||||
tcg_temp_free_i64(t0); \
|
||||
}
|
||||
|
||||
#define GEN_STFS(name, stop, op, type) \
|
||||
GEN_STF(name, stop, op | 0x20, type); \
|
||||
GEN_STUF(name, stop, op | 0x21, type); \
|
||||
GEN_STUXF(name, stop, op | 0x01, type); \
|
||||
GEN_STXF(name, stop, 0x17, op | 0x00, type)
|
||||
|
||||
static void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 src, TCGv addr)
|
||||
{
|
||||
TCGv_i32 tmp = tcg_temp_new_i32();
|
||||
@ -1190,11 +1019,6 @@ static void gen_qemu_st32fs(DisasContext *ctx, TCGv_i64 src, TCGv addr)
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
/* stfd stfdu stfdux stfdx */
|
||||
GEN_STFS(stfd, st64_i64, 0x16, PPC_FLOAT);
|
||||
/* stfs stfsu stfsux stfsx */
|
||||
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT);
|
||||
|
||||
/* stfdepx (external PID lfdx) */
|
||||
static void gen_stfdepx(DisasContext *ctx)
|
||||
{
|
||||
@ -1473,6 +1297,77 @@ static void gen_stfqx(DisasContext *ctx)
|
||||
tcg_temp_free_i64(t1);
|
||||
}
|
||||
|
||||
/* Floating-point Load/Store Instructions */
|
||||
static bool do_lsfpsd(DisasContext *ctx, int rt, int ra, TCGv displ,
|
||||
bool update, bool store, bool single)
|
||||
{
|
||||
TCGv ea;
|
||||
TCGv_i64 t0;
|
||||
REQUIRE_INSNS_FLAGS(ctx, FLOAT);
|
||||
REQUIRE_FPU(ctx);
|
||||
if (update && ra == 0) {
|
||||
gen_invalid(ctx);
|
||||
return true;
|
||||
}
|
||||
gen_set_access_type(ctx, ACCESS_FLOAT);
|
||||
t0 = tcg_temp_new_i64();
|
||||
ea = do_ea_calc(ctx, ra, displ);
|
||||
if (store) {
|
||||
get_fpr(t0, rt);
|
||||
if (single) {
|
||||
gen_qemu_st32fs(ctx, t0, ea);
|
||||
} else {
|
||||
gen_qemu_st64_i64(ctx, t0, ea);
|
||||
}
|
||||
} else {
|
||||
if (single) {
|
||||
gen_qemu_ld32fs(ctx, t0, ea);
|
||||
} else {
|
||||
gen_qemu_ld64_i64(ctx, t0, ea);
|
||||
}
|
||||
set_fpr(rt, t0);
|
||||
}
|
||||
if (update) {
|
||||
tcg_gen_mov_tl(cpu_gpr[rt], ea);
|
||||
}
|
||||
tcg_temp_free_i64(t0);
|
||||
tcg_temp_free(ea);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool do_lsfp_D(DisasContext *ctx, arg_D *a, bool update, bool store,
|
||||
bool single)
|
||||
{
|
||||
return do_lsfpsd(ctx, a->rt, a->ra, tcg_constant_tl(a->si), update, store,
|
||||
single);
|
||||
}
|
||||
|
||||
static bool do_lsfp_X(DisasContext *ctx, arg_X *a, bool update,
|
||||
bool store, bool single)
|
||||
{
|
||||
return do_lsfpsd(ctx, a->rt, a->ra, cpu_gpr[a->rb], update, store, single);
|
||||
}
|
||||
|
||||
TRANS(LFS, do_lsfp_D, false, false, true)
|
||||
TRANS(LFSU, do_lsfp_D, true, false, true)
|
||||
TRANS(LFSX, do_lsfp_X, false, false, true)
|
||||
TRANS(LFSUX, do_lsfp_X, true, false, true)
|
||||
|
||||
TRANS(LFD, do_lsfp_D, false, false, false)
|
||||
TRANS(LFDU, do_lsfp_D, true, false, false)
|
||||
TRANS(LFDX, do_lsfp_X, false, false, false)
|
||||
TRANS(LFDUX, do_lsfp_X, true, false, false)
|
||||
|
||||
TRANS(STFS, do_lsfp_D, false, true, true)
|
||||
TRANS(STFSU, do_lsfp_D, true, true, true)
|
||||
TRANS(STFSX, do_lsfp_X, false, true, true)
|
||||
TRANS(STFSUX, do_lsfp_X, true, true, true)
|
||||
|
||||
TRANS(STFD, do_lsfp_D, false, true, false)
|
||||
TRANS(STFDU, do_lsfp_D, true, true, false)
|
||||
TRANS(STFDX, do_lsfp_X, false, true, false)
|
||||
TRANS(STFDUX, do_lsfp_X, true, true, false)
|
||||
|
||||
#undef _GEN_FLOAT_ACB
|
||||
#undef GEN_FLOAT_ACB
|
||||
#undef _GEN_FLOAT_AB
|
||||
|
@ -50,43 +50,14 @@ GEN_FLOAT_B(riz, 0x08, 0x0D, 1, PPC_FLOAT_EXT),
|
||||
GEN_FLOAT_B(rip, 0x08, 0x0E, 1, PPC_FLOAT_EXT),
|
||||
GEN_FLOAT_B(rim, 0x08, 0x0F, 1, PPC_FLOAT_EXT),
|
||||
|
||||
#define GEN_LDF(name, ldop, opc, type) \
|
||||
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
|
||||
#define GEN_LDUF(name, ldop, opc, type) \
|
||||
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
|
||||
#define GEN_LDUXF(name, ldop, opc, type) \
|
||||
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
|
||||
#define GEN_LDXF(name, ldop, opc2, opc3, type) \
|
||||
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
|
||||
#define GEN_LDFS(name, ldop, op, type) \
|
||||
GEN_LDF(name, ldop, op | 0x20, type) \
|
||||
GEN_LDUF(name, ldop, op | 0x21, type) \
|
||||
GEN_LDUXF(name, ldop, op | 0x01, type) \
|
||||
GEN_LDXF(name, ldop, 0x17, op | 0x00, type)
|
||||
|
||||
GEN_LDFS(lfd, ld64, 0x12, PPC_FLOAT)
|
||||
GEN_LDFS(lfs, ld32fs, 0x10, PPC_FLOAT)
|
||||
GEN_HANDLER_E(lfdepx, 0x1F, 0x1F, 0x12, 0x00000001, PPC_NONE, PPC2_BOOKE206),
|
||||
GEN_HANDLER_E(lfiwax, 0x1f, 0x17, 0x1a, 0x00000001, PPC_NONE, PPC2_ISA205),
|
||||
GEN_HANDLER_E(lfiwzx, 0x1f, 0x17, 0x1b, 0x1, PPC_NONE, PPC2_FP_CVT_ISA206),
|
||||
GEN_HANDLER_E(lfdpx, 0x1F, 0x17, 0x18, 0x00200001, PPC_NONE, PPC2_ISA205),
|
||||
|
||||
#define GEN_STF(name, stop, opc, type) \
|
||||
GEN_HANDLER(name, opc, 0xFF, 0xFF, 0x00000000, type),
|
||||
#define GEN_STUF(name, stop, opc, type) \
|
||||
GEN_HANDLER(name##u, opc, 0xFF, 0xFF, 0x00000000, type),
|
||||
#define GEN_STUXF(name, stop, opc, type) \
|
||||
GEN_HANDLER(name##ux, 0x1F, 0x17, opc, 0x00000001, type),
|
||||
#define GEN_STXF(name, stop, opc2, opc3, type) \
|
||||
GEN_HANDLER(name##x, 0x1F, opc2, opc3, 0x00000001, type),
|
||||
#define GEN_STFS(name, stop, op, type) \
|
||||
GEN_STF(name, stop, op | 0x20, type) \
|
||||
GEN_STUF(name, stop, op | 0x21, type) \
|
||||
GEN_STUXF(name, stop, op | 0x01, type) \
|
||||
GEN_STXF(name, stop, 0x17, op | 0x00, type)
|
||||
|
||||
GEN_STFS(stfd, st64_i64, 0x16, PPC_FLOAT)
|
||||
GEN_STFS(stfs, st32fs, 0x14, PPC_FLOAT)
|
||||
GEN_STXF(stfiw, st32fiw, 0x17, 0x1E, PPC_FLOAT_STFIWX)
|
||||
GEN_HANDLER_E(stfdepx, 0x1F, 0x1F, 0x16, 0x00000001, PPC_NONE, PPC2_BOOKE206),
|
||||
GEN_HANDLER_E(stfdpx, 0x1F, 0x17, 0x1C, 0x00200001, PPC_NONE, PPC2_ISA205),
|
||||
|
Loading…
Reference in New Issue
Block a user