[PATCH 21/27] arcv3: TCG instruction generator changes

cupertinomiranda at gmail.com cupertinomiranda at gmail.com
Mon Apr 5 15:31:32 BST 2021


From: Cupertino Miranda <cmiranda at synopsys.com>

---
 target/arc/translate.c | 180 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 180 insertions(+)

diff --git a/target/arc/translate.c b/target/arc/translate.c
index 1712fcc9c3..6b2102394f 100644
--- a/target/arc/translate.c
+++ b/target/arc/translate.c
@@ -303,6 +303,15 @@ static bool read_and_decode_context(DisasContext *ctx,
                                         cpu_ldl_code(ctx->env,
                                         ctx->cpc + length));
         length += 4;
+#ifdef TARGET_ARCV3
+    } else if(ctx->insn.signed_limm_p) {
+        ctx->insn.limm = ARRANGE_ENDIAN(true,
+                                        cpu_ldl_code (ctx->env,
+                                        ctx->cpc + length));
+        if(ctx->insn.limm & 0x80000000)
+          ctx->insn.limm += 0xffffffff00000000;
+        length += 4;
+#endif
     } else {
         ctx->insn.limm = 0;
     }
@@ -747,7 +756,14 @@ arc_gen_SR(DisasCtxt *ctx, TCGv src2, TCGv src1)
 {
     int ret = DISAS_NEXT;
 
+#ifdef TARGET_ARCV2
+    writeAuxReg(src2, src1);
+#elif TARGET_ARCV3
+    TCGv temp = tcg_temp_local_new();
+    tcg_gen_andi_tl(temp, src1, 0xffffffff);
     writeAuxReg(src2, src1);
+    tcg_temp_free(temp);
+#endif
     return ret;
 }
 int
@@ -770,6 +786,169 @@ arc_gen_SYNC(DisasCtxt *ctx)
 }
 
 
+#ifdef TARGET_ARCV3
+/*
+ * The mpyl instruction is a 64x64 signed multipler that produces
+ * a 64-bit product (the lower 64-bit of the actual prodcut).
+ */
+int
+arc_gen_MPYL(DisasCtxt *ctx, TCGv a, TCGv b, TCGv c)
+{
+    if ((getFFlag () == true)) {
+        arc_gen_excp(ctx, EXCP_INST_ERROR, 0, 0);
+        return DISAS_NEXT;
+    }
+
+    TCGLabel *done = gen_new_label();
+
+    if (ctx->insn.cc) {
+        TCGv cc = tcg_temp_local_new();
+        arc_gen_verifyCCFlag(ctx, cc);
+        tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done);
+        tcg_temp_free(cc);
+    }
+
+    TCGv_i64 lo = tcg_temp_local_new_i64();
+    TCGv_i64 hi = tcg_temp_local_new_i64();
+
+    tcg_gen_muls2_i64(lo, hi, b, c);
+    tcg_gen_mov_tl(a, lo);
+
+    tcg_temp_free_i64(hi);
+    tcg_temp_free_i64(lo);
+    gen_set_label(done);
+
+    return DISAS_NEXT;
+}
+
+/*
+ * The mpyml instruction is a 64x64 signed multipler that produces
+ * a 64-bit product (the higher 64-bit of the actual prodcut).
+ */
+int
+arc_gen_MPYML(DisasCtxt *ctx, TCGv a, TCGv b, TCGv c)
+{
+    if ((getFFlag () == true)) {
+        arc_gen_excp(ctx, EXCP_INST_ERROR, 0, 0);
+        return DISAS_NEXT;
+    }
+
+    TCGLabel *done = gen_new_label();
+
+    if (ctx->insn.cc) {
+        TCGv cc = tcg_temp_local_new();
+        arc_gen_verifyCCFlag(ctx, cc);
+        tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done);
+        tcg_temp_free(cc);
+    }
+
+    TCGv lo = tcg_temp_local_new();
+    TCGv hi = tcg_temp_local_new();
+    tcg_gen_muls2_i64(lo, hi, b, c);
+    tcg_gen_mov_tl(a, hi);
+
+    tcg_temp_free(hi);
+    tcg_temp_free(lo);
+    gen_set_label(done);
+
+    return DISAS_NEXT;
+}
+
+/*
+ * The mpymul instruction is a 64x64 unsigned multipler that produces
+ * a 64-bit product (the higher 64-bit of the actual prodcut).
+ */
+int
+arc_gen_MPYMUL(DisasCtxt *ctx, TCGv a, TCGv b, TCGv c)
+{
+    if ((getFFlag () == true)) {
+        arc_gen_excp(ctx, EXCP_INST_ERROR, 0, 0);
+        return DISAS_NEXT;
+    }
+
+    TCGLabel *done = gen_new_label();
+
+    if (ctx->insn.cc) {
+        TCGv cc = tcg_temp_local_new();
+        arc_gen_verifyCCFlag(ctx, cc);
+        tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done);
+        tcg_temp_free(cc);
+    }
+
+    TCGv lo = tcg_temp_local_new();
+    TCGv hi = tcg_temp_local_new();
+
+    tcg_gen_mulu2_i64(lo, hi, b, c);
+    tcg_gen_mov_tl(a, hi);
+
+    tcg_temp_free(hi);
+    tcg_temp_free(lo);
+    gen_set_label(done);
+
+    return DISAS_NEXT;
+}
+
+/*
+ * The mpymsul instruction is a 64x64 signedxunsigned multipler that
+ * produces * a 64-bit product (the higher 64-bit of the actual prodcut).
+ */
+int
+arc_gen_MPYMSUL(DisasCtxt *ctx, TCGv a, TCGv b, TCGv c)
+{
+    if ((getFFlag () == true)) {
+        arc_gen_excp(ctx, EXCP_INST_ERROR, 0, 0);
+        return DISAS_NEXT;
+    }
+
+    TCGLabel *done = gen_new_label();
+
+    if (ctx->insn.cc) {
+        TCGv cc = tcg_temp_local_new();
+        arc_gen_verifyCCFlag(ctx, cc);
+        tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done);
+        tcg_temp_free(cc);
+    }
+
+    TCGv lo = tcg_temp_local_new();
+    TCGv hi = tcg_temp_local_new();
+    tcg_gen_mulsu2_tl(lo, hi, b, c);
+    tcg_gen_mov_tl(a, hi);
+
+    tcg_temp_free(hi);
+    tcg_temp_free(lo);
+    gen_set_label(done);
+
+    return DISAS_NEXT;
+}
+
+/*
+ * a = b + (c << 32)
+ */
+int
+arc_gen_ADDHL(DisasCtxt *ctx, TCGv a, TCGv b, TCGv c)
+{
+    TCGLabel *done = gen_new_label();
+
+    if (ctx->insn.cc) {
+        TCGv cc = tcg_temp_local_new();
+        arc_gen_verifyCCFlag(ctx, cc);
+        tcg_gen_brcondi_tl(TCG_COND_NE, cc, 1, done);
+        tcg_temp_free(cc);
+    }
+
+    TCGv shifted = tcg_temp_local_new();
+    tcg_gen_shli_tl(shifted, c, 32);
+    tcg_gen_add_tl(a, b, shifted);
+
+    tcg_temp_free(shifted);
+    gen_set_label(done);
+
+    return DISAS_NEXT;
+}
+
+#endif
+#ifdef TARGET_ARCV2
+
 /*
  * Function to add boiler plate code for conditional execution.
  * It will add tcg_gen codes only if there is a condition to
@@ -1208,6 +1387,7 @@ arc_gen_VSUB4H(DisasCtxt *ctx, TCGv dest, TCGv_i32 b, TCGv_i32 c)
     }
     return DISAS_NEXT;
 }
+#endif
 
 int
 arc_gen_SWI(DisasCtxt *ctx, TCGv a)
-- 
2.20.1




More information about the linux-snps-arc mailing list