qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


From: Michael Rolnik
Subject: [Qemu-devel] [PATCH RFC v1 16/29] target-arc: BBIT0, BBIT1, BR
Date: Fri, 9 Sep 2016 01:31:57 +0300

Signed-off-by: Michael Rolnik <address@hidden>
---
 target-arc/translate-inst.c | 136 ++++++++++++++++++++++++++++++++++++++++++++
 target-arc/translate-inst.h |  35 ++++++++++++
 2 files changed, 171 insertions(+)

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);
+
-- 
2.4.9 (Apple Git-60)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]