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:
Fernando Eckhardt Valle 2021-10-29 17:23:53 -03:00 committed by David Gibson
parent 725b2d4dac
commit fbd2e60ef1
3 changed files with 95 additions and 205 deletions

View File

@ -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

View File

@ -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

View File

@ -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),