From 12fcf96e93eced8b53ca5b3c844c96458fb45ef0 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Sat, 21 Feb 2026 15:13:08 -0800 Subject: [PATCH] IR: Adds a ContextClear operation This will be useful for zeroing parts of the context at CLZero alignment and sizes. --- .../Source/Interface/Core/JIT/MemoryOps.cpp | 18 ++++++++++++++++++ FEXCore/Source/Interface/IR/IR.json | 11 +++++++++++ 2 files changed, 29 insertions(+) diff --git a/FEXCore/Source/Interface/Core/JIT/MemoryOps.cpp b/FEXCore/Source/Interface/Core/JIT/MemoryOps.cpp index 17861a03f..589b25bfd 100644 --- a/FEXCore/Source/Interface/Core/JIT/MemoryOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/MemoryOps.cpp @@ -566,6 +566,24 @@ DEF_OP(LoadDF) { ldrsb(Dst.X(), STATE, offsetof(FEXCore::Core::CPUState, flags[Flag])); } +DEF_OP(ContextClear) { + auto Op = IROp->C(); + if (CTX->HostFeatures.SupportsCLZERO) { + // We can use CLZero directly when hardware supports it. + // Provides a fairly generous speed-up on Ampere1A hardware. + // TODO: When FEAT_MOPS hardware ships, test memset using MOPS. + for (size_t i = 0; i < Op->Size; i += 64) { + add(ARMEmitter::Size::i64Bit, TMP1, STATE.R(), Op->Offset + i); + dc(ARMEmitter::DataCacheOperation::ZVA, TMP1); + } + } else { + movi(ARMEmitter::SubRegSize::i64Bit, VTMP1.Q(), 0); + for (size_t i = 0; i < Op->Size; i += 32) { + stp(VTMP1.Q(), VTMP1.Q(), STATE.R(), Op->Offset + i); + } + } +} + ARMEmitter::ExtendedMemOperand Arm64JITCore::GenerateMemOperand( IR::OpSize AccessSize, ARMEmitter::Register Base, IR::OrderedNodeWrapper Offset, IR::MemOffsetType OffsetType, uint8_t OffsetScale) { if (Offset.IsInvalid()) { diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 1013ace84..565d4286d 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -777,6 +777,17 @@ "RegisterSize == FEXCore::IR::OpSize::i128Bit || RegisterSize == FEXCore::IR::OpSize::i256Bit", "Offset % IR::OpSizeToSize(RegisterSize) == 0" ] + }, + "ContextClear u32:$Offset, u32:$Size": { + "Desc": [ + "Clears a region of the context by CLZero size", + "Both the offset and size alignment need to be by CLZero size" + ], + "HasSideEffects": true, + "EmitValidation": [ + "Offset % 64 == 0", + "Size % 64 == 0" + ] } }, "Atomic": {