On 8/22/26 12:08, Matt Turner wrote:
RFC because:
- Only wired up for x86_64, and only for qemu_ld and qemu_st; the i128
qemu_ld2 and qemu_st2 pairs are left alone.
- Requiring that no slow path exists is stricter than necessary. Recording
the displacement in TCGLabelQemuLdst and emitting one lea on the slow
path would cover alignment-checked accesses too, at no fast path cost.
- Softmmu wants the displacement folded into the TLB comparison as well,
which is a bigger change than this one.
- A one op window catches everything the frontends emit today but is
trivially defeated by anything scheduled in between.
Plausible. Several times I've considered exposing complex addressing
modes to the translators so that things that do LEA are kept intact for
awhile. There are plenty of host-specific code sequences for x << s + y
+ c, even before we fold that into the memory access. Then expose the
host memory path to tcg ops, somehow, and finally implement a simple CSE
pass. But yeah, hand waving is as far as I've ever gone.
On the second point, I guess you also assuming the offset is also
aligned? I.e. for X + 8*N, you can test X for 8-byte alignment without
constructing the complete address.
+static bool tcg_target_ldst_disp_ok(TCGContext *s, MemOpIdx oi, int64_t disp)
+{
+#ifdef CONFIG_USER_ONLY
+ MemOp opc = get_memop(oi);
+ TCGAtomAlign aa;
+ int64_t ofs;
+
+ if (tcg_use_softmmu || s->addr_type != TCG_TYPE_I64) {
+ return false;
+ }
+ aa = atom_and_align_for_opc(s, opc, MO_ATOM_WITHIN16,
+ (opc & MO_SIZE) == MO_128);
+ if (aa.align) {
+ return false;
+ }
+ ofs = (int64_t)x86_guest_base.ofs + disp;
+ return ofs == (int32_t)ofs;
+#else
+ return false;
+#endif
+}
These compilation mode tests belong...
+static void __attribute__((noinline))
+fold_ldst_disp(TCGContext *s)
+{
+ TCGOp *op;
+
+ if (!TCG_TARGET_HAS_ldst_disp) {
+ return;
+ }
... here, before we step over the loop. You might as well pass MemOp to
the target function and not MemOpIdx -- nothing about the mmu_idx is
relevant.
Ideally, the atom_and_align test would also be done generically, not
requiring each target to replicate that boilerplate.
r~