target/arm: Implement CB, CBB, CBH
Compare and branch instructions, with various operand widths. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20260518174750.660258-3-richard.henderson@linaro.org Reviewed-by: Peter Maydell <peter.maydell@linaro.org> [PMM: move var decl to top of function] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Richard Henderson committed
May 18, 2026 at 10:47 UTC
c2219ef906cf413b6cb15c1734cca4f6f610926f
2 files changed
+52
target/arm/tcg/a64.decode
+9
@@ -208,6 +208,15 @@ TBZ . 011011 nz:1 ..... .............. rt:5 &tbz imm=%imm14 bitpos=
208
# B.cond and BC.cond
209
B_cond 0101010 0 ................... c:1 cond:4 imm=%imm19
210
211
+# CB, CBB, CBH
212
+%imm9 5:s9 !function=times_4
213
+&cb cc rt rm imm esz
214
+@cb . ....... cc:3 rm:5 .. ......... rt:5 &cb imm=%imm9
215
+CB_cond 0 1110100 ... ..... 00 ......... ..... @cb esz=2
216
+CB_cond 1 1110100 ... ..... 00 ......... ..... @cb esz=3
217
+CB_cond 0 1110100 ... ..... 10 ......... ..... @cb esz=0 # CBB
218
+CB_cond 0 1110100 ... ..... 11 ......... ..... @cb esz=1 # CBH
219
+
220
BR 1101011 0000 11111 000000 rn:5 00000 &r
221
BLR 1101011 0001 11111 000000 rn:5 00000 &r
222
RET 1101011 0010 11111 000000 rn:5 00000 &r
target/arm/tcg/translate-a64.c
+43
@@ -1774,6 +1774,49 @@ static bool trans_B_cond(DisasContext *s, arg_B_cond *a)
1774
return true;
1775
}
1776
1777
+static bool trans_CB_cond(DisasContext *s, arg_CB_cond *a)
1778
+{
1779
+ static const TCGCond cb_cond[8] = {
1780
+ [0] = TCG_COND_GT,
1781
+ [1] = TCG_COND_GE,
1782
+ [2] = TCG_COND_GTU,
1783
+ [3] = TCG_COND_GEU,
1784
+ [4] = TCG_COND_NEVER, /* reserved */
1785
+ [5] = TCG_COND_NEVER, /* reserved */
1786
+ [6] = TCG_COND_EQ,
1787
+ [7] = TCG_COND_NE,
1788
+ };
1789
+ TCGCond cond = cb_cond[a->cc];
1790
+ TCGv_i64 t, m;
1791
+ DisasLabel match;
1792
+
1793
+ if (!dc_isar_feature(aa64_cmpbr, s) || cond == TCG_COND_NEVER) {
1794
+ return false;
1795
+ }
1796
+
1797
+ t = cpu_reg(s, a->rt);
1798
+ m = cpu_reg(s, a->rm);
1799
+ if (a->esz != MO_64) {
1800
+ MemOp mop = a->esz | (is_signed_cond(cond) ? MO_SIGN : 0);
1801
+ TCGv_i64 tt = tcg_temp_new_i64();
1802
+ TCGv_i64 tm = tcg_temp_new_i64();
1803
+
1804
+ tcg_gen_ext_i64(tt, t, mop);
1805
+ tcg_gen_ext_i64(tm, m, mop);
1806
+ t = tt;
1807
+ m = tm;
1808
+ }
1809
+
1810
+ reset_btype(s);
1811
+ match = gen_disas_label(s);
1812
+
1813
+ tcg_gen_brcond_i64(cond, t, m, match.label);
1814
+ gen_goto_tb(s, 0, 4);
1815
+ set_disas_label(s, match);
1816
+ gen_goto_tb(s, 1, a->imm);
1817
+ return true;
1818
+}
1819
+
1820
static void set_btype_for_br(DisasContext *s, int rn)
1821
{
1822
if (dc_isar_feature(aa64_bti, s)) {