qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [PATCH 40/60] AArch64: Add tbz instruction emulation


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

This patch adds emulation for the tbz/tbnz instructions.

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

diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index 2c2adb8..7232cf4 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -294,6 +294,38 @@ static void handle_condb(DisasContext *s, uint32_t insn)
     s->is_jmp = DISAS_TB_JUMP;
 }
 
+static void handle_tbz(DisasContext *s, uint32_t insn)
+{
+    uint64_t addr = s->pc - 4 + (get_sbits(insn, 5, 14) << 2);
+    bool is_one = get_bits(insn, 24, 1);
+    int shift = get_bits(insn, 19, 5) | (get_bits(insn, 31, 1) << 5);
+    int source = get_reg(insn);
+    int no_match;
+    uint64_t mask = 1ULL << shift;
+    TCGv_i64 tcg_cmp, tcg_mask;
+
+    tcg_cmp = tcg_temp_new_i64();
+    tcg_mask = tcg_const_i64(mask);
+    tcg_gen_and_i64(tcg_cmp, cpu_reg(source), tcg_mask);
+
+    no_match = gen_new_label();
+    if (is_one) {
+        tcg_gen_brcond_i64(TCG_COND_NE, tcg_cmp, tcg_mask, no_match);
+    } else {
+        tcg_gen_brcond_i64(TCG_COND_EQ, tcg_cmp, tcg_mask, no_match);
+    }
+    gen_goto_tb(s, 0, addr);
+    tcg_gen_exit_tb(0);
+
+    gen_set_label(no_match);
+    gen_goto_tb(s, 1, s->pc);
+
+    tcg_temp_free_i64(tcg_cmp);
+    tcg_temp_free_i64(tcg_mask);
+
+    s->is_jmp = DISAS_TB_JUMP;
+}
+
 static void ldst_do_vec_int(DisasContext *s, int freg_offs, TCGv_i64 tcg_addr,
                             int size, bool is_store)
 {
@@ -1856,6 +1888,14 @@ void disas_a64_insn(CPUARMState *env, DisasContext *s)
             unallocated_encoding(s);
         }
         break;
+    case 0x16:
+    case 0x17:
+        if (get_bits(insn, 29, 2) == 0x1) {
+            handle_tbz(s, insn);
+        } else {
+            unallocated_encoding(s);
+        }
+        break;
     default:
         unallocated_encoding(s);
         break;
-- 
1.7.12.4




reply via email to

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