qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 33/60] AArch64: Add bc instruction emulation


From: Alexander Graf
Subject: [Qemu-devel] [PATCH 33/60] AArch64: Add bc instruction emulation
Date: Fri, 27 Sep 2013 02:48:27 +0200

This patch adds emulation for compare and branch instructions (cbz, cbnz)

Signed-off-by: Alexander Graf <address@hidden>
---
 target-arm/translate-a64.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index fdcf876..229b467 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -233,6 +233,41 @@ static void handle_br(DisasContext *s, uint32_t insn)
     s->is_jmp = DISAS_JUMP;
 }
 
+static void handle_cb(DisasContext *s, uint32_t insn)
+{
+    uint64_t addr = s->pc - 4 + (get_sbits(insn, 5, 19) << 2);
+    bool is_zero = !get_bits(insn, 24, 1);
+    bool is_32bit = !get_bits(insn, 31, 1);
+    int dest = get_reg(insn);
+    int no_match;
+    TCGv_i64 tcg_cmp, tcg_zero;
+
+    tcg_cmp = tcg_temp_new_i64();
+    tcg_zero = tcg_const_i64(0);
+
+    if (is_32bit) {
+        tcg_gen_ext32u_i64(tcg_cmp, cpu_reg(dest));
+    } else {
+        tcg_gen_mov_i64(tcg_cmp, cpu_reg(dest));
+    }
+
+    no_match = gen_new_label();
+    if (is_zero) {
+        tcg_gen_brcond_i64(TCG_COND_NE, tcg_cmp, tcg_zero, no_match);
+    } else {
+        tcg_gen_brcond_i64(TCG_COND_EQ, tcg_cmp, tcg_zero, no_match);
+    }
+    gen_goto_tb(s, 0, addr);
+
+    gen_set_label(no_match);
+    gen_goto_tb(s, 1, s->pc);
+
+    s->is_jmp = DISAS_TB_JUMP;
+
+    tcg_temp_free_i64(tcg_cmp);
+    tcg_temp_free_i64(tcg_zero);
+}
+
 static void ldst_do_vec_int(DisasContext *s, int freg_offs, TCGv_i64 tcg_addr,
                             int size, bool is_store)
 {
@@ -1706,6 +1741,15 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
     case 0x14:
         if (get_bits(insn, 29, 3) == 0x6 && !get_bits(insn, 2, 3)) {
             handle_svc(s, insn);
+        } else if (get_bits(insn, 29, 2) == 0x1) {
+            handle_cb(s, insn);
+        } else {
+            unallocated_encoding(s);
+        }
+        break;
+    case 0x15:
+        if (get_bits(insn, 29, 2) == 0x1) {
+            handle_cb(s, insn);
         } else {
             unallocated_encoding(s);
         }
-- 
1.7.12.4




reply via email to

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