Memory set, unprivileged
These instructions set a required number of bytes in memory to the value in the least significant byte of the source data register. The prologue, main, and epilogue instructions are expected to be run in succession and to appear consecutively in memory: SETPT, then SETMT, and then SETET.
SETPT performs some preconditioning of the arguments suitable for using the SETMT instruction, and sets an IMPLEMENTATION DEFINED portion of the requested number of bytes. SETMT sets a further IMPLEMENTATION DEFINED portion of the remaining bytes. SETET sets any final remaining bytes.
The ability to set an IMPLEMENTATION DEFINED number of bytes allows an implementation to optimize how the bytes being set are divided between the different instructions.
For more information on exceptions specific to memory set instructions, see Memory Copy and Memory Set exceptions.
The architecture supports two algorithms for the memory set: option A and option B. Which algorithm is used is IMPLEMENTATION DEFINED.
Portable software should not assume that the choice of algorithm is constant.
For SETPT:
On completion of SETPT, option A:
On completion of SETPT, option B:
For SETMT, option A, when PSTATE.C = '0':
For SETMT, option B, when PSTATE.C = '1':
For SETET, option A, when PSTATE.C = '0':
For SETET, option B, when PSTATE.C = '1':
Explicit Memory Write effects produced by the instruction behave as if the instruction was executed at EL0 if the Effective value of PSTATE.UAO is 0 and either:
Otherwise, the Explicit Memory Write effects operate with the restrictions determined by the Exception level at which the instruction is executed.
| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| sz | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | Rs | x | x | 0 | 1 | 0 | 1 | Rn | Rd | |||||||||||||
| o0 | op1 | op2 | |||||||||||||||||||||||||||||
if !IsFeatureImplemented(FEAT_MOPS) || sz != '00' then EndOfDecode(Decode_UNDEF); end; var memset : SETParams; memset.d = UInt(Rd); memset.s = UInt(Rs); memset.n = UInt(Rn); let options : bits(2) = op2[1:0]; let nontemporal : boolean = options[1] == '1'; case op2[3:2] of when '00' => memset.stage = MOPSStage_Prologue; when '01' => memset.stage = MOPSStage_Main; when '10' => memset.stage = MOPSStage_Epilogue; otherwise => EndOfDecode(Decode_UNDEF); end;
For information about the CONSTRAINED UNPREDICTABLE behavior of this instruction, see Architectural Constraints on UNPREDICTABLE behaviors, and particularly Memory Copy and Memory Set SET* and Crossing a page boundary with different memory types or Shareability attributes.
| <Xs> |
Is the 64-bit name of the general-purpose register that holds the source data, encoded in the "Rs" field. |
CheckMOPSEnabled(); CheckSETConstrainedUnpredictable(memset); let data : bits(8) = X{}(memset.s); var B : MOPSBlockSize = 0; memset.is_setg = FALSE; memset.nzcv = PSTATE.[N,Z,C,V]; memset.toaddress = X{64}(memset.d); if memset.stage == MOPSStage_Prologue then memset.setsize = UInt(X{64}(memset.n)); else memset.setsize = SInt(X{64}(memset.n)); end; memset.implements_option_a = SETOptionA(); let privileged : boolean = (if options[0] == '1' then AArch64_IsUnprivAccessPriv() else PSTATE.EL != EL0); let accdesc : AccessDescriptor = CreateAccDescMOPS(MemOp_STORE, privileged, nontemporal); if memset.stage == MOPSStage_Prologue then if memset.setsize > ArchMaxMOPSBlockSize then memset.setsize = ArchMaxMOPSBlockSize; end; if memset.implements_option_a then memset.nzcv = '0000'; memset.toaddress = memset.toaddress + memset.setsize; memset.setsize = 0 - memset.setsize; else memset.nzcv = '0010'; end; end; memset.stagesetsize = MemSetStageSize(memset); if memset.stage != MOPSStage_Prologue then CheckMemSetParams(memset, options); end; var memaddrdesc : AddressDescriptor; var memstatus : PhysMemRetStatus; var memory_set : integer; var fault : boolean = FALSE; if memset.implements_option_a then while memset.stagesetsize < 0 && !fault looplimit ArchMaxMOPSBlockSize do // IMP DEF selection of the block size that is worked on. While many // implementations might make this constant, that is not assumed. B = SETSizeChoice(memset, 1); assert B <= -1 * memset.stagesetsize; (memory_set, memaddrdesc, memstatus) = MemSetBytes(memset.toaddress + memset.setsize, data, B, accdesc); if memory_set != B then fault = TRUE; else memset.setsize = memset.setsize + B; memset.stagesetsize = memset.stagesetsize + B; end; end; else while memset.stagesetsize > 0 && !fault looplimit ArchMaxMOPSBlockSize do // IMP DEF selection of the block size that is worked on. While many // implementations might make this constant, that is not assumed. B = SETSizeChoice(memset, 1); assert B <= memset.stagesetsize; (memory_set, memaddrdesc, memstatus) = MemSetBytes(memset.toaddress, data, B, accdesc); if memory_set != B then fault = TRUE; else memset.toaddress = memset.toaddress + B; memset.setsize = memset.setsize - B; memset.stagesetsize = memset.stagesetsize - B; end; end; end; UpdateSetRegisters(memset, fault, memory_set); if fault then if IsFault(memaddrdesc) then AArch64_Abort(memaddrdesc.fault); else let iswrite : boolean = TRUE; HandleExternalAbort(memstatus, iswrite, memaddrdesc, B, accdesc); end; end; if memset.stage == MOPSStage_Prologue then PSTATE.[N,Z,C,V] = memset.nzcv; end;
2026-03_rel 2026-03-26 20:48:11
Copyright © 2010-2026 Arm Limited or its affiliates. All rights reserved. This document is Non-Confidential.