>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


Reply via email to