diff mbox

[RFC,v1,16/29] target-arc: BBIT0, BBIT1, BR

Message ID 1473373930-31547-17-git-send-email-mrolnik@gmail.com
State New
Headers show

Commit Message

Michael Rolnik Sept. 8, 2016, 10:31 p.m. UTC
Signed-off-by: Michael Rolnik <mrolnik@gmail.com>
---
 target-arc/translate-inst.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
 target-arc/translate-inst.h |  35 ++++++++++++
 2 files changed, 171 insertions(+)

Comments

Richard Henderson Sept. 21, 2016, 12:25 a.m. UTC | #1
On 09/08/2016 03:31 PM, Michael Rolnik wrote:
> +static void arc_gen_exec_delayslot(DisasCtxt *ctx)
> +{
> +    if (ctx->opt.limm == 0) {
> +        uint32_t cpc = ctx->cpc;
> +        uint32_t npc = ctx->npc;
> +        uint32_t dpc = ctx->dpc;
> +        uint32_t pcl = ctx->pcl;
> +        options_t opt = ctx->opt;
> +        int bstate = ctx->bstate;
> +
> +        ctx->cpc = ctx->npc;
> +        ctx->pcl = ctx->cpc & 0xfffffffc;
> +
> +        ++ctx->ds;
> +
> +        /* TODO: check for illegal instruction sequence */
> +
> +        memset(&ctx->opt, 0, sizeof(ctx->opt));
> +        arc_decode(ctx);
> +
> +        --ctx->ds;
> +
> +        ctx->cpc = cpc;
> +        ctx->npc = npc;
> +        ctx->dpc = dpc;
> +        ctx->pcl = pcl;
> +        ctx->opt = opt;
> +        ctx->bstate = bstate;
> +    }
> +}

It might be easier to put the delay slot into a TB by itself.  That will avoid 
having to duplicate the decoding here.


r~
diff mbox

Patch

diff --git a/target-arc/translate-inst.c b/target-arc/translate-inst.c
index c3795fe..8288edd 100644
--- a/target-arc/translate-inst.c
+++ b/target-arc/translate-inst.c
@@ -104,6 +104,42 @@  static void gen_sub_Vf(TCGv dest, TCGv src1, TCGv src2)
     tcg_temp_free_i32(t1);
 }
 
+static void arc_gen_exec_delayslot(DisasCtxt *ctx)
+{
+    if (ctx->opt.limm == 0) {
+        uint32_t cpc = ctx->cpc;
+        uint32_t npc = ctx->npc;
+        uint32_t dpc = ctx->dpc;
+        uint32_t pcl = ctx->pcl;
+        options_t opt = ctx->opt;
+        int bstate = ctx->bstate;
+
+        ctx->cpc = ctx->npc;
+        ctx->pcl = ctx->cpc & 0xfffffffc;
+
+        ++ctx->ds;
+
+        /* TODO: check for illegal instruction sequence */
+
+        memset(&ctx->opt, 0, sizeof(ctx->opt));
+        arc_decode(ctx);
+
+        --ctx->ds;
+
+        ctx->cpc = cpc;
+        ctx->npc = npc;
+        ctx->dpc = dpc;
+        ctx->pcl = pcl;
+        ctx->opt = opt;
+        ctx->bstate = bstate;
+    }
+}
+
+static void arc_gen_kill_delayslot(DisasCtxt *ctx)
+{
+    /*  nothing to do   */
+}
+
 /*
     ADC
 */
@@ -1651,3 +1687,103 @@  int arc_gen_MULU64(DisasCtxt *ctx, TCGv dest, TCGv src1, TCGv src2)
     return BS_NONE;
 }
 
+/*
+    BBIT0
+*/
+int arc_gen_BBIT0(DisasCtxt *ctx, TCGv src1, TCGv src2, TCGv rd)
+{
+    TCGv mask = tcg_temp_new_i32();
+    TCGv cond = tcg_temp_new_i32();
+    TCGLabel *label_done = gen_new_label();
+    TCGLabel *label_jump = gen_new_label();
+
+    tcg_gen_andi_tl(mask, src2, 0x31);
+    tcg_gen_shr_tl(mask, ctx->one, mask);
+    tcg_gen_andc_tl(cond, src1, mask);      /*  cond = src1 & ~(1 << src2)   */
+
+    tcg_gen_brcond_tl(TCG_COND_EQ, cond, ctx->zero, label_jump);
+
+    tcg_gen_movi_tl(cpu_pc, ctx->npc);
+    arc_gen_exec_delayslot(ctx);
+    tcg_gen_br(label_done);
+
+gen_set_label(label_jump);
+    tcg_gen_shli_tl(cpu_pc, rd, 1);
+    tcg_gen_addi_tl(cpu_pc, cpu_pc, ctx->pcl);
+    if (ctx->opt.d == 0) {
+        arc_gen_kill_delayslot(ctx);
+    } else {
+        arc_gen_exec_delayslot(ctx);
+    }
+
+gen_set_label(label_done);
+    tcg_temp_free_i32(cond);
+    tcg_temp_free_i32(mask);
+
+    return  BS_BRANCH_DS;
+}
+
+/*
+    BBIT1
+*/
+int arc_gen_BBIT1(DisasCtxt *ctx, TCGv src1, TCGv src2, TCGv rd)
+{
+    TCGv mask = tcg_temp_new_i32();
+    TCGv cond = tcg_temp_new_i32();
+    TCGLabel *label_done = gen_new_label();
+    TCGLabel *label_jump = gen_new_label();
+
+    tcg_gen_andi_tl(mask, src2, 0x31);
+    tcg_gen_shr_tl(mask, ctx->one, mask);
+    tcg_gen_and_tl(cond, src1, mask);       /*  cond = src1 & (1 << src2)   */
+
+    tcg_gen_brcond_tl(TCG_COND_EQ, cond, ctx->zero, label_jump);
+
+    tcg_gen_movi_tl(cpu_pc, ctx->dpc);
+    arc_gen_exec_delayslot(ctx);
+    tcg_gen_br(label_done);
+
+gen_set_label(label_jump);
+    tcg_gen_shli_tl(cpu_pc, rd, 1);
+    tcg_gen_addi_tl(cpu_pc, cpu_pc, ctx->pcl);
+    if (ctx->opt.d == 0) {
+        arc_gen_kill_delayslot(ctx);
+    } else {
+        arc_gen_exec_delayslot(ctx);
+    }
+
+gen_set_label(label_done);
+    tcg_temp_free_i32(cond);
+    tcg_temp_free_i32(mask);
+
+    return  BS_BRANCH_DS;
+}
+
+/*
+    BR
+*/
+int arc_gen_BR(DisasCtxt *ctx, TCGv src1, TCGv src2, TCGv Rd, TCGCond cond)
+{
+    TCGLabel *label_done = gen_new_label();
+    TCGLabel *label_jump = gen_new_label();
+
+    tcg_gen_brcond_tl(cond, src1, src2, label_jump);
+
+    tcg_gen_movi_tl(cpu_pc, ctx->dpc);
+    arc_gen_exec_delayslot(ctx);
+    tcg_gen_br(label_done);
+
+gen_set_label(label_jump);
+    tcg_gen_shli_tl(cpu_pc, Rd, 1);
+    tcg_gen_addi_tl(cpu_pc, cpu_pc, ctx->pcl);
+    if (ctx->opt.d == 0) {
+        arc_gen_kill_delayslot(ctx);
+    } else {
+        arc_gen_exec_delayslot(ctx);
+    }
+
+gen_set_label(label_done);
+
+    return  BS_BRANCH_DS;
+}
+
diff --git a/target-arc/translate-inst.h b/target-arc/translate-inst.h
index e017237..c78ed24 100644
--- a/target-arc/translate-inst.h
+++ b/target-arc/translate-inst.h
@@ -22,6 +22,37 @@ 
 #include "qemu/bitops.h"
 #include "tcg/tcg.h"
 
+typedef enum ARC_COND {
+    ARC_COND_AL      = 0x00,
+    ARC_COND_RA      = 0x00,
+    ARC_COND_EQ      = 0x01,
+    ARC_COND_Z       = 0x01,
+    ARC_COND_NE      = 0x02,
+    ARC_COND_NZ      = 0x02,
+    ARC_COND_PL      = 0x03,
+    ARC_COND_P       = 0x03,
+    ARC_COND_MI      = 0x04,
+    ARC_COND_N       = 0x04,
+    ARC_COND_CS      = 0x05,
+    ARC_COND_C       = 0x05,
+    ARC_COND_LO      = 0x05,
+    ARC_COND_CC      = 0x06,
+    ARC_COND_NC      = 0x06,
+    ARC_COND_HS      = 0x06,
+    ARC_COND_VS      = 0x07,
+    ARC_COND_V       = 0x07,
+    ARC_COND_VC      = 0x08,
+    ARC_COND_NV      = 0x08,
+    ARC_COND_GT      = 0x09,
+    ARC_COND_GE      = 0x0a,
+    ARC_COND_LT      = 0x0b,
+    ARC_COND_LE      = 0x0c,
+    ARC_COND_HI      = 0x0d,
+    ARC_COND_LS      = 0x0e,
+    ARC_COND_PNZ     = 0x0f,
+} ARC_COND;
+
+
 int arc_gen_ADC(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);
 int arc_gen_ADD(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);
 int arc_gen_ADD1(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);
@@ -99,3 +130,7 @@  int arc_gen_DIVAW(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);
 int arc_gen_MUL64(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);
 int arc_gen_MULU64(DisasCtxt *c, TCGv dest, TCGv src1, TCGv src2);
 
+int arc_gen_BBIT0(DisasCtxt *c, TCGv src1, TCGv src2, TCGv rd);
+int arc_gen_BBIT1(DisasCtxt *c, TCGv src1, TCGv src2, TCGv rd);
+int arc_gen_BR(DisasCtxt *c, TCGv src1, TCGv src2, TCGv Rd, TCGCond cond);
+