@samitouri / QOSamiQemu / commits / c2219ef906

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)) {