[PATCH] tcg/aarch64: Use TBNZ for 16-byte alignment check on i128 ld/st

yujun posted 1 patch 3 weeks, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260629111602.282742-1-yujun@kylinos.cn
Maintainers: Richard Henderson <richard.henderson@linaro.org>
tcg/aarch64/tcg-target.c.inc | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
[PATCH] tcg/aarch64: Use TBNZ for 16-byte alignment check on i128 ld/st
Posted by yujun 3 weeks, 5 days ago
Without FEAT_LSE2, 128-bit guest loads and stores that require full
atomicity but only guarantee 8-byte alignment must choose between an
LDXP+STXP loop and a pair of 8-byte accesses at runtime.  When the
required alignment is MO_64, prepare_host_addr() has already verified
8-byte alignment, so only bit 3 needs testing.

Use TBNZ on bit 3 instead of ANDSI #15 plus B.cond, saving one
instruction on the common path.  Keep the wider test for lesser
alignments.

Fixes: 929124ec0b ("tcg/aarch64: Support 128-bit load/store")
Signed-off-by: yujun <yujun@kylinos.cn>
---
 tcg/aarch64/tcg-target.c.inc | 24 ++++++++++++++++--------
 1 file changed, 16 insertions(+), 8 deletions(-)

diff --git a/tcg/aarch64/tcg-target.c.inc b/tcg/aarch64/tcg-target.c.inc
index cc9c2a5158..36b129363f 100644
--- a/tcg/aarch64/tcg-target.c.inc
+++ b/tcg/aarch64/tcg-target.c.inc
@@ -1898,14 +1898,18 @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
          * may be handled with two 8-byte loads.
          */
         if (h.aa.align < MO_128) {
-            /*
-             * TODO: align should be MO_64, so we only need test bit 3,
-             * which means we could use TBNZ instead of ANDS+B_C.
-             */
-            tcg_out_logicali(s, Ilogic_imm_ANDSI, 0, TCG_REG_XZR, addr_reg,
-                             15);
             branch = s->code_ptr;
-            tcg_out_insn(s, bcond_imm, B_C, TCG_COND_NE, 0);
+            if (h.aa.align == MO_64) {
+                /*
+                 * 8-byte alignment is already verified; test bit 3 to
+                 * distinguish 8- from 16-byte alignment.
+                 */
+                tcg_out_insn(s, tbz, TBNZ, addr_reg, 3, 0);
+            } else {
+                tcg_out_logicali(s, Ilogic_imm_ANDSI, 0, TCG_REG_XZR, addr_reg,
+                                 15);
+                tcg_out_insn(s, bcond_imm, B_C, TCG_COND_NE, 0);
+            }
             use_pair = true;
         }
 
@@ -1944,7 +1948,11 @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg datalo, TCGReg datahi,
         if (use_pair) {
             /* "b .+8", branching across the one insn of use_pair. */
             tcg_out_insn(s, branch, B, 2);
-            reloc_pc19(branch, tcg_splitwx_to_rx(s->code_ptr));
+            if (h.aa.align == MO_64) {
+                reloc_pc14(branch, tcg_splitwx_to_rx(s->code_ptr));
+            } else {
+                reloc_pc19(branch, tcg_splitwx_to_rx(s->code_ptr));
+            }
         }
     }
 
-- 
2.25.1