>From RFC 02653 for Power ISA 3.2 :
Implement the getter and setter for DMRs with row level granularity.
Implement the following DMF instructions :
DMSETDMRZ : X-form
DMXX{EXTF,INST}DMR256 : XX2-form
DMXX{EXTF,INST}DMR512 : XX3-form
Signed-off-by: Chinmay Rath <[email protected]>
---
target/ppc/cpu.h | 5 ++
target/ppc/insn32.decode | 18 +++++++
target/ppc/translate.c | 11 ++++
target/ppc/translate/dmf-impl.c.inc | 80 +++++++++++++++++++++++++++++
4 files changed, 114 insertions(+)
create mode 100644 target/ppc/translate/dmf-impl.c.inc
diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h
index 1cd379810a..7221868793 100644
--- a/target/ppc/cpu.h
+++ b/target/ppc/cpu.h
@@ -3055,6 +3055,11 @@ static inline ppc_avr_t *cpu_avr_ptr(CPUPPCState *env,
int i)
return (ppc_avr_t *)((uintptr_t)env + avr_full_offset(i));
}
+static inline int dmr_row_offset(int reg, int row)
+{
+ return offsetof(CPUPPCState, dmr[reg].row[row]);
+}
+
static inline bool ppc_has_spr(PowerPCCPU *cpu, int spr)
{
/* We can test whether the SPR is defined by checking for a valid name */
diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode
index 6563dc4f64..2a9733d6fd 100644
--- a/target/ppc/insn32.decode
+++ b/target/ppc/insn32.decode
@@ -274,12 +274,20 @@
&MMIRR_XX3 xa xb xt pmsk xmsk ymsk
%xx_at 23:3
%xx_xa_pair 2:1 17:4 !function=times_2
+%xx_xb_pair 1:1 12:4 !function=times_2
@XX3_at ...... ... .. ..... ..... ........ ... &MMIRR_XX3
xt=%xx_at xb=%xx_xb \
pmsk=255
xmsk=15 ymsk=15
&XX3_dm xt xa xb dm
@XX3_dm ...... ..... ..... ..... . dm:2 ..... ... &XX3_dm
xt=%xx_xt xa=%xx_xa xb=%xx_xb
+&XX3_abp_as_p xap xbp as p
+@XX3_abp_as_p ...... as:3 .. .... p:1 .... . ........ ... &XX3_abp_as_p
xap=%xx_xa_pair xbp=%xx_xb_pair
+
+%p0p1 16:1 11:1
+&XX2_bp_as_p xbp as p
+@XX2_bp_as_p ...... as:3 ...... . .... . ......... .. &XX2_bp_as_p
xbp=%xx_xb_pair p=%p0p1
+
&XX4 xt xa xb xc
@XX4 ...... ..... ..... ..... ..... .. .... &XX4 xt=%xx_xt
xa=%xx_xa xb=%xx_xb xc=%xx_xc
@@ -1534,6 +1542,16 @@ VMODUD 000100 ..... ..... ..... 11011001011
@VX
VMODSQ 000100 ..... ..... ..... 11100001011 @VX
VMODUQ 000100 ..... ..... ..... 11000001011 @VX
+## DMF Instructions
+
+DMSETDMRZ 011111 ... -- 00010 ----- 0010110001 - @X_a
+
+DMXXEXTFDMR512 111100 ... -- .... . .... - 11100010 ..- @XX3_abp_as_p
+DMXXINSTDMR512 111100 ... -- .... . .... - 11101010 ..- @XX3_abp_as_p
+
+DMXXEXTFDMR256 111100 ... ------ . .... . 111100100 .- @XX2_bp_as_p
+DMXXINSTDMR256 111100 ... ------ . .... . 111100101 .- @XX2_bp_as_p
+
## SLB Management Instructions
SLBIE 011111 ----- ----- ..... 0110110010 - @X_rb
diff --git a/target/ppc/translate.c b/target/ppc/translate.c
index 48e5903214..c714ed665a 100644
--- a/target/ppc/translate.c
+++ b/target/ppc/translate.c
@@ -3992,6 +3992,15 @@ static int64_t dw_compose_ea(DisasContext *ctx, int x)
} \
} while (0)
+#define REQUIRE_DM(CTX) \
+ do { \
+ if (unlikely(!(CTX)->dm_enabled)) { \
+ gen_exception_err((CTX), POWERPC_EXCP_FU, \
+ FSCR_IC_DM); \
+ return true; \
+ } \
+ } while (0)
+
#define REQUIRE_FPU(ctx) \
do { \
if (unlikely(!(ctx)->fpu_enabled)) { \
@@ -4384,6 +4393,8 @@ static bool trans_ICBIEP(DisasContext *ctx, arg_X_ea *a)
#include "translate/vsx-impl.c.inc"
+#include "translate/dmf-impl.c.inc"
+
#include "translate/dfp-impl.c.inc"
#include "translate/spe-impl.c.inc"
diff --git a/target/ppc/translate/dmf-impl.c.inc
b/target/ppc/translate/dmf-impl.c.inc
new file mode 100644
index 0000000000..5409ba8836
--- /dev/null
+++ b/target/ppc/translate/dmf-impl.c.inc
@@ -0,0 +1,80 @@
+/*** DMF extension ***/
+
+static inline void set_dmr_row(int reg, int row, TCGv_i128 src)
+{
+ tcg_gen_st_i128(src, tcg_env, dmr_row_offset(reg, row));
+}
+
+static inline void get_dmr_row(TCGv_i128 dst, int reg, int row)
+{
+ tcg_gen_ld_i128(dst, tcg_env, dmr_row_offset(reg, row));
+}
+
+static bool trans_DMSETDMRZ(DisasContext *ctx, arg_DMSETDMRZ *a)
+{
+ TCGv_i128 zero;
+ TCGv_i64 hi, lo;
+
+ REQUIRE_INSNS_FLAGS2(ctx, ISA320);
+ REQUIRE_DM(ctx);
+
+ zero = tcg_temp_new_i128();
+ hi = tcg_constant_i64(0);
+ lo = tcg_constant_i64(0);
+
+ tcg_gen_concat_i64_i128(zero, lo, hi);
+ for (int row = 0; row < 8; row++) {
+ set_dmr_row(a->ra, row, zero);
+ }
+ return true;
+}
+
+static bool do_ext_inst_512(DisasContext *ctx, arg_XX3_abp_as_p *a, bool ext)
+{
+ TCGv_i128 temp;
+
+ REQUIRE_DM(ctx);
+ REQUIRE_VSX(ctx);
+
+ temp = tcg_temp_new_i128();
+ int start_row = (a->p > 0) ? 4 : 0;
+
+ for (int i = 0; i < 4; i++) {
+ int vsr_reg = (i < 2) ? a->xap : a->xbp;
+ if (ext) {
+ get_dmr_row(temp, a->as, start_row + i);
+ set_vsr_full(vsr_reg + (i % 2), temp);
+ } else {
+ get_vsr_full(temp, vsr_reg + (i % 2));
+ set_dmr_row(a->as, start_row + i, temp);
+ }
+ }
+ return true;
+}
+
+static bool do_ext_inst_256(DisasContext *ctx, arg_XX2_bp_as_p *a, bool ext)
+{
+ TCGv_i128 temp;
+
+ REQUIRE_DM(ctx);
+ REQUIRE_VSX(ctx);
+
+ temp = tcg_temp_new_i128();
+ int start_row = 2 * a->p;
+
+ for (int i = 0; i < 2; i++) {
+ if (ext) {
+ get_dmr_row(temp, a->as, start_row + i);
+ set_vsr_full(a->xbp + i, temp);
+ } else {
+ get_vsr_full(temp, a->xbp + i);
+ set_dmr_row(start_row, a->xbp + i, temp);
+ }
+ }
+ return true;
+}
+
+TRANS_FLAGS2(ISA320, DMXXEXTFDMR512, do_ext_inst_512, true)
+TRANS_FLAGS2(ISA320, DMXXINSTDMR512, do_ext_inst_512, false)
+TRANS_FLAGS2(ISA320, DMXXEXTFDMR256, do_ext_inst_256, true)
+TRANS_FLAGS2(ISA320, DMXXINSTDMR256, do_ext_inst_256, false)
--
2.55.0