aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFernando Eckhardt Valle <phervalle@gmail.com>2021-10-29 17:23:53 -0300
committerDavid Gibson <david@gibson.dropbear.id.au>2021-11-09 10:32:51 +1100
commitfbd2e60ef1bdd626c1430a6c1c653e63fed56040 (patch)
treedb21e0b2eff5f2af25e6d5e74aca2532ee7fdaad
parent725b2d4dac67c96c044ed53df2c5e7128e9aa013 (diff)
downloadqemu-fbd2e60ef1bdd626c1430a6c1c653e63fed56040.zip
qemu-fbd2e60ef1bdd626c1430a6c1c653e63fed56040.tar.gz
qemu-fbd2e60ef1bdd626c1430a6c1c653e63fed56040.tar.bz2
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>
-rw-r--r--target/ppc/insn32.decode24
-rw-r--r--target/ppc/translate/fp-impl.c.inc247
-rw-r--r--target/ppc/translate/fp-ops.c.inc29
3 files changed, 95 insertions, 205 deletions
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 9fd8d6b..19ef9bf 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -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
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 9f7868e..57a799d 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -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
diff --git a/target/ppc/translate/fp-ops.c.inc b/target/ppc/translate/fp-ops.c.inc
index 88fab65..4260635 100644
--- a/target/ppc/translate/fp-ops.c.inc
+++ b/target/ppc/translate/fp-ops.c.inc
@@ -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),