s->base.is_jmp = DISAS_UPDATE;
}
+/* Generate a label used for skipping this instruction */
+static void arm_gen_condlabel(DisasContext *s)
+{
+ if (!s->condjmp) {
+ s->condlabel = gen_new_label();
+ s->condjmp = 1;
+ }
+}
+
+/* Skip this instruction if the ARM condition is false */
+static void arm_skip_unless(DisasContext *s, uint32_t cond)
+{
+ arm_gen_condlabel(s);
+ arm_gen_test_cc(cond ^ 1, s->condlabel);
+}
+
static void disas_arm_insn(DisasContext *s, unsigned int insn)
{
unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
if (cond != 0xe) {
/* if not always execute, we generate a conditional jump to
next instruction */
- s->condlabel = gen_new_label();
- arm_gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
+ arm_skip_unless(s, cond);
}
if ((insn & 0x0f900000) == 0x03000000) {
if ((insn & (1 << 21)) == 0) {
/* Conditional branch. */
op = (insn >> 22) & 0xf;
/* Generate a conditional jump to next instruction. */
- s->condlabel = gen_new_label();
- arm_gen_test_cc(op ^ 1, s->condlabel);
- s->condjmp = 1;
+ arm_skip_unless(s, op);
/* offset[11:1] = insn[10:0] */
offset = (insn & 0x7ff) << 1;
case 1: case 3: case 9: case 11: /* czb */
rm = insn & 7;
tmp = load_reg(s, rm);
- s->condlabel = gen_new_label();
- s->condjmp = 1;
+ arm_gen_condlabel(s);
if (insn & (1 << 11))
tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
else
break;
}
/* generate a conditional jump to next instruction */
- s->condlabel = gen_new_label();
- arm_gen_test_cc(cond ^ 1, s->condlabel);
- s->condjmp = 1;
+ arm_skip_unless(s, cond);
/* jump to the offset */
val = (uint32_t)s->pc + 2;
uint32_t cond = dc->condexec_cond;
if (cond != 0x0e) { /* Skip conditional when condition is AL. */
- dc->condlabel = gen_new_label();
- arm_gen_test_cc(cond ^ 1, dc->condlabel);
- dc->condjmp = 1;
+ arm_skip_unless(dc, cond);
}
}