1
From e993aef3beb76acb151077147d617d29f459d297 Mon Sep 17 00:00:00 2001
2
From: Alexander Graf <agraf@suse.de>
3
Date: Tue, 17 Dec 2013 19:42:33 +0000
4
Subject: [PATCH 33/49] target-arm: A64: add support for conditional branches
6
This patch adds emulation for the conditional branch (b.cond) instruction.
8
Signed-off-by: Alexander Graf <agraf@suse.de>
9
[claudio: adapted to new decoder structure,
10
reused arm infrastructure for checking the flags]
11
Signed-off-by: Claudio Fontana <claudio.fontana@linaro.org>
12
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13
Reviewed-by: Richard Henderson <rth@twiddle.net>
15
target-arm/translate-a64.c | 29 +++++++++++++++++++++++++++--
16
target-arm/translate.c | 14 +++++++++-----
17
target-arm/translate.h | 2 ++
18
3 files changed, 38 insertions(+), 7 deletions(-)
20
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
21
index b694665..4eb2992 100644
22
--- a/target-arm/translate-a64.c
23
+++ b/target-arm/translate-a64.c
24
@@ -239,10 +239,35 @@ static void disas_test_b_imm(DisasContext *s, uint32_t insn)
25
unsupported_encoding(s, insn);
28
-/* Conditional branch (immediate) */
29
+/* C3.2.2 / C5.6.19 Conditional branch (immediate)
30
+ * 31 25 24 23 5 4 3 0
31
+ * +---------------+----+---------------------+----+------+
32
+ * | 0 1 0 1 0 1 0 | o1 | imm19 | o0 | cond |
33
+ * +---------------+----+---------------------+----+------+
35
static void disas_cond_b_imm(DisasContext *s, uint32_t insn)
37
- unsupported_encoding(s, insn);
41
+ if ((insn & (1 << 4)) || (insn & (1 << 24))) {
42
+ unallocated_encoding(s);
45
+ addr = s->pc + sextract32(insn, 5, 19) * 4 - 4;
46
+ cond = extract32(insn, 0, 4);
49
+ /* genuinely conditional branches */
50
+ int label_match = gen_new_label();
51
+ arm_gen_test_cc(cond, label_match);
52
+ gen_goto_tb(s, 0, s->pc);
53
+ gen_set_label(label_match);
54
+ gen_goto_tb(s, 1, addr);
56
+ /* 0xe and 0xf are both "always" conditions */
57
+ gen_goto_tb(s, 0, addr);
62
diff --git a/target-arm/translate.c b/target-arm/translate.c
63
index 3a1387e..64bccaa 100644
64
--- a/target-arm/translate.c
65
+++ b/target-arm/translate.c
66
@@ -671,7 +671,11 @@ static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
70
-static void gen_test_cc(int cc, int label)
72
+ * generate a conditional branch based on ARM condition code cc.
73
+ * This is common between ARM and Aarch64 targets.
75
+void arm_gen_test_cc(int cc, int label)
79
@@ -7105,7 +7109,7 @@ static void disas_arm_insn(CPUARMState * env, DisasContext *s)
80
/* if not always execute, we generate a conditional jump to
82
s->condlabel = gen_new_label();
83
- gen_test_cc(cond ^ 1, s->condlabel);
84
+ arm_gen_test_cc(cond ^ 1, s->condlabel);
87
if ((insn & 0x0f900000) == 0x03000000) {
88
@@ -9122,7 +9126,7 @@ static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw
89
op = (insn >> 22) & 0xf;
90
/* Generate a conditional jump to next instruction. */
91
s->condlabel = gen_new_label();
92
- gen_test_cc(op ^ 1, s->condlabel);
93
+ arm_gen_test_cc(op ^ 1, s->condlabel);
96
/* offset[11:1] = insn[10:0] */
97
@@ -9479,7 +9483,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
98
cond = s->condexec_cond;
99
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
100
s->condlabel = gen_new_label();
101
- gen_test_cc(cond ^ 1, s->condlabel);
102
+ arm_gen_test_cc(cond ^ 1, s->condlabel);
106
@@ -10152,7 +10156,7 @@ static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
108
/* generate a conditional jump to next instruction */
109
s->condlabel = gen_new_label();
110
- gen_test_cc(cond ^ 1, s->condlabel);
111
+ arm_gen_test_cc(cond ^ 1, s->condlabel);
114
/* jump to the offset */
115
diff --git a/target-arm/translate.h b/target-arm/translate.h
116
index 23a45da..a6f6b3e 100644
117
--- a/target-arm/translate.h
118
+++ b/target-arm/translate.h
119
@@ -65,4 +65,6 @@ static inline void gen_a64_set_pc_im(uint64_t val)
123
+void arm_gen_test_cc(int cc, int label);
125
#endif /* TARGET_ARM_TRANSLATE_H */